/* =============================================================
   DeltaWerks Cinematic Scroll-Journey Homepage Styles
   ============================================================= */

/* ---- Container ---- */
.cinema-journey {
    /* Hero block positioning vars — defined here so siblings (like the
       global scroll cue) can track the block's left/width without
       duplicating clamps. Single source of truth. */
    --hero-left: clamp(4px, 3.8vw, 100px);                    /* -60px total shift left from original 8vw/160 baseline */
    --hero-width: clamp(500px, 56vw, 980px);                  /* Calibrated PAMP — was ghost-PAMPed for 4 rounds, now real */
    --hero-em: clamp(17px, 1.65vw, 28px);                     /* Calibrated — headline @ 3em ≈ 71px at 1440, substantial without dominating */
    /* Diamond X-position on the divider lines:
       block-left + frame.margin-left (5.5em) + rule-width/2 (8.5em)
       = block-left + 14em. Scroll cue locks to this so it forms a
       vertical spine with the divider diamonds. */
    --hero-diamond-x: calc(var(--hero-left) + 14 * var(--hero-em));

    /* Production frame positioning vars — single tune-point for the
       production station. Tighter min (so narrow viewports don't
       crowd the scene), bigger max (so 4K doesn't strand the frame
       up-left), more vertical breathing room (top scales further). */
    --prod-left: clamp(1rem, 3vw, 3rem);     /* slid left from 5vw — keeps frame's right edge clear of the pillar */
    --prod-top: calc(clamp(7rem, 14vh, 16rem) + 60px);
    /* Bumped from clamp(340, 32vw, 720) — the production frame is the
       primary conversion target so it needs more visual weight than a
       supporting card. Now ~38% of viewport instead of 32%, with the
       max ceiling also raised. */
    --prod-width: clamp(380px, 38vw, 820px);
    /* Em base for everything INSIDE the production frame. Bumped from
       clamp(14, 1.2vw, 28) → clamp(15, 1.35vw, 32) — ~12% proportional
       growth across all typography to fill the bigger frame and make
       the conversion message register at first glance. */
    --prod-em: clamp(15px, 1.35vw, 32px);

    position: relative;
    width: 100%;
    background: #02050b; /* prevents flash of white during video buffer */
    /* Explicit scroll height — the inner spacer alone wasn't being honored
       inside the parent flex column (App.tsx main has flex flex-col min-h-0).
       Setting min-height here guarantees the document is tall enough to scroll. */
    min-height: 500vh;
    flex-shrink: 0;
}

/* ---- Layer 1: Video ---- */
.cinema-video-layer {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
}
.cinema-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* Source frames (1920x1080) have the sigil composition baked in
       via the Blender camera — no CSS shifts. */
}
.cinema-video-loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #02050b;
}
.cinema-loading-pulse {
    width: 60px;
    height: 60px;
    border: 1px solid rgba(96, 165, 250, 0.4);
    border-radius: 50%;
    animation: cinema-pulse 1.6s ease-in-out infinite;
}
@keyframes cinema-pulse {
    0%, 100% { transform: scale(0.85); opacity: 0.4; }
    50%      { transform: scale(1.05); opacity: 1; }
}

/* ---- Scroll-snap anchors ----
   Invisible 1px-tall divs positioned at each station's landing scroll
   position. The document has scroll-snap-type: y proximity, and these
   anchors are the snap targets. The browser softly snaps to the
   nearest anchor when the user pauses scroll near it — gentle, doesn't
   fight aggressive scroll past. If we want STRONGER pause-at-station
   behavior, change scroll-snap-stop to 'always' (forces a stop even
   on fast scrolls). */
.cinema-snap-anchor {
    /* Snap target — full-viewport-height so the browser has a robust
       region to detect as a snap target (1px-tall targets are often
       skipped by browsers as they're hard to "catch" mid-scroll).
       scroll-snap-align: start anchors the top of this element to the
       top of the viewport when snapped. Position is set inline via
       React (top: Xvh) for each station's landing scroll position. */
    position: absolute;
    left: 0;
    width: 1px;
    height: 100vh;
    pointer-events: none;
    opacity: 0;            /* invisible but still a valid snap target — visibility:hidden may not register */
    scroll-snap-align: start;
    /* `always` = browser STOPS at this snap point even mid-scroll, so
       fast scrolling can't blow past stations. Combined with mandatory
       snap on html, each station is a "must-pass-through" rest point. */
    scroll-snap-stop: always;
}

/* Also clean up the unused vestigial .cinema-snap-marker class so it
   doesn't interfere if anything ever renders it. */
.cinema-snap-marker {
    display: none;
}

/* ---- Layer 2: Overlays ---- */
.cinema-overlay-layer {
    position: fixed;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}
.cinema-station-overlay {
    position: absolute;
    inset: 0;
    transition: opacity 120ms linear;
    color: white;
}

/* ---- Scroll spacer ---- */
.cinema-scroll-spacer {
    position: relative;
    z-index: -1;
    pointer-events: none;
}

/* ---- Snap markers (hidden, drive proximity scroll-snap to each keyframe) ---- */
.cinema-snap-marker {
    position: absolute;
    left: 0;
    width: 1px;
    height: 100vh;     /* one viewport tall — its center is the snap target */
    pointer-events: none;
    visibility: hidden;
    scroll-snap-align: center;
    scroll-snap-stop: normal;  /* don't force-stop; gentle proximity snap */
}

/* ============================================================
   HERO LAYOUT — container-based scaling.
   .cinema-hero-block is the single scaling unit: positioned + sized
   ONCE; sets a base font-size via clamp; everything inside uses em
   units so bracket and content scale together without drift across
   viewports. Color tokens scoped here so they don't pollute the rest
   of the brand palette.
   ============================================================ */
.cinema-hero-block {
    /* Scoped color tokens */
    --cyan: #22b7ff;
    --cyan-soft: #9beeff;
    --gold: #ffe794;
    --white: #f8fbff;

    /* The single positioning + sizing point for the entire hero.
       Pulls left + width from .cinema-journey CSS vars so the scroll
       cue (sibling element) can track this same block automatically.
       top clamp tuned to drop the block further into the viewport on
       taller screens — was clamp(70, 8.5vh, 120) which glued it to
       the top and left ~490px empty below at 1080p. */
    position: absolute;
    z-index: 2;
    top: clamp(80px, 20vh, 320px);
    left: var(--hero-left);
    width: var(--hero-width);

    /* THE base font-size that everything else scales from. Driven by
       --hero-em on .cinema-journey so a single tune-point in that block
       grows the entire hero (bracket margins, headline @ 3em, bullets,
       rule width, diamond X). Was hardcoded clamp(13px, 1.1vw, 19px). */
    font-size: var(--hero-em);
}

/* Content panel — flows naturally INSIDE the bracket arms. Left margin
   clears the bracket's vertical arm; right margin leaves a small gap
   so text doesn't kiss the chamfered top-right / bottom-right corner. */
.cinema-hero-frame {
    position: relative;
    margin-left: 4.5em;          /* clears bracket vertical arm + gap — was 5.1em, -0.6em (~15px) for tighter nest into bracket */
    margin-right: 1.5em;          /* clears chamfered corner taper */
    max-width: 26em;             /* limits text + divider width */
    padding: 1.4em 0 0.6em;      /* breathing room from bracket arms */
    /* Block nudge — moves the entire content (rune → bullets) without
       affecting the absolutely-positioned bracket. Negative X = left,
       negative Y = up.
       X uses clamp so the leftward shift scales with viewport width
       instead of staying a fixed -40px (which over-shifts at narrow
       viewports and pushes content out of the bracket on the left).
       Wide viewports get the full -40px nudge; narrow viewports taper
       to -12px so the content stays inside the bracket arms. */
    transform: translate(clamp(-40px, -2.8vw, -12px), -5px);
}

/* "[" bracket — absolutely positioned, sized to span the FULL hero-block
   width so the top + bottom horizontal arms wrap OVER the content. The
   vertical arm sits on the left (asset has it anchored there); stretching
   horizontally just lengthens the top/bottom arms — exactly what we want.
   Explicit height: calc(100% + 1.2em) forces the image to stretch to
   that height regardless of natural aspect ratio — without this the
   <img>'s natural aspect would override and the bracket would only span
   a fraction of the content. */
.cinema-hero-bracket {
    position: absolute;
    left: 0;
    right: 0;                    /* span full hero-block width */
    top: -0.6em;
    width: auto;                 /* let left+right define width */
    height: calc(100% + 1.2em);
    object-fit: fill;
    opacity: 0.92;
    filter:
        drop-shadow(0 0 4px rgba(0, 158, 255, 0.8))
        drop-shadow(0 0 15px rgba(0, 93, 255, 0.38));
    pointer-events: none;
    user-select: none;
    -webkit-user-drag: none;
}

/* Block-wide exit transform — slides the entire hero block up + fades
   on scroll-out. Replaces the per-element transforms. The exit travel
   distance is calibrated to the block's resting position (top: 20vh)
   plus block height after the PAMP rounds — at -480px the block's
   bottom edge has cleared the top of most viewports by the time
   opacity finishes wiping it out. Was -140px which left it visibly
   hovering at fade-completion. */
.cinema-hero-block {
    transform: translateY(calc(-480px * var(--exit, 0)));
    opacity: calc(1 - var(--exit, 0));
    transition: transform 80ms linear, opacity 80ms linear;
    will-change: transform, opacity;
}
/* .cinema-hero-frame-tl was overriding the codex left positioning
   (it set left: 1.5-4rem which slammed the panel against the bracket).
   The base .cinema-hero-frame rule above already sets the correct
   left: clamp(128px, 8.75vw, 168px) per codex. Just keep text-align. */
.cinema-hero-frame-tl {
    text-align: left;
}

/* --- Slate: tick-backed label clip ---
   Flex row: vertical plasma tick on the left binds the runes (rovás
   "teremt" = create) + Manifest wordmark as one structural unit.
   Tick aesthetic matches .cinema-hero-subline::before so the visual
   language stays consistent across the hero block. */
.cinema-hero-slate {
    display: flex;
    align-items: center;
    gap: 0.7em;
    margin-bottom: 0.45em;
    /* Drop visually toward the horizontal divider — transform doesn't
       affect layout, so divider/headline below stay anchored. Tweak
       this single value if the tick needs to align tighter or looser
       to the bracket's chamfered top corner. */
    transform: translateY(0.7em);
}
.cinema-hero-slate-tick {
    flex: 0 0 auto;
    width: 0.18em;
    height: calc(2.6em - 2px);   /* 1px off top + 1px off bottom (center-anchored via parent's align-items: center) */
    /* Solid at top (anchors to bracket chamfer), fades out at the bottom
       to harmonize with the divider's transparent outer edges. Both
       elements now share a "fade outward from focal anchor" language. */
    background: linear-gradient(
        to bottom,
        var(--cyan) 0%,
        var(--cyan) 65%,
        rgba(34, 183, 255, 0) 100%
    );
    box-shadow:
        0 0 4px rgba(154, 236, 255, 0.85),
        0 0 12px rgba(34, 183, 255, 0.85),
        0 0 22px rgba(0, 99, 255, 0.45);
    pointer-events: none;
}
.cinema-hero-slate-stack {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* Lift runes+word stack independently of the tick. Transform doesn't
       affect layout, so the tick stays kissed to the bracket chamfer
       while the text slides up to balance the empty space above. */
    transform: translateY(calc(-1.1em + 3px));
}
.cinema-hero-slate-runes {
    margin-bottom: 0.18em;       /* tight gap — they read as one stamp */
    color: #48caff;
    font-family: 'Noto Sans Old Hungarian', Consolas, 'Courier New', monospace;
    font-size: 0.7em;
    font-weight: 700;
    letter-spacing: 0.4em;
    line-height: 1;
    text-transform: uppercase;
    text-shadow:
        0 0 3px rgba(154, 236, 255, 0.95),
        0 0 12px rgba(0, 158, 255, 0.9),
        0 0 22px rgba(0, 99, 255, 0.5);
    pointer-events: none;
    user-select: none;
}
.cinema-hero-slate-word {
    color: var(--gold);
    font-size: 1.3em;
    font-weight: 300;
    letter-spacing: 0.7em;
    line-height: 1;
    text-transform: uppercase;
    text-shadow: 0 0 11px rgba(255, 231, 148, 0.38);
}

/* --- Headline — em-based sizing scales with block --- */
.cinema-hero-headline {
    margin: 0;
    font-size: 3em;
    font-weight: 800;
    line-height: 0.93;
    letter-spacing: 0;
    font-family: 'Segoe UI', 'Rajdhani', 'Eurostile', 'Arial Narrow', Arial, sans-serif;
}
/* Each SplitText segment becomes a block-level line via this rule.
   The wrapper span receives className="cinema-hero-headline-line"
   from React; we make it block so the 3 lines stack. */
.cinema-hero-headline-line {
    display: block;
    color: #fbfbff;
    text-shadow:
        0 0 2px rgba(255, 255, 255, 0.55),
        0 0 20px rgba(255, 255, 255, 0.15);
}
/* Accent — overrides the line color + adds the codex glow stack */
.cinema-hero-headline .cinema-headline-accent {
    color: #48caff;
    font-weight: 800;
    text-shadow:
        0 0 3px rgba(154, 236, 255, 0.95),
        0 0 12px rgba(0, 158, 255, 0.95),
        0 0 35px rgba(0, 99, 255, 0.65);
}
/* Accent word — plasma blue with a strong multi-layer halo so it reads
   as "burning" plasma rather than just colored text. Mimics codex's
   reference: the word should glow like the wireframe sigil itself. */
.cinema-headline-accent {
    color: #3DB5F1;
    text-shadow:
        0 0 40px rgba(61, 181, 241, 0.65),       /* outer atmospheric halo */
        0 0 22px rgba(125, 220, 255, 0.55),      /* mid halo */
        0 0 10px rgba(125, 220, 255, 0.45),      /* inner halo */
        0 0 3px rgba(180, 235, 255, 0.4),        /* sharp inner edge */
        0 2px 28px rgba(0, 0, 0, 0.85);
}

/* --- Divider: sweep line + diamond ---
   Fades out fast (by exit=0.3) and lifts upward, so the rising headline
   letters don't visually pass through it. */
.cinema-hero-divider {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin: 1.1rem 0 1.2rem;
    --divider-p: clamp(0, calc(var(--exit, 0) / 0.3), 1);
    transform: translateY(calc(-50px * var(--divider-p)));
    opacity: calc(1 - var(--divider-p));
    will-change: transform, opacity;
    transition: transform 80ms linear, opacity 80ms linear;
}
.cinema-hero-divider-line {
    flex: 0 0 auto;
    width: 92px;
    height: 1px;
    /* Plasma blue (matches the headline accent + sigil glow) so the
       divider feels like part of the brand color system instead of
       floating off in cyan. Diamond removed per design pass. */
    background: linear-gradient(
        90deg,
        rgba(61, 181, 241, 0.85),
        rgba(61, 181, 241, 0.25) 70%,
        transparent
    );
}
/* Diamond: deep electric blue — picks up the same accent-blue-600 (#2563EB)
   that powers the header's bottom border. Structural-color pickup. */
.cinema-hero-divider-diamond {
    width: 6px;
    height: 6px;
    flex: 0 0 auto;
    transform: rotate(45deg);
    background: #3B82F6;                       /* accent-blue-500 — slightly brighter than the header line so it reads at this small size */
    box-shadow: 0 0 10px rgba(37, 99, 235, 0.7);
}

/* --- Subline ---
   Color was a flat slate-gray (rgba(190,205,225,0.78)) — operator flagged
   it as "dead husk gray". Replaced with a cool moonlit ice-blue that reads
   as reflected light from the wireframe glow: alive, but still clearly a
   supporting voice (lower contrast than the white headline). */
/* --- Hero rule (divider) — em-based, scales with block.
   Color + glow match the "imagination" headline accent so all the
   plasma-blue elements read as one family. */
.cinema-hero-rule {
    position: relative;
    height: 0.8em;
    width: 17em;
    max-width: 100%;
    margin: 0.85em 0;
}
.cinema-hero-rule::before,
.cinema-hero-rule::after {
    content: '';
    position: absolute;
    top: 50%;
    width: calc(50% - 20px);
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(72, 202, 255, 0.95));
    box-shadow:
        0 0 3px rgba(154, 236, 255, 0.85),
        0 0 12px rgba(0, 158, 255, 0.7),
        0 0 22px rgba(0, 99, 255, 0.45);
}
.cinema-hero-rule::before { left: 0; }
.cinema-hero-rule::after {
    right: 0;
    transform: scaleX(-1);
}
.cinema-hero-rule span {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 9px;
    height: 9px;
    border-right: 2px solid #48caff;
    border-bottom: 2px solid #48caff;
    transform: translate(-50%, -62%) rotate(45deg);
    box-shadow:
        0 0 3px rgba(154, 236, 255, 0.95),
        0 0 12px rgba(0, 158, 255, 0.9),
        0 0 22px rgba(0, 99, 255, 0.55);
}
.cinema-hero-rule-small {
    margin: 0.85em 0 0.65em;
    /* Match the top divider's brightness — was dimmed at 0.62; full
       opacity so the glow stack reads at the same intensity. */
}
/* Mirror the diamond's highlight direction on the bottom rule. Top rule
   uses border-right + border-bottom (highlight on the bottom V of the
   diamond, pointing down toward the headline). Bottom rule swaps to
   border-left + border-top so the highlight forms the top V (pointing
   up toward the top divider — mirrored pair across the headline). */
.cinema-hero-rule-small span {
    border-right: 0;
    border-bottom: 0;
    border-left: 2px solid #48caff;
    border-top: 2px solid #48caff;
}

/* --- Tagline (subline) — em-based --- */
.cinema-hero-subline {
    position: relative;
    margin: 1.9em 0 0;             /* extra breathing room from headline */
    padding-left: 0.7em;
    color: var(--cyan-soft);
    font-size: 0.85em;
    line-height: 1.35;
    text-shadow: 0 0 10px rgba(0, 174, 255, 0.24);
}
.cinema-hero-subline::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.18em;
    bottom: 0.08em;
    width: 0.18em;
    background: var(--cyan);
    box-shadow: 0 0 12px rgba(34, 183, 255, 0.85);
}

/* --- Bullet list — em-based --- */
.cinema-hero-list {
    display: grid;
    gap: 0.55em;
    margin: 0;
    padding: 0;
    list-style: none;
    color: #f8fbff;
    font-size: 0.85em;
    font-weight: 600;
    line-height: 1.22;
    text-shadow: 0 0 9px rgba(0, 0, 0, 0.9);
}
.cinema-hero-list li {
    position: relative;
    padding-left: 1.55em;
}
.cinema-hero-list li::before {
    content: '';
    position: absolute;
    left: 0.12em;
    top: 0.43em;
    width: 0.5em;
    height: 0.5em;
    background: var(--cyan);
    transform: rotate(45deg);
    box-shadow:
        0 0 8px rgba(34, 183, 255, 1),
        0 0 18px rgba(0, 118, 255, 0.85);
}

/* ---- Per-letter staggered upward exit ----
   The parent (.cinema-hero-frame) sets `--exit` from React state
   (0 = stable, 1 = fully past fade range). Each text run can also set
   `--start-delay` (0..1) to trail behind another run.

   Each .cinema-split-char gets a per-letter "start" point based on its
   index in the global run, so the leftmost letter starts moving first
   and the rightmost last. Each letter then has a 0.5-wide window in
   which it animates from 0 (stable) to 1 (fully lifted out + faded).

   Words are wrapped in .cinema-split-word with `inline-block + nowrap`
   so line-wrap only happens between words, never mid-word. */
.cinema-hero-frame { --exit: 0; }

.cinema-split-word {
    display: inline-block;
    white-space: nowrap;
}
.cinema-split-char {
    /* Pure CSS cascade — left-to-right by char index in the source string.
       The translation and the fade run on DIFFERENT curves so each char
       physically flies upward (visible motion) BEFORE it fades out.
       Without this split, chars would dim before they noticeably moved. */
    --letter-start: calc((var(--idx) / var(--total)) * 0.6 + var(--start-delay, 0));
    /* Move: char lifts -240px over a 0.35-wide window (visibly flies) */
    --p-move: clamp(0, calc((var(--exit) - var(--letter-start)) / 0.35), 1);
    /* Fade: starts 0.15 AFTER move begins, finishes at letter-start + 0.40
       so chars stay opaque while they're flying and only fade once they're
       well above their original position. */
    --p-fade: clamp(0, calc((var(--exit) - var(--letter-start) - 0.15) / 0.25), 1);

    display: inline-block;
    transform: translateY(calc(-240px * var(--p-move)));
    opacity: calc(1 - var(--p-fade));
    will-change: transform, opacity;
}

/* Legacy class kept for non-hero stations that may still use it */
.cinema-rule {
    width: 80px;
    height: 1px;
    background: linear-gradient(90deg, rgba(34, 211, 238, 0.7), transparent);
    margin: 1rem 0;
}
.cinema-rule-accent {
    background: linear-gradient(90deg, rgba(245, 158, 11, 0.7), transparent);
}

/* --- Narrow viewports: extra clearance under header, tighter scale ---
   Mobile (Apple devices especially) needs noticeably more headroom or
   the headline collides with the bottom of the DeltaWerks logo glow. */
@media (max-width: 800px) {
    .cinema-hero-frame {
        top: clamp(7.5rem, 13vh, 9rem);
        max-width: 90vw;
    }
    .cinema-hero-frame-tl {
        left: 5vw;
    }
    .cinema-hero-sigil { margin-bottom: 0.9rem; }
    .cinema-hero-headline { font-size: 1.4rem; line-height: 1.18; }
    .cinema-hero-subline  { font-size: 0.85rem; }
    .cinema-hero-divider-line { width: 64px; }
}
@media (max-width: 480px) {
    .cinema-hero-frame { top: 7.5rem; }
    .cinema-hero-headline { font-size: 1.25rem; }
}

/* ---- Runic scroll cue (bottom, near-center) ----
   Operator's custom PNG glyph — has its own halo/glow baked in.
   Shifted slightly left of viewport center to align with the central
   wireframe sigil's apex (the sigil is composed slightly off-center
   in source frames). */
.cinema-scroll-cue {
    /* Fixed to viewport — was `absolute`, which anchored to the bottom
       of the .cinema-journey container (min-height: 500vh) instead of
       the visible viewport, parking the cue 5 screens below where the
       user could see it. Matches the video + overlay layers' fixing. */
    position: fixed;
    bottom: clamp(0.6rem, 2.5vh, 1.8rem);
    /* Centered horizontally on the HERO BLOCK (left side of viewport),
       not the sigil. Block sits at left: clamp(20, 3.5vw, 56) with
       width clamp(420, 42vw, 760) — center is left + width/2 =
       clamp(230, 24.5vw, 436). The arrow now lives at the bottom of
       the information lane, urging the eye down after the bullets. */
    /* Anchor to the divider diamond's X-position — arrow + diamonds
       form a vertical spine through the hero block. Auto-tracks the
       block across all viewports via shared CSS vars. */
    left: var(--hero-diamond-x);
    transform: translate(calc(-50% - 45px), -20px);  /* -45px left + -20px up — fine-tuned alignment with diamond stack */
    pointer-events: none;
    transition: opacity 700ms ease;
    z-index: 3;
}
.cinema-scroll-cue-icon {
    display: block;
    /* Reduced 30% from previous (56/4.6vw/96) per operator preference */
    width: clamp(40px, 3.2vw, 68px);
    height: auto;
    user-select: none;
    -webkit-user-drag: none;
    animation: cinema-cue-bob 2.6s ease-in-out infinite;
}
@keyframes cinema-cue-bob {
    0%, 100% { transform: translateY(0);   opacity: 0.92; }
    50%      { transform: translateY(8px); opacity: 1;    }
}

/* ---- CTA buttons (shared across hero + stations) ---- */
.cinema-cta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    margin-top: 0.8rem;
}
.cinema-cta {
    display: inline-block;
    padding: 0.7rem 1.2rem;
    border-radius: 4px;
    font-size: 0.72rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    transition: background 200ms ease, border-color 200ms ease;
}
.cinema-cta-primary {
    background: rgba(245, 158, 11, 0.18);
    border: 1px solid rgba(245, 158, 11, 0.6);
    color: rgba(245, 200, 100, 1);
}
.cinema-cta-primary:hover {
    background: rgba(245, 158, 11, 0.28);
}
.cinema-cta-secondary {
    background: rgba(2, 5, 11, 0.4);
    border: 1px solid rgba(96, 165, 250, 0.5);
    color: rgba(150, 200, 255, 0.95);
}
.cinema-cta-secondary:hover {
    background: rgba(96, 165, 250, 0.15);
}

/* ---- Scroll cue (chevron at hero bottom) ---- */
.cinema-scroll-chevron {
    font-size: 1.4rem;
    animation: cinema-bob 2s ease-in-out infinite;
}
@keyframes cinema-bob {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(6px); }
}

/* ===========================================================
   STATION CONTENT — three panel variants
   Driven by [data-panel-style="..."] on .cinema-journey root
   =========================================================== */

/* Common station content base */
.cinema-station-content { color: white; }

/* ============================================================
   TACTICAL CARD — single chamfered panel containing all station
   content (slate + headline + divider + bullets/subline + CTA).
   Replaces the previous split-zone composition. CSS-only, no PNG
   artwork — chamfered corners via clip-path, gold L-bracket
   accents at each corner, subtle plasma-blue inner border line,
   dark backdrop-blur fill so the wireframe scene tones DOWN
   behind the card without disappearing.
   ============================================================ */
.cinema-station-tactical {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.cinema-tactical-card {
    --enter: 1;
    --exit: 0;
    --chamfer: 16px;

    position: absolute;
    top: clamp(7rem, 13vh, 11rem);
    left: clamp(2rem, 5vw, 5rem);
    width: clamp(360px, 38vw, 540px);

    /* No background or clip-path on the main element — those live on
       ::before (border layer) and ::after (fill layer) so the chamfered
       border line is visible on ALL 8 edges including the diagonals. */
    background: transparent;

    padding: 1.85rem 2rem 1.6rem;

    /* Slide UP entry, fade-out exit — same physics as before */
    transform: translateY(calc((1 - var(--enter)) * 60px));
    opacity: clamp(0, min(calc(var(--enter) * 1.5), calc(1 - var(--exit))), 1);
    will-change: transform, opacity;
    transition: transform 120ms linear, opacity 120ms linear;

    pointer-events: auto;

    display: flex;
    flex-direction: column;
}

/* BORDER LAYER — the chamfered colored fill, sized to the full card.
   Shows through at the 1px gap left by the inset of ::after, forming the
   visible border line on all 8 edges (top/right/bottom/left + 4 diagonals). */
.cinema-tactical-card::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(61, 181, 241, 0.4);
    clip-path: polygon(
        var(--chamfer) 0,
        calc(100% - var(--chamfer)) 0,
        100% var(--chamfer),
        100% calc(100% - var(--chamfer)),
        calc(100% - var(--chamfer)) 100%,
        var(--chamfer) 100%,
        0 calc(100% - var(--chamfer)),
        0 var(--chamfer)
    );
    z-index: 0;
}

/* FILL LAYER — the dark blurred interior, inset 1px so the border shows.
   Same chamfer shape; the 1px inset means each of the 8 edges of the
   border layer protrudes 1px past this fill, creating the visible
   border line. */
.cinema-tactical-card::after {
    content: '';
    position: absolute;
    inset: 1px;
    background: rgba(2, 5, 11, 0.55);
    backdrop-filter: blur(8px) saturate(1.1);
    -webkit-backdrop-filter: blur(8px) saturate(1.1);
    clip-path: polygon(
        var(--chamfer) 0,
        calc(100% - var(--chamfer)) 0,
        100% var(--chamfer),
        100% calc(100% - var(--chamfer)),
        calc(100% - var(--chamfer)) 100%,
        var(--chamfer) 100%,
        0 calc(100% - var(--chamfer)),
        0 var(--chamfer)
    );
    z-index: 1;
}

/* All actual content (corners + slate + headline + content + CTA) needs
   to sit ABOVE the ::before and ::after layers. */
.cinema-tactical-card > * {
    position: relative;
    z-index: 2;
}

/* Corner brackets — small gold L-shapes at each of the 4 corners,
   inside the chamfer. Modular HUD vocabulary without going ornate. */
.cinema-tactical-card-corner {
    position: absolute;
    width: 24px;
    height: 24px;
    border-color: #E5CB99;                /* accent-gold-300 — matches slate */
    border-style: solid;
    pointer-events: none;
    opacity: 0.85;
}
.cinema-tactical-card-corner.cnr-tl {
    top: 12px; left: 12px;
    border-width: 1px 0 0 1px;            /* top + left = ┌ */
}
.cinema-tactical-card-corner.cnr-tr {
    top: 12px; right: 12px;
    border-width: 1px 1px 0 0;            /* top + right = ┐ */
}
.cinema-tactical-card-corner.cnr-bl {
    bottom: 12px; left: 12px;
    border-width: 0 0 1px 1px;            /* bottom + left = └ */
}
.cinema-tactical-card-corner.cnr-br {
    bottom: 12px; right: 12px;
    border-width: 0 1px 1px 0;            /* bottom + right = ┘ */
}

/* --- Slate inside the card: tick-backed label clip (gold variant) ---
   Mirrors the hero's slate structure exactly: vertical tick on the
   left binds rune kicker + station name as a single unit. Gold token
   set instead of plasma blue; everything else is the same shape, so
   the brand grammar reads as one system. */
.cinema-tactical-card-slate {
    display: flex;
    align-items: center;
    gap: 0.55em;
    margin: 0 0 1.1em;
}
.cinema-tactical-card-slate-tick {
    flex: 0 0 auto;
    width: 0.18em;                    /* was 3px — now scales with em */
    height: calc(2.6em - 2px);
    /* Slate uses the HERO's blue+gold pairing as a brand constant
       across all stations — tick + rune in plasma blue, word in gold.
       Color is intentionally NOT pulled from the accent token here so
       the slate reads as the same brand greeting regardless of the
       station's accent (which shows up in the body of the card
       instead — headline, divider, bullets, CTA). */
    background: linear-gradient(
        to bottom,
        #22b7ff 0%,
        #22b7ff 65%,
        transparent 100%
    );
    box-shadow:
        0 0 4px rgba(154, 236, 255, 0.85),
        0 0 12px rgba(34, 183, 255, 0.85),
        0 0 22px rgba(0, 99, 255, 0.45);
    pointer-events: none;
}
.cinema-tactical-card-slate-stack {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* Lift stack so word top aligns with tick top, runes fill upper
       space — same trick as hero. */
    transform: translateY(-0.6em);
}
.cinema-tactical-card-rune {
    margin-bottom: 0.18em;
    font-family: 'Noto Sans Old Hungarian', Consolas, 'Courier New', monospace;
    font-size: 0.78em;
    font-weight: 700;
    letter-spacing: 0.4em;
    line-height: 1;
    /* Plasma blue — brand constant. Mirrors hero rune treatment exactly
       so the slate is the same greeting on every station. */
    color: #48caff;
    text-transform: uppercase;
    text-shadow:
        0 0 3px rgba(154, 236, 255, 0.95),
        0 0 12px rgba(0, 158, 255, 0.9),
        0 0 22px rgba(0, 99, 255, 0.5);
    pointer-events: none;
    user-select: none;
}
.cinema-tactical-card-word {
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: 0.92em;
    font-weight: 600;
    letter-spacing: 0.5em;
    /* Warm gold — brand constant. Matches hero "Manifest" word color
       so PRODUCTION / FORGE / [future stations] all read in the same
       gold identity treatment. */
    color: #ffe794;
    text-transform: uppercase;
    text-shadow:
        0 0 11px rgba(255, 231, 148, 0.38),
        0 2px 8px rgba(0, 0, 0, 0.7);
}

/* --- Headline kicker: small caps clarifier between slate and headline ---
   Renders when config.headlineKicker is set. Used to add an English-language
   legibility signal under brand-deep slate words (e.g. "AI ENGINEERING"
   under "LOGOS"). Visually subordinate to both the slate above (which uses
   bigger Orbitron) and the headline below (which uses big Orbitron),
   ice-blue muted color so it sits as a quiet bridge between the two. */
.cinema-tactical-card-headline-kicker {
    font-family: 'Roboto Condensed', system-ui, sans-serif;
    font-size: 0.82em;                          /* was 0.68em — bumped for better legibility */
    font-weight: 500;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    /* Plasma blue — matches .cinema-tactical-card-rune exactly so the
       slate runes + headline kicker form a coherent brand-color band
       above the white headline. Brand constant across all stations. */
    color: #48caff;
    /* Tighter margins to free vertical space for CTAs on tall-content
        viewports — operator reported CTAs being pushed out of frame
        on 4K + 1/3-split-screen widths. Was 0.4em 0 0.3em. */
    margin: 0.1em 0 0.1em;
    line-height: 1;
    text-shadow:
        0 0 3px rgba(154, 236, 255, 0.95),
        0 0 10px rgba(72, 202, 255, 0.6);
}

/* --- Headline: confident, big, gold accent ---
   Was 2.55em — slight reduction to 2.3em to free vertical space for
   CTAs on tall-content viewports (4K + split-screen). Still big
   enough to anchor as the conversion focal point. */
.cinema-tactical-card-headline {
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: 2.3em;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.005em;
    margin: 0;
    color: white;
    text-shadow:
        0 2px 22px rgba(0, 0, 0, 0.85),
        0 0 1px rgba(0, 0, 0, 0.9);
}
/* Gentler accent glow scoped to the tactical-card headline. The global
   .cinema-headline-accent rule has a strong halo intended for the hero
   — too much intensity for the dossier-card context. This override
   drops the glow ~35% and pulls color from the accent tokens so each
   station gets a glow that matches its accent text color. */
.cinema-tactical-card-headline .cinema-headline-accent {
    text-shadow:
        0 0 26px var(--tc-headline-accent-1),
        0 0 14px var(--tc-headline-accent-2),
        0 0 7px var(--tc-headline-accent-3),
        0 0 2px var(--tc-headline-accent-4),
        0 2px 22px rgba(0, 0, 0, 0.85);
}

/* --- Divider: gold sweep line + diamond, mirrors .cinema-hero-rule
   exactly. Gradient lines fade from outside (transparent) to inside
   (solid gold) toward a center diamond — same focal-point grammar. */
.cinema-tactical-card-rule {
    position: relative;
    height: 0.8em;
    width: 14em;
    max-width: 100%;
    /* Tightened from 1em / 1.1em — frees ~14px vertical for CTA fit */
    margin: 0.6em 0 0.65em;
}
.cinema-tactical-card-rule::before,
.cinema-tactical-card-rule::after {
    content: '';
    position: absolute;
    top: 50%;
    width: calc(50% - 1.1em);         /* was calc(50% - 18px) */
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--tc-accent));
    box-shadow:
        0 0 3px var(--tc-glow-1),
        0 0 12px var(--tc-glow-2),
        0 0 22px var(--tc-glow-3);
}
.cinema-tactical-card-rule::before { left: 0; }
.cinema-tactical-card-rule::after {
    right: 0;
    transform: scaleX(-1);
}
.cinema-tactical-card-rule span {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 0.55em;                    /* was 9px */
    height: 0.55em;
    border-right: 0.12em solid var(--tc-accent);  /* was 2px */
    border-bottom: 0.12em solid var(--tc-accent);
    transform: translate(-50%, -62%) rotate(45deg);
    box-shadow:
        0 0 3px var(--tc-glow-1),
        0 0 12px var(--tc-glow-2),
        0 0 22px var(--tc-glow-3);
}

/* --- Content: bullets or subline --- */
.cinema-tactical-card-list {
    list-style: none;
    padding: 0;
    /* Reduced margin-bottom 1.4em -> 0.85em and gap 0.55em -> 0.4em
       to compress vertical footprint — frees room for CTAs on tall
       viewports (4K + split-screen) where they were getting clipped. */
    margin: 0 0 0.85em;
    display: flex;
    flex-direction: column;
    gap: 0.4em;
}
.cinema-tactical-card-list li {
    font-family: 'Roboto Condensed', system-ui, sans-serif;
    font-size: 1.05em;                /* PAMP — was 0.92em, bumped for legibility (still fits one-line) */
    font-weight: 400;
    line-height: 1.4;
    color: rgb(210, 230, 248);            /* bright ice-blue */
    position: relative;
    padding-left: 1.05em;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}
.cinema-tactical-card-list li::before {
    content: '◆';
    position: absolute;
    left: 0;
    top: 0.22em;
    color: var(--tc-accent);
    font-size: 0.55em;
    /* Multi-layer glow stack — color pulled from accent tokens */
    text-shadow:
        0 0 3px var(--tc-glow-1),
        0 0 12px var(--tc-glow-2),
        0 0 22px var(--tc-glow-3);
}
.cinema-tactical-card-subline {
    font-family: 'Roboto Condensed', system-ui, sans-serif;
    font-size: 0.92em;                /* was clamp(0.85rem, 0.95vw, 1rem) */
    line-height: 1.5;
    color: rgb(200, 225, 245);
    margin: 0 0 1.4em;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}

/* --- CTA row: pins the dual-CTA pair to the bottom of the card.
   Primary (Get Quote) left, secondary (Production Portal) right.
   Wraps on very narrow viewports so neither gets crushed. --- */
.cinema-tactical-card-cta-row {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Tighter gap so both buttons fit side-by-side on every viewport,
       including 4K where the secondary button was getting clipped /
       wrapping below the visible HUD area on the live build. Was 0.45em. */
    gap: 0.3em;
    margin-top: auto;                       /* pin to bottom of flex column */
    margin-bottom: -0.9em;
    /* Force nowrap — under no circumstance should the second button
       wrap to a new line where it gets clipped by the frame's bottom
       chrome. If buttons can't fit, they overflow horizontally (still
       visible) instead of wrapping vertically (invisible). */
    flex-wrap: nowrap;
    transform: translateX(4px);
}

/* --- Content right-shift: slate / headline / rule / bullets all
   pushed right a touch so they breathe inside the frame's interior
   safe area, which is biased left-of-center due to the frame's
   chamfer asymmetry. CTA row is intentionally EXCLUDED — it stays
   at its locked +4px between-chamfer position. */
.cinema-tactical-card-slate,
.cinema-tactical-card-headline,
.cinema-tactical-card-rule,
.cinema-tactical-card-list,
.cinema-tactical-card-subline {
    transform: translateX(14px);
}

/* --- Primary CTA: dossier "press here" beacon. Plasma-blue + gold
   halo glow so it reads as the focal action (not just text in a box).
   This is "Get Quote" — the action that books the deal. All sizing in
   em so the button scales with the rest of the card across viewports. */
.cinema-tactical-card-cta {
    display: inline-block;
    /* Reduced padding + font-size + letter-spacing so both buttons
       fit side-by-side on every viewport from MacBook Pro 1440 up
       through 4K. Operator confirmed on live: secondary button was
       missing on 4K with previous tuning. */
    padding: 0.7em 0.95em;
    border-radius: 0.35em;
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: 0.72em;
    font-weight: 800;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--tc-accent);                         /* accent-themed text */
    background: rgba(2, 5, 11, 0.88);
    border: 1px solid rgba(96, 165, 250, 0.85);
    /* Halo glow — plasma blue outer + gold inner. Eye reads the button
       as a unified glowing element, not separate parts. */
    box-shadow:
        0 0 12px rgba(96, 165, 250, 0.45),
        0 0 28px rgba(96, 165, 250, 0.18),
        inset 0 0 12px rgba(229, 203, 153, 0.08);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    transition:
        background 200ms ease,
        border-color 200ms ease,
        box-shadow 200ms ease,
        transform 200ms ease;
}
.cinema-tactical-card-cta:hover {
    background: rgba(15, 30, 55, 0.92);
    border-color: rgba(96, 165, 250, 1);
    box-shadow:
        0 0 18px rgba(96, 165, 250, 0.6),
        0 0 40px rgba(96, 165, 250, 0.25),
        inset 0 0 14px rgba(229, 203, 153, 0.15);
    transform: translateY(-1px);
}

/* --- Secondary CTA: same vibe as primary. The class is kept so we
   can differentiate later if needed, but right now both buttons share
   the full glow + filled treatment for visual consistency. --- */
.cinema-tactical-card-cta-secondary {
    /* Inherits all styles from .cinema-tactical-card-cta — no overrides */
}

/* --- CTA arrow PAMP — the "go here" direction signal needs to read
   instantly. Bigger, bolder, glowing, and pulled in tight next to the
   label so it reads as one mark, not floating punctuation. The arrow
   character is the long-arrow (⟶) inside an aria-hidden span. */
.cinema-tactical-card-cta span[aria-hidden] {
    display: inline-block;
    font-size: 1.55em;                /* dwarfs the surrounding label letters */
    font-weight: 900;
    letter-spacing: 0;                /* override the CTA's 0.32em tracking */
    line-height: 0;                   /* CRITICAL — prevents the larger arrow from inflating the button's line-box and pushing the label down */
    vertical-align: middle;           /* center the arrow against the label cap-height */
    margin-left: 0.15em;              /* tight gap from label */
    margin-right: -0.15em;            /* claw back trailing space */
    transform: translateY(-0.02em);   /* tiny visual nudge for Orbitron baseline */
    text-shadow:
        0 0 6px var(--tc-glow-1),
        0 0 14px var(--tc-glow-2),
        0 0 26px var(--tc-glow-3);
    transition: transform 200ms ease;
}
.cinema-tactical-card-cta:hover span[aria-hidden] {
    transform: translate(0.2em, -0.02em);   /* arrow lunges forward on hover */
}

/* Narrow viewports — tactical card collapses gracefully */
@media (max-width: 800px) {
    .cinema-tactical-card {
        top: clamp(7rem, 12vh, 9rem);
        left: 4vw;
        width: 92vw;
        max-width: 460px;
    }
    .cinema-tactical-card-headline { font-size: 1.4rem; line-height: 1.15; }
}

/* ============================================================
   STATION SPLIT-ZONE COMPOSITION (used by stations with a frame)
   ============================================================
   Two-zone layout extending the hero's visual grammar:
     - Zone A: title card (rune mark + headline + divider) in the
       upper-left, text-on-scene, no panel chrome. Reads first.
     - Zone B: HUD frame in the lower-left holding ONLY the subline
       and CTA. Reads as a "dossier" prop in the scene, not a poster.
   The wireframe scene in the center is the prime visual; the title
   card is the silent statement; the dossier is the tactical detail. */

.cinema-station-split {
    /* The .cinema-station-overlay parent is already absolutely positioned
       and inset:0; this just makes our two zones positionable relative
       to that overlay. */
    position: absolute;
    inset: 0;
}

/* --- Zone A: title card, upper-left, text-on-scene --- */
.cinema-station-titlecard {
    --enter: 1;
    --exit: 0;
    position: absolute;
    top: clamp(6rem, 11vh, 9rem);
    left: clamp(1.5rem, 4vw, 4rem);
    max-width: clamp(20rem, 32vw, 38rem);
    z-index: 2;
    pointer-events: none;
    /* Whole zone fades on station exit (per-letter handles entry) */
    opacity: clamp(0, calc(1 - var(--exit)), 1);
    transition: opacity 120ms linear;
}
/* Title card mark = rune + station name (e.g. 𐳠 PRODUCTION).
   Styled identically to the hero's 𐳍 WELCOME slate — same gold color,
   same opacity, same spacing, same glow. Visual continuity: every
   station declares itself this way. */
.cinema-station-titlecard-mark {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0 0 1.4rem;
    /* Match hero slate: NOT rotated at rest, slides only on enter/exit */
}
.cinema-station-titlecard-rune {
    font-size: clamp(2.6rem, 3.6vw, 4.2rem);
    line-height: 0.9;
    color: #E5CB99;                          /* accent-gold-300 */
    opacity: 0.75;                           /* match hero rune opacity */
    text-shadow:
        0 0 22px rgba(229, 203, 153, 0.5),
        0 0 8px rgba(229, 203, 153, 0.35),
        0 2px 14px rgba(0, 0, 0, 0.7);
    letter-spacing: 0;
    margin-top: -0.2em;
}
/* Word label ("PRODUCTION", "3D", etc.) — identical to .cinema-hero-slate-word */
.cinema-station-titlecard-word {
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: clamp(0.85rem, 1vw, 1.05rem);
    font-weight: 600;
    letter-spacing: 0.55em;
    color: #E5CB99;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.75);
    margin-left: 0.4rem;
    text-transform: uppercase;
}
.cinema-station-titlecard-headline {
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: clamp(1.5rem, 2.4vw, 2.8rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.005em;
    margin: 0;
    color: white;
    text-shadow:
        0 2px 28px rgba(0, 0, 0, 0.85),
        0 0 1px rgba(0, 0, 0, 0.9);
}
.cinema-station-titlecard-divider {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin: 1rem 0 0;
}
.cinema-station-titlecard-line {
    flex: 0 0 auto;
    width: 92px;
    height: 1px;
    background: linear-gradient(
        90deg,
        rgba(229, 203, 153, 0.85),
        rgba(229, 203, 153, 0.25) 70%,
        transparent
    );
}
.cinema-station-titlecard-diamond {
    width: 6px;
    height: 6px;
    flex: 0 0 auto;
    transform: rotate(45deg);
    background: #E5CB99;                    /* matches gold accent on this station */
    box-shadow: 0 0 10px rgba(229, 203, 153, 0.55);
}

/* Per-letter drop-IN cascade for the title card headline. Letters fall
   from -45px above into place, staggered left-to-right.  Continuity
   with the hero's exit-upward motion: hero's words went UP; Production's
   words COME DOWN. Same alphabet, opposite direction. */
.cinema-station-titlecard .cinema-split-char {
    --letter-start: calc((var(--idx) / var(--total)) * 0.55);
    --p-enter: clamp(0, calc((var(--enter) - var(--letter-start)) / 0.35), 1);
    display: inline-block;
    transform: translateY(calc((1 - var(--p-enter)) * -45px));
    opacity: clamp(0, calc(var(--p-enter) * 1.5), 1);
    will-change: transform, opacity;
}

/* --- Zone B: dossier (HUD frame) — overrides for the smaller, quieter,
       subline+CTA-only frame. */
.cinema-station-dossier {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
/* Dossier sizing + position. Tuned for the near-square panel artwork
   (aspect ~1.07). Slightly wider than the portrait variant since the
   square shape gives less vertical room — width drives total area. */
.cinema-station-dossier .cinema-hud-frame {
    width: clamp(220px, 19vw, 300px);
    bottom: clamp(1.5rem, 3.5vh, 2.5rem);
    left: clamp(1.5rem, 4vw, 4rem);
    opacity: clamp(0, calc(min(calc(var(--enter) * 1.6), calc(1 - var(--exit))) * 0.92), 1);
}

/* ============================================================
   HUD-FULL LAYOUT — single PNG frame containing all content.
   Used by stations with config.frame (Production, etc.).
   The frame artwork provides the visual border; content inside
   uses the same typography vocabulary as the hero. */
.cinema-station-hud-full {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.cinema-station-hud-full .cinema-hud-frame {
    /* Pulls from .cinema-journey CSS vars — single tune-point for all
       station-frame positioning. Tighter min, bigger max, taller top
       than the original clamps to fix scene-crowding at narrow viewports
       and "stranded up-left" feel at 4K. */
    top: var(--prod-top);
    bottom: auto;
    left: var(--prod-left);
    width: var(--prod-width);
}

/* Per-station entry-motion overrides. Default .cinema-hud-frame slides
   UP from below (translateY 130%). Each station gets its own entrance
   signature so the journey reads as varied, not repetitive.
   - production: UP (default)        — gold, the foundation
   - 3d/forge:   LEFT                — blue, partner to AI's right
   - ai:         RIGHT               — cyan, mirrors forge
   - werkshop:   UP (default)        — cyan, grounded craft
   - apparel:    LEFT                — blue, bookends the journey */
[data-station="3d"] .cinema-hud-frame {
    /* Combined motion: ENTERS from the LEFT (translateX), EXITS DOWNWARD
       through the bottom of the viewport (translateY × 100vh).
       100vh guarantees the panel clears the bottom regardless of where
       it was positioned, since vh > panel-top-offset on any normal layout. */
    transform:
      translateX(calc((1 - var(--enter)) * -130%))
      translateY(calc(var(--exit, 0) * 100vh));
    /* Opacity over the exit window (175 → 215, 40 frames total):
       - frames 175 → 180: stays at 1 (panel solid, motion only)
       - frames 180 → 205: linear fade from 1 → 0 (25 frames of fade)
       - frames 205 → 215: stays at 0 (gone before motion completes)
       Exit progress goes 0 → 1 over the 40-frame window, so the breakpoints
       in --exit terms are: 0.125 (frame 180) → 0.75 (frame 205).
       Math: opacity = (0.75 - exit) / (0.75 - 0.125) = (0.75 - exit) / 0.625
       Combined with enter ramp via min() so this never overrides the entry. */
    opacity: clamp(0, min(
      var(--enter),
      calc((0.75 - var(--exit, 0)) / 0.625)
    ), 1);
}
[data-station="ai"] .cinema-hud-frame {
    transform: translateX(calc((1 - var(--enter)) * 130%));
}
[data-station="apparel"] .cinema-hud-frame {
    transform: translateX(calc((1 - var(--enter)) * -130%));
}

/* Content inside the HUD frame — flex column, CTA pinned to bottom.
   Establishes the em-base for the entire production card via --prod-em
   on .cinema-journey. All children use em units so typography +
   spacing scale together with the frame artwork. */
.cinema-hud-content {
    font-size: var(--prod-em);
    display: flex;
    flex-direction: column;
    height: 100%;
    /* Padding inside the safe area for some extra inner breathing room */
    padding: 0.5em 0.25em;
    pointer-events: auto;
}

/* Tone-down — applied ONLY to the frame artwork so the cyan border
   integrates with the wireframe scene WITHOUT washing out the inner
   text. Earlier we had blend-mode on the whole frame and the text
   inside was reading as gray. Restricted to the IMG fixes that. */
.cinema-station-dossier .cinema-hud-frame-img {
    mix-blend-mode: screen;
    filter: saturate(0.7);
}

/* Dossier inner content — flex column, CTA pinned to bottom of safe
   area for "movie-poster credit block" feel. Text stays full-strength. */
.cinema-station-dossier-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    gap: 0.55rem;
}
.cinema-station-dossier-subline {
    font-family: 'Roboto Condensed', 'Roboto', system-ui, sans-serif;
    font-size: clamp(0.72rem, 0.78vw, 0.85rem);
    line-height: 1.45;
    color: rgb(200, 225, 245);
    margin: 0;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}

/* Bullet list — punchy spec-sheet aesthetic, scaled to the smaller dossier */
.cinema-station-dossier-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}
.cinema-station-dossier-list li {
    font-family: 'Roboto Condensed', system-ui, sans-serif;
    font-size: clamp(0.72rem, 0.78vw, 0.85rem);
    font-weight: 400;
    line-height: 1.35;
    color: rgb(210, 230, 248);
    position: relative;
    padding-left: 0.95em;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.75);
    letter-spacing: 0.01em;
}
.cinema-station-dossier-list li::before {
    content: '◆';
    position: absolute;
    left: 0;
    top: 0.22em;
    color: #E5CB99;
    font-size: 0.55em;
    text-shadow: 0 0 8px rgba(229, 203, 153, 0.5);
}
.cinema-station-dossier-cta {
    /* Slightly tighter padding/font for the smaller dossier */
    padding: 0.55rem 0.9rem;
    font-size: 0.6rem;
    letter-spacing: 0.26em;
}
.cinema-station-dossier-cta {
    /* "Movie-poster credit block" — pinned to bottom */
    margin-top: auto;
    align-self: flex-start;
    display: inline-block;
    padding: 0.7rem 1.1rem;
    border-radius: 4px;
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    text-decoration: none;
    color: rgba(245, 200, 100, 1);
    background: rgba(245, 158, 11, 0.18);
    border: 1px solid rgba(245, 158, 11, 0.6);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    transition: background 200ms ease, border-color 200ms ease;
    pointer-events: auto;
}
.cinema-station-dossier-cta:hover {
    background: rgba(245, 158, 11, 0.32);
    border-color: rgba(245, 200, 100, 0.85);
}

/* Narrow-viewport rules: collapse split zone gracefully */
@media (max-width: 800px) {
    .cinema-station-titlecard {
        top: clamp(7rem, 12vh, 9rem);
        max-width: 90vw;
        left: 5vw;
    }
    .cinema-station-titlecard-headline { font-size: 1.5rem; line-height: 1.15; }
    .cinema-station-dossier .cinema-hud-frame {
        width: clamp(220px, 60vw, 320px);
    }
}

/* ---- HUD frame variant ----
   PNG-based station panel positioned in the lower-left as an
   "accoutrement" — central wireframe stays the visual hero, the HUD
   frame sits beside it as a supporting overlay. Boot-up animation
   drives the frame's transform/filter from `--enter: 0` (booting) to
   `--enter: 1` (fully present). */
.cinema-station-hud {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.cinema-hud-frame {
    --enter: 1;
    --exit: 0;
    position: absolute;
    /* Lower-left anchor. Width sized so a portrait frame (aspect ≈ 0.75)
       fits as a "control terminal" without occupying more than ~half the
       viewport height. Height derives from the aspect-ratio prop. */
    bottom: clamp(2rem, 6vh, 5rem);
    left: clamp(1.5rem, 4vw, 4rem);
    width: clamp(280px, 28vw, 400px);
    pointer-events: auto;
    /* Entry: slide UP from below. Exit: fade opacity (no translation). */
    transform: translateY(calc((1 - var(--enter)) * 130%));
    opacity: clamp(0, min(calc(var(--enter) * 1.6), calc(1 - var(--exit))), 1);
    will-change: transform, opacity;
    transition: transform 120ms linear, opacity 120ms linear;
}
.cinema-hud-frame-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    pointer-events: none;
    user-select: none;
    -webkit-user-drag: none;
}
.cinema-hud-frame-content {
    position: absolute;
    display: flex;
    flex-direction: column;
    /* Fill the safe area top-to-bottom so the inner panel can pin its
       CTA to the bottom while the headline anchors at the top. */
    align-items: stretch;
    overflow: hidden;
    /* Content rides with the frame — no separate fade. The whole panel
       (frame + text + CTA) slides in together as one cohesive unit. */
}

/* HUD-frame inner content — portrait variant.
   The frame is taller-than-wide so we have room for a more dramatic
   headline + multiline subline + CTA pinned to the bottom. */
.cinema-station-hud .cinema-panel {
    /* Neutralize default panel chrome — HUD frame provides its own */
    position: static;
    background: transparent;
    border: none;
    padding: 0;
    box-shadow: none;
    backdrop-filter: none;
    /* Stretch to fill safe area, distribute children top-to-bottom */
    display: flex;
    flex-direction: column;
    height: 100%;
}
.cinema-station-hud .cinema-station-rune {
    font-size: clamp(0.62rem, 0.78vw, 0.78rem);
    margin: 0 0 0.5rem;
    letter-spacing: 0.25em;
}
.cinema-station-hud .cinema-station-headline {
    font-size: clamp(1.1rem, 1.5vw, 1.55rem);
    line-height: 1.08;
    margin: 0;
}
.cinema-station-hud .cinema-rule {
    width: 50px;
    margin: 0.7rem 0;
}
.cinema-station-hud .cinema-station-subline {
    font-size: clamp(0.78rem, 0.9vw, 0.92rem);
    line-height: 1.5;
    margin: 0;
    color: rgba(168, 207, 236, 0.92);   /* ice-blue, matching hero subline */
}
/* Push the CTA row to the bottom of the safe area for a "movie-poster
   credit block" feel — headline anchored top, CTA anchored bottom. */
.cinema-station-hud .cinema-cta-row {
    margin-top: auto;
    padding-top: 1rem;
}
.cinema-station-hud .cinema-cta {
    font-size: 0.66rem;
    padding: 0.65rem 1rem;
    letter-spacing: 0.24em;
}
[data-panel-style] .cinema-station-hud .cinema-panel {
    position: static;
}
.cinema-station-rune {
    color: rgba(96, 165, 250, 0.7);
    font-size: 0.85rem;
    letter-spacing: 0.22em;
    margin: 0 0 0.4rem;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
}
.cinema-station-headline {
    font-family: 'Orbitron', system-ui, sans-serif;
    font-size: clamp(1.6rem, 3.2vw, 2.4rem);
    font-weight: 700;
    line-height: 1.0;
    margin: 0;
    text-shadow: 0 2px 24px rgba(0, 0, 0, 0.75);
}
.cinema-station-subline {
    font-size: clamp(0.85rem, 1.2vw, 1rem);
    line-height: 1.5;
    color: rgba(220, 230, 250, 0.82);
    max-width: 50ch;
    margin: 0 0 1rem;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.7);
}

/* Accent colors (per station) */
.cinema-accent-gold .cinema-headline-accent { color: #fbbf24; }
.cinema-accent-blue .cinema-headline-accent { color: #48caff; }
.cinema-accent-cyan .cinema-headline-accent { color: #22d3ee; }

/* === Tactical-card color tokens, scoped per accent ===
   Every station's tactical-card slate / divider / bullets / headline
   accent reads from these vars. To add a new accent: declare these
   four values on .cinema-accent-NAME and the entire card auto-themes. */
.cinema-accent-gold {
    --tc-accent: #E5CB99;
    --tc-glow-1: rgba(255, 231, 148, 0.95);  /* sharp inner highlight */
    --tc-glow-2: rgba(229, 203, 153, 0.85);  /* mid halo */
    --tc-glow-3: rgba(168, 133, 58, 0.5);    /* outer atmospheric */
    --tc-headline-accent-1: rgba(255, 215, 110, 0.42);
    --tc-headline-accent-2: rgba(255, 220, 140, 0.35);
    --tc-headline-accent-3: rgba(255, 230, 160, 0.3);
    --tc-headline-accent-4: rgba(255, 240, 190, 0.25);
}
.cinema-accent-blue {
    /* Hero plasma blue — pulled from .cinema-hero-slate-runes so the
       blue stations (3D, Apparel) read as the same energy as the
       hero's rune kicker + "imagination" accent. Tighter, more
       saturated than the previous periwinkle-blue token. */
    --tc-accent: #48caff;
    --tc-glow-1: rgba(154, 236, 255, 0.95);  /* light-blue-white inner */
    --tc-glow-2: rgba(0, 158, 255, 0.85);    /* saturated mid */
    --tc-glow-3: rgba(0, 99, 255, 0.5);      /* deep outer */
    --tc-headline-accent-1: rgba(0, 158, 255, 0.42);
    --tc-headline-accent-2: rgba(72, 202, 255, 0.35);
    --tc-headline-accent-3: rgba(125, 220, 255, 0.3);
    --tc-headline-accent-4: rgba(180, 235, 255, 0.25);
}
.cinema-accent-cyan {
    --tc-accent: #22d3ee;
    --tc-glow-1: rgba(154, 240, 255, 0.95);
    --tc-glow-2: rgba(34, 211, 238, 0.85);
    --tc-glow-3: rgba(8, 145, 178, 0.5);
    --tc-headline-accent-1: rgba(34, 211, 238, 0.42);
    --tc-headline-accent-2: rgba(80, 220, 245, 0.35);
    --tc-headline-accent-3: rgba(130, 235, 250, 0.3);
    --tc-headline-accent-4: rgba(180, 245, 255, 0.25);
}
.cinema-accent-gold .cinema-rule-accent {
    background: linear-gradient(90deg, rgba(245, 158, 11, 0.7), transparent);
}
.cinema-accent-blue .cinema-rule-accent {
    background: linear-gradient(90deg, rgba(96, 165, 250, 0.7), transparent);
}
.cinema-accent-cyan .cinema-rule-accent {
    background: linear-gradient(90deg, rgba(34, 211, 238, 0.7), transparent);
}

/* ===== Variant: WIDE (D) — wide bottom-anchored panel ===== */
[data-panel-style="wide"] .cinema-panel {
    position: absolute;
    left: 5%;
    right: 5%;
    bottom: 8%;
    background: rgba(2, 5, 11, 0.6);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(96, 165, 250, 0.45);
    border-radius: 10px;
    padding: 1.4rem 1.8rem;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 24px rgba(59, 130, 246, 0.18);
}
[data-panel-style="wide"] .cinema-accent-gold .cinema-panel {
    border-color: rgba(245, 158, 11, 0.55);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 28px rgba(245, 158, 11, 0.18);
}
[data-panel-style="wide"] .cinema-panel:hover {
    transform: perspective(800px) rotateX(0.5deg) rotateY(-0.5deg);
    transition: transform 280ms ease;
}

/* ===== Variant: SIDE (F) — left-anchored vertical panel ===== */
[data-panel-style="side"] .cinema-panel {
    position: absolute;
    left: 5%;
    top: 50%;
    transform: translateY(-50%);
    width: 38%;
    min-width: 320px;
    max-width: 520px;
    background: rgba(2, 5, 11, 0.62);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid rgba(96, 165, 250, 0.5);
    border-left: 3px solid rgba(96, 165, 250, 0.7);
    border-radius: 4px;
    padding: 1.6rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 0 28px rgba(59, 130, 246, 0.2);
}
[data-panel-style="side"] .cinema-accent-gold .cinema-panel {
    border-left-color: rgba(245, 158, 11, 0.85);
}
[data-panel-style="side"] .cinema-panel:hover {
    transform: translateY(-50%) perspective(800px) rotateY(-1deg);
    transition: transform 280ms ease;
}

/* ===== Variant: TEXT-ON-SCENE (G) — no panel ===== */
[data-panel-style="text-on-scene"] .cinema-panel {
    position: absolute;
    left: 5%;
    right: 5%;
    bottom: 12%;
    max-width: 720px;
    /* No background, no border, no blur — just text */
    background: transparent;
    border: none;
    padding: 0;
}
[data-panel-style="text-on-scene"] .cinema-station-overlay {
    /* Add a bottom-gradient darkening to the overlay itself for readability */
    background: linear-gradient(
        180deg,
        transparent 50%,
        rgba(2, 5, 11, 0.55) 100%
    );
}

/* ---- Mobile (<768px): collapse panels to bottom-strip regardless of variant ---- */
@media (max-width: 767px) {
    [data-panel-style] .cinema-panel {
        position: absolute;
        left: 4%;
        right: 4%;
        bottom: 6%;
        top: auto;
        transform: none;
        width: auto;
        min-width: 0;
        max-width: none;
        background: rgba(2, 5, 11, 0.7);
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px);
        border: 1px solid rgba(96, 165, 250, 0.45);
        border-radius: 8px;
        padding: 1rem 1.2rem;
    }
    .cinema-station-headline { font-size: 1.4rem; }
    .cinema-hero-headline    { font-size: 1.6rem; }
}

/* ---- Reduced motion: disable all animation and transition ---- */
@media (prefers-reduced-motion: reduce) {
    .cinema-station-overlay,
    .cinema-cta,
    .cinema-panel {
        transition: none !important;
        animation: none !important;
    }
    .cinema-scroll-chevron { animation: none; }
    .cinema-loading-pulse  { animation: none; opacity: 0.4; }
}
