/* ═══════════════════════════════════════════
   now-showing — the browse page (beat 3 · 32 s · swipe · hold `posters` at 21.9 s)

   Layers inside the one container (all absolute over the stage box):
     hero      the full-bleed photo (two <img>s: one animating, the next parked),
               a top and a bottom scrim, and the dim the exit pushes into
     chrome    the service monogram (top left) and the profile chip (beside
               the spine's Mute pill, which owns the top right): decoration
     stack     packed from the bottom: the title block, the poster row, the
               controls band. The band sits 80-124 px above the bottom edge
               (the bottom 72 px hold nothing), so the row's bottom edge is
               ~136 px up, well over the 80 px floor.

   State lives in data-* attributes (the badge guard does not observe them)
   and decorative motion runs on the Web Animations API from js/now-showing.js;
   only the three controls toggle classes, so the guard re-measures exactly
   when a control appears or goes. No filter, no blur, no blend mode.
   ═══════════════════════════════════════════ */

/* --now-showing-title-extra is the second title line's height (set by the
   fit, 0 for a one-line title): the posters give back part of it, so a
   two-line title never pushes the stack up into the chrome on a 640 px phone. */
.now-showing-container {
    --now-showing-poster-h: clamp(140px, calc(35vh - var(--now-showing-title-extra, 0px) * 0.7 - var(--now-showing-squeeze, 0px)), 300px);
    --now-showing-poster-w: calc(var(--now-showing-poster-h) * 2 / 3);
    --now-showing-gutter: 16px;
    position: absolute;
    inset: 0;
    overflow: hidden;
    color: var(--text-primary);
    font-family: var(--font-body);
}

@supports (height: 1dvh) {
    .now-showing-container {
        --now-showing-poster-h: clamp(140px, calc(35dvh - var(--now-showing-title-extra, 0px) * 0.7 - var(--now-showing-squeeze, 0px)), 300px);
    }
}

/* prepare(): entry states land instantly, never animated in. */
.now-showing-instant,
.now-showing-instant *,
.now-showing-instant *::before,
.now-showing-instant *::after {
    transition: none !important;
}

/* ───── The hero ───── */
.now-showing-hero {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: var(--screen-bg);
    pointer-events: none;
}

.now-showing-hero-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 30%;          /* the upper-third bias: a face, not a forehead */
    transform-origin: 50% 38%;
    opacity: 0;
}

.now-showing-hero-img[data-now-showing-on] {
    opacity: 1;
}

.now-showing-hero-img[data-now-showing-top] {
    z-index: 1;
}

.now-showing-hero-img[data-now-showing-failed] {
    visibility: hidden;                /* the cinema ground shows, never a broken icon */
}

/* The settle's lift: a flat light layer over the photo (never a filter),
   under the scrims and the text block's backing. */
.now-showing-lift {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: var(--light-core);
    opacity: 0;
}

.now-showing-scrim-top,
.now-showing-scrim-bottom,
.now-showing-dim {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 2;
    opacity: 0;
}

.now-showing-scrim-top {
    top: 0;
    height: 24%;
    background: var(--hero-scrim-top);
}

.now-showing-scrim-bottom {
    bottom: 0;
    height: 74%;
    background: var(--hero-scrim-bottom);
}

.now-showing-dim {
    top: 0;
    bottom: 0;
    z-index: 3;
    background: var(--void);
}

/* ───── Chrome: decoration only ───── */
.now-showing-chrome {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    height: calc(56px + env(safe-area-inset-top, 0px));
    padding: env(safe-area-inset-top, 0px) 100px 0 var(--now-showing-gutter);   /* 100 px: the Mute pill's corner */
    color: var(--decor-ink);
    pointer-events: none;
    opacity: 0;
}

.now-showing-mono {
    display: inline-flex;
    align-items: center;
    font: 700 1.3rem/1 var(--font-display);
    letter-spacing: -0.04em;
    color: var(--decor-ink);
}

.now-showing-mono-join {
    width: 3px;
    height: 1.05rem;
    margin: 0 1px;
    border-radius: 2px;
    background: var(--mono-join);
    opacity: 0.55;
    transform: skewX(-16deg);
}

.now-showing-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    max-width: 62%;
}

.now-showing-chip-img {
    flex: none;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    object-fit: cover;
    object-position: 50% 30%;
}

.now-showing-chip-img[data-now-showing-failed] {
    visibility: hidden;
}

.now-showing-chip-label {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font: 500 0.72rem/1.2 var(--font-body);
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* ───── The stack: titles, row, controls, packed from the bottom ───── */
.now-showing-stack {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(56px + env(safe-area-inset-top, 0px));
    bottom: calc(80px + env(safe-area-inset-bottom, 0px));
    z-index: 4;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 12px;
}

/* ───── The title block ───── */
.now-showing-titles {
    position: relative;
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 8px;
    text-align: center;
    transform-origin: 50% 0;
}

/* The text block's one backing (kicker, plaque, meta, starring): void at
   0.82, solid across the block and 40 px past it each way, feathered at its
   outer edges. On by 0.4 s, before any text; a white photo behind it still
   leaves every line above 4.5:1 (shots.md). */
.now-showing-titles::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -40px;
    bottom: -40px;
    z-index: -1;
    background: var(--block-backing);
    opacity: 0;
    transition: opacity 0.4s var(--ease-silk);
    pointer-events: none;
}

.now-showing-titles[data-now-showing-backed]::before {
    opacity: 1;
}

.now-showing-kicker {
    margin: 0 0 8px;
    font: 500 0.74rem/1.2 var(--font-body);
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--accent-warm);
    text-shadow: var(--sub-outline);
    opacity: 0;
}

.now-showing-plaque {
    position: relative;
    display: inline-block;
    max-width: 100%;
    padding: 12px 14px 13px;
    border-radius: 10px;
}

/* The plaque's fill is its own layer, so it can fade in at the settle
   without touching the title's own opacity. */
.now-showing-plaque::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--plaque-fill);
    box-shadow: var(--plaque-inset);
    opacity: var(--now-showing-plaque-fill, 0);
    transition: opacity 0.6s var(--ease-silk);
}

.now-showing-plaque[data-now-showing-lit] {
    --now-showing-plaque-fill: 1;
}

.now-showing-halo {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 150%;
    height: 300%;
    border-radius: 50%;
    background: radial-gradient(closest-side, var(--halo) 0%, var(--halo-far) 55%, transparent 100%);
    transform: translate(-50%, -50%);
    opacity: 0;
    pointer-events: none;
    z-index: -1;                       /* behind the plaque's fill (the stack is the stacking context) */
}

/* A title of 1-3 characters stands under a round halo. */
.now-showing-plaque[data-now-showing-round] .now-showing-halo {
    width: auto;
    height: 260%;
    aspect-ratio: 1;
}

.now-showing-bulbs {
    position: absolute;
    inset: 3px;
    pointer-events: none;
    opacity: 0;                        /* the frame arrives with the plaque, at the reveal */
}

.now-showing-bulb {
    position: absolute;
    width: 5px;
    height: 5px;
    margin: -2.5px 0 0 -2.5px;
    border-radius: 50%;
    background: var(--bulb-off);
}

.now-showing-bulb-lit {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--bulb-on);
    box-shadow: var(--bulb-glow);
    opacity: 0;
}

.now-showing-title {
    position: relative;
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: min(3.4rem, 13vw);      /* overwritten by the fit (setShowTitle) */
    line-height: 1.05;
    color: var(--text-primary);
    text-shadow: var(--title-shadow);
}

.now-showing-title-line {
    display: block;
    white-space: nowrap;
    opacity: 0;
}

.now-showing-title-line2[hidden] {
    display: none;
}

/* ReveelStage.lightSweep on line 2 at the settle: its glint is inset in the
   line's own box, so the line's glow need not be clipped while it crosses. */
.now-showing-title-line.reveel-sweep {
    overflow: visible;
}

.now-showing-sheen-clip {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: inherit;
    pointer-events: none;
}

.now-showing-sheen {
    position: absolute;
    top: -10%;
    bottom: -10%;
    left: 0;
    width: 45%;
    background: linear-gradient(75deg, transparent 0%, var(--halo) 40%, var(--light-core) 50%, var(--halo) 60%, transparent 100%);
    opacity: 0;
    transform: translateX(-120%) skewX(-14deg);
}

.now-showing-meta {
    margin: 10px 0 0;
    font: 500 0.74rem/1.3 var(--font-body);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-secondary);
    text-shadow: var(--sub-outline);
    opacity: 0;
}

.now-showing-starring {
    margin: 4px 0 0;
    max-width: 30rem;
    font: italic 400 1rem/1.3 var(--font-display);
    color: var(--text-primary);
    text-shadow: var(--sub-outline);
    text-wrap: balance;
    overflow-wrap: anywhere;
    opacity: 0;
}

/* ───── The poster row: the swipe surface ───── */
.now-showing-row {
    position: relative;
    flex: none;
}

.now-showing-row-real {
    opacity: 0;
}

.now-showing-echo {
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
}

.now-showing-row-heading {
    margin: 0 0 8px;
    padding: 0 var(--now-showing-gutter);
    font: 500 0.74rem/1.35 var(--font-body);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    text-align: center;
    color: var(--text-secondary);
    text-shadow: var(--sub-outline);
    text-wrap: balance;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

.now-showing-row-label {
    color: var(--accent-warm-bright);
}

.now-showing-viewport {
    position: relative;
    height: calc(var(--now-showing-poster-h) * 1.08 + 4px);
    overflow: hidden;
    touch-action: pan-y;
    cursor: grab;
}

.now-showing-track {
    position: absolute;
    inset: 0;
}

/* A deck, not a strip: the centred poster at 1.06x, the next two peeking
   behind it at smaller scales. Each poster's place is --now-showing-x (in
   poster widths, set per step) plus the live drag. */
.now-showing-poster {
    --now-showing-s: 0.86;
    position: absolute;
    left: 50%;
    top: calc(var(--now-showing-poster-h) * 0.04 + 2px);
    width: var(--now-showing-poster-w);
    height: var(--now-showing-poster-h);
    margin: 0 0 0 calc(var(--now-showing-poster-w) / -2);
    overflow: hidden;
    border: var(--poster-frame);
    border-radius: var(--poster-radius);
    background: var(--bg-elevated);
    box-shadow: var(--poster-shadow);
    pointer-events: none;              /* not a control: the swipe lives on the row's surface (.now-showing-viewport) */
    opacity: 0.78;
    transform:
        translate3d(calc(var(--now-showing-x, 0) * var(--now-showing-poster-w) + var(--now-showing-drag, 0px)), 0, 0)
        scale(var(--now-showing-s));
    transition:
        transform 0.55s var(--ease-expo-out),
        opacity 0.55s var(--ease-silk),
        border-color 0.55s var(--ease-silk);
}

.now-showing-poster[data-now-showing-depth="0"] {
    --now-showing-s: 1.06;
    opacity: 1;
    border-color: var(--accent-warm-bright);
}

.now-showing-poster[data-now-showing-depth="2"] {
    --now-showing-s: 0.74;
    opacity: 0.5;
}

.now-showing-poster[data-now-showing-depth="3"] {
    --now-showing-s: 0.7;
    opacity: 0;
    visibility: hidden;
    transition:
        transform 0.55s var(--ease-expo-out),
        opacity 0.3s var(--ease-silk),
        visibility 0s linear 0.3s;
}

.now-showing-track[data-now-showing-dragging] .now-showing-poster {
    transition: none;
}

.now-showing-poster-art {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.now-showing-poster-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 30%;
}

.now-showing-poster[data-now-showing-failed] .now-showing-poster-img {
    visibility: hidden;
}

.now-showing-poster-scrim {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 58%;
    background: var(--poster-title-scrim);
}

.now-showing-poster-title {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;                        /* its own stacking context: the backing sits under the text, over the photo */
    margin: 0;
    padding: 8px 9px 11px;
    color: var(--text-primary);
    text-align: center;
    /* Break at a hyphen or a space first; a word too long for the poster
       breaks mid-word only as a last resort, hyphenated (lang="en" is set on
       each title), and only words of 10+ letters ever are. */
    overflow-wrap: break-word;
    -webkit-hyphens: auto;
    hyphens: auto;
    hyphenate-limit-chars: 10 4 4;
    text-wrap: balance;
    opacity: 0;                        /* off-centre posters are previews: only the centred one carries its title */
    transition: opacity 0.55s var(--ease-expo-out);
}

/* The title's own backing: void at 0.82, solid under the whole title box
   (every line, one or three) and feathering out over 24 px above it. Over a
   pure-white photo: text-primary 11.27:1, accent-warm-bright 7.95:1. */
.now-showing-poster-title::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    top: -24px;
    z-index: -1;
    background: linear-gradient(0deg, rgba(5, 5, 17, 0.82) 0, rgba(5, 5, 17, 0.82) calc(100% - 24px), rgba(5, 5, 17, 0) 100%);
    pointer-events: none;
}

.now-showing-poster[data-now-showing-depth="0"] .now-showing-poster-title {
    opacity: 1;
}

.now-showing-poster-sheen-clip {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.now-showing-poster-sheen {
    position: absolute;
    top: -10%;
    bottom: -10%;
    left: 0;
    width: 60%;
    background: linear-gradient(75deg, transparent 0%, var(--halo) 42%, var(--light-core) 50%, var(--halo) 58%, transparent 100%);
    opacity: 0;
    transform: translateX(-130%) skewX(-12deg);
}

/* Look (a): Playfair 700 caps, tracked, centred over a bottom gradient. */
.now-showing-poster[data-now-showing-look="a"] .now-showing-poster-title {
    font: 700 calc(var(--now-showing-poster-h) * 0.066 * var(--now-showing-title-fit, 1))/1.12 var(--font-display);
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* Look (b): Playfair italic 400, lowercase, set large across the lower third. */
.now-showing-poster[data-now-showing-look="b"] .now-showing-poster-title {
    padding: 8px 10px 12px;
    font: italic 400 calc(var(--now-showing-poster-h) * 0.094 * var(--now-showing-title-fit, 1))/1.02 var(--font-display);
    letter-spacing: -0.01em;
    text-transform: lowercase;
    text-align: left;
}

/* Look (c): Pinyon script over a soft gradient, never under 1.9rem. */
.now-showing-poster[data-now-showing-look="c"] .now-showing-poster-scrim {
    height: 64%;
    background: linear-gradient(0deg, var(--scrim) 0%, rgba(5, 5, 17, 0.32) 48%, rgba(5, 5, 17, 0) 100%);
}

.now-showing-poster[data-now-showing-look="c"] .now-showing-poster-title {
    padding: 8px 8px 8px;
    font: 400 max(1.9rem, calc(var(--now-showing-poster-h) * 0.13))/1.08 var(--font-script);
    color: var(--accent-warm-bright);
}

/* (d)/(e) set the title on an opaque --bg-elevated block: no backing needed
   (text-primary on bg-elevated, 15.62:1, whatever the photo). */
.now-showing-poster[data-now-showing-look="d"] .now-showing-poster-title::before,
.now-showing-poster[data-now-showing-look="e"] .now-showing-poster-title::before {
    display: none;
}

/* Look (d), and its mirror (e) when two splits meet: the photo whole in the
   upper two-thirds at its own ratio, the title on a --bg-elevated block
   under a gilt hairline. A landscape always takes this look. */
.now-showing-poster[data-now-showing-look="d"] .now-showing-poster-art,
.now-showing-poster[data-now-showing-look="e"] .now-showing-poster-art {
    bottom: 33.4%;
    background: var(--void);
}

.now-showing-poster[data-now-showing-look="d"] .now-showing-poster-img,
.now-showing-poster[data-now-showing-look="e"] .now-showing-poster-img {
    object-fit: contain;
    object-position: 50% 50%;
}

.now-showing-poster[data-now-showing-look="d"] .now-showing-poster-scrim,
.now-showing-poster[data-now-showing-look="e"] .now-showing-poster-scrim {
    display: none;
}

.now-showing-poster[data-now-showing-look="d"] .now-showing-poster-title,
.now-showing-poster[data-now-showing-look="e"] .now-showing-poster-title {
    top: 66.6%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px 10px;
    border-top: 1px solid var(--gilt-line-strong);
    background: var(--bg-elevated);
    font: 600 calc(var(--now-showing-poster-h) * 0.054 * var(--now-showing-title-fit, 1))/1.2 var(--font-body);
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.now-showing-poster[data-now-showing-look="e"] .now-showing-poster-title {
    justify-content: flex-start;
    text-align: left;
}

/* ───── The controls band (80-124 px above the bottom edge) ───── */
.now-showing-controls {
    flex: none;
    display: grid;
    grid-template-columns: auto auto;
    justify-content: center;
    align-items: center;
    column-gap: 14px;
    min-height: 44px;
    padding: 0 var(--now-showing-gutter);
}

.now-showing-hint,
.now-showing-open {
    grid-area: 1 / 1;
    justify-self: end;
}

.now-showing-next {
    grid-area: 1 / 2;
}

.now-showing-hint {
    margin: 0;
    font: 500 0.74rem/1.2 var(--font-body);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-secondary);
    text-shadow: var(--sub-outline);
    opacity: 0;
    visibility: hidden;
}

.now-showing-next,
.now-showing-open {
    min-height: 44px;
    padding: 0 1.2rem;
    border-radius: 999px;
    font: 600 0.8rem/1 var(--font-body);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    -webkit-tap-highlight-color: transparent;
}

.now-showing-next {
    border: 0;
    background: var(--btn-fill);
    color: var(--btn-ink);
    box-shadow: var(--btn-shadow);
}

.now-showing-open {
    border: 1px solid var(--btn-ghost-border);
    background: var(--btn-ghost-fill);
    color: var(--text-primary);
}

.now-showing-next:focus-visible,
.now-showing-open:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
}

/* The hint and "Next poster" arrive 0.8 s after the hold cue, by delay, not
   by a timer; until then the button is hidden, so it cannot be pressed. */
.now-showing-hint.now-showing-on,
.now-showing-next.now-showing-on {
    animation: now-showing-appear 0.5s var(--ease-silk) 0.8s both;
}

.now-showing-open.now-showing-on {
    animation: now-showing-appear 0.5s var(--ease-silk) both;
}

.now-showing-hint.now-showing-on.now-showing-gone,
.now-showing-next.now-showing-on.now-showing-gone,
.now-showing-open.now-showing-on.now-showing-gone {
    animation: now-showing-leave 0.4s var(--ease-silk) both;
}

@keyframes now-showing-appear {
    from { opacity: 0; visibility: hidden; }
    to { opacity: 1; visibility: visible; }
}

@keyframes now-showing-leave {
    from { opacity: 1; visibility: visible; }
    to { opacity: 0; visibility: hidden; }
}

/* ───── Reduced motion: every part still plays, calmly ─────
   The hero cross-fades instead of panning, the ghosts become fades and the
   bulbs come on in four groups with no chase (all in JS, on film.reduced());
   here the row's slide becomes short. */
@media (prefers-reduced-motion: reduce) {
    .now-showing-poster {
        transition:
            transform 0.25s var(--ease-silk),
            opacity 0.25s var(--ease-silk),
            border-color 0.25s var(--ease-silk);
    }

    .now-showing-plaque::before {
        transition-duration: 0.9s;
    }
}
