/* ============================================================================
   DRAGONEYE ACADEMY — SALES PAGE V2

   ⚠️ DELIBERATELY SEPARATE FROM ../styles.css. V1 stays live as the backup, and
   a backup you can break by editing is not a backup.

   THE BRIEF: hook first, then build, and the scroll itself has to be worth
   doing. Panels stacked on top of each other are still panels, so every beat
   below has a mechanic: the turn cross-fades, the falsehoods scroll past a
   pinned heading, the rail travels sideways, the cinema plates hold while the
   words move over them.

   ⛔ ALL OF IT DEGRADES TO A READABLE PAGE. Every mechanic sits behind
   @supports (animation-timeline) and prefers-reduced-motion. Without them you
   get plain stacked sections in the right order. The words are the content;
   the motion is never load-bearing.

   Motion budget: transform and opacity only, driven by scroll timelines, which
   the browser runs off the main thread. Nothing above the fold waits on JS.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Rethink+Sans:ital,wght@0,400..800;1,400..600&display=swap');

:root{
  --ink-900:#0b0d0c; --ink-850:#0f1211; --ink-800:#141817; --ink-750:#191e1c;
  --ink-700:#1f2523; --ink-600:#2a312e; --ink-500:#3a423f;
  --gold-deep:#a8772a; --gold:#e8c068; --gold-bright:#ffd86b;
  --warm-white:#f3f1ec;

  --bg:var(--ink-900); --surface:var(--ink-800); --surface-raised:var(--ink-750);
  --text:var(--warm-white); --text-muted:#aba59c; --text-faint:#6f6b63;
  --on-accent:#1a1407; --divider:var(--ink-600);
  --hairline-tool:rgba(168,119,42,0.55); --hairline-data:rgba(243,241,236,0.18);
  --accent:var(--gold); --accent-strong:var(--gold-bright); --accent-deep:var(--gold-deep);
  --accent-gradient:linear-gradient(135deg,#8a5e22 0%,#e8c068 22%,#fff3c8 40%,#e8c068 52%,#a8772a 68%,#ffd86b 86%,#9a6b1e 100%);
  --accent-cta:linear-gradient(180deg,#ffe6a3 0%,#ecc873 46%,#caa040 100%);

  --font-display:"Rethink Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
  --font-sans:"Rethink Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
  --font-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --tracking-caps:0.22em;

  --maxw:1320px;
  --pad:clamp(1.25rem,4vw,3rem);
  --band-y:clamp(6rem,14vh,11rem);
  --dur-fast:160ms; --dur-base:320ms; --dur-slow:900ms;
  --ease-out:cubic-bezier(0.16,1,0.3,1);
  --radius-md:12px; --radius-lg:20px; --radius-pill:999px;
}
:root{color-scheme:dark}

*,*::before,*::after{box-sizing:border-box}

/* ⛔ THE hidden ATTRIBUTE LOSES TO ANY AUTHOR display RULE, AND IT LOSES
   SILENTLY. The browser implements it as `display:none` in its OWN stylesheet,
   which sits below everything we write, so the moment an element is given
   `display:flex` or `display:grid` the attribute stops doing anything at all.
   Nothing errors. The element simply stays on screen.

   It bit on /booked on 12 Aug 2026: the "Access is set up" panel is a flex
   column, so it was visible from page load, sitting under a booking form
   nobody had submitted yet and announcing a success that had not happened.
   Worse, it looked exactly like a security failure until the empty "signed up
   as" line proved the handler had never run.

   ⚠️ !important is not laziness here. Without it this rule is just another
   author rule and loses to any later one with equal or higher specificity,
   which is the whole problem restated. */
[hidden]{display:none !important}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-sans);
     font-size:clamp(1rem,0.5vw + 0.9rem,1.15rem);line-height:1.6;
     -webkit-font-smoothing:antialiased;overflow-x:hidden}

.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
img{max-width:100%;height:auto;display:block}
a{color:inherit}
p{margin:0 0 1.15rem}

/* ⛔ TRACKING. This was -0.035em on headings and -0.045em on the price, which
   at display sizes pulled the letters into each other and read as broken
   kerning. It was not the typeface, it was me. Rethink Sans is the brand face,
   shared with the platform and the product site, and it is not this page's to
   change: see dragoneye-design-system/tokens.css and rule 1 in CLAUDE.md.
   Large type needs LESS negative tracking, not more. Keep it gentle. */
h1,h2,h3{font-family:var(--font-display);font-weight:800;margin:0;
         letter-spacing:-0.015em;line-height:1.02;text-wrap:balance;
         font-kerning:normal;font-variant-ligatures:common-ligatures}
h2{font-size:clamp(2.1rem,4.9vw,4.1rem);letter-spacing:-0.012em;line-height:1.06}
h3{font-size:clamp(1.15rem,1.5vw,1.5rem);font-weight:700;letter-spacing:-0.005em;line-height:1.2}

.kicker{font-family:var(--font-mono);font-size:0.7rem;letter-spacing:var(--tracking-caps);
        text-transform:uppercase;color:var(--accent-deep);margin:0 0 1.4rem;display:block}
.muted{color:var(--text-muted)} .faint{color:var(--text-faint)} .sm{font-size:0.9rem}
.grad{background:var(--accent-gradient);-webkit-background-clip:text;background-clip:text;color:transparent}
.lede{font-size:clamp(1.1rem,1vw + 0.85rem,1.5rem);color:var(--text-muted);
      line-height:1.5;max-width:58ch;text-wrap:pretty}

.skip{position:absolute;left:-9999px;background:var(--accent);color:var(--on-accent);
      padding:0.7rem 1.1rem;z-index:200;font-weight:700}
.skip:focus{left:0;top:0}

.rv{opacity:0;transform:translateY(26px);
    transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out)}
.rv.in{opacity:1;transform:none}
.rv[data-d="1"]{transition-delay:90ms}
.rv[data-d="2"]{transition-delay:180ms}
.rv[data-d="3"]{transition-delay:270ms}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;
     padding:0.9rem 1.7rem;border-radius:var(--radius-pill);font-weight:700;
     font-size:0.98rem;text-decoration:none;border:1px solid transparent;cursor:pointer;
     transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out)}
.btn-primary{background:var(--accent-cta);color:var(--on-accent);
             box-shadow:0 1px 0 rgba(255,255,255,0.35) inset}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 14px 34px rgba(232,192,104,0.26)}
.btn-sm{padding:0.55rem 1.15rem;font-size:0.88rem}
.btn-lg{padding:1.05rem 2.2rem;font-size:1.05rem}

/* ── nav ────────────────────────────────────────────────────────────────── */
.nav{position:fixed;inset:0 0 auto 0;z-index:60;border-bottom:1px solid transparent;
     transition:background var(--dur-base),border-color var(--dur-base),backdrop-filter var(--dur-base)}
.nav.stuck{background:rgba(11,13,12,0.86);backdrop-filter:blur(16px);border-bottom-color:var(--divider)}
.nav-in{display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
        padding-block:clamp(0.8rem,1.6vh,1.3rem)}
.nav-mark img{width:clamp(140px,12vw,180px)}
.nav-links{display:flex;align-items:center;gap:clamp(1rem,2vw,2.2rem)}
.nav-links a{text-decoration:none;font-size:0.9rem;color:var(--text-muted)}
.nav-links a:hover{color:var(--text)}
.nav-links .btn{color:var(--on-accent)}

/* ══ 1 · HERO ═══════════════════════════════════════════════════════════ */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;
      justify-content:center;overflow:hidden;padding-top:6rem}
.hero-stage{position:absolute;inset:0;z-index:0}
#heroScene{position:absolute;inset:0;opacity:0;transition:opacity 1.2s var(--ease-out)}
#heroScene.ready{opacity:1}
#heroScene canvas{width:100%!important;height:100%!important;display:block}
.hero-still{position:absolute;inset:0;opacity:1;transition:opacity 1.2s var(--ease-out);
            background:url("../assets/hero-site.jpg") center 40%/cover no-repeat}
.hero-still.gone{opacity:0}
/* Three layers, in order: a soft wash down the copy side so the longer promise
   line stays legible over bright grass, the radial pool it sits in, and a lift
   off the bottom so the section joins the page. Feathered to nothing by ~85%
   so the building is never boxed in, which is the bit Jeremy liked. */
.hero-vig{position:absolute;inset:0;
  background:
    linear-gradient(100deg,rgba(11,13,12,0.92) 0%,rgba(11,13,12,0.78) 32%,rgba(11,13,12,0.3) 60%,rgba(11,13,12,0) 86%),
    radial-gradient(120% 90% at 15% 85%,rgba(11,13,12,0.9) 0%,rgba(11,13,12,0.6) 40%,rgba(11,13,12,0) 74%),
    linear-gradient(to top,var(--bg) 0%,rgba(11,13,12,0.25) 24%,rgba(11,13,12,0) 52%)}
.hero-in{position:relative;z-index:1}
/* Two lines, not three, and pulled back from 9.5rem. At the old size it filled
   the screen and left the reader nowhere to look. Line height sits just above
   1 so the two lines read as a pair without touching. */
.hero h1{font-size:clamp(2.7rem,7.6vw,6.6rem);line-height:1.0;letter-spacing:-0.018em}
.hero h1 span{display:block}
/* Wider than it was: this is now the promise, not a tagline, so it needs room
   to read as one thought rather than breaking after three words. */
.hero-sub{margin-top:clamp(1.4rem,2.6vh,2.2rem);font-size:clamp(1.02rem,1.15vw,1.3rem);
          color:var(--text);max-width:50ch;line-height:1.5;text-wrap:pretty}
.hero-foot{position:absolute;left:0;right:0;bottom:clamp(1.2rem,3vh,2.4rem);z-index:1;
           display:flex;align-items:flex-end;justify-content:space-between;gap:1rem}
.hero-cred{font-family:var(--font-mono);font-size:0.7rem;letter-spacing:0.1em;
           text-transform:uppercase;color:var(--text-faint)}
.scroll-cue i{display:block;width:1px;height:52px;
  background:linear-gradient(to bottom,rgba(232,192,104,0),var(--accent-deep) 55%,rgba(232,192,104,0));
  animation:cue 2.8s var(--ease-out) infinite}
@keyframes cue{0%{opacity:0;transform:translateY(-12px)}45%{opacity:1}100%{opacity:0;transform:translateY(14px)}}

/* ══ 2 · THE TURN — the revelation ══════════════════════════════════════
   Base (no scroll-timeline): both lines simply stack and read in order. */
.turn{background:var(--bg)}
.turn-track{padding:clamp(6rem,18vh,12rem) 0}
.turn-stage{display:grid}
.statement{font-family:var(--font-display);font-weight:800;letter-spacing:-0.016em;
           line-height:1.06;font-size:clamp(2rem,5.4vw,4.4rem);margin:0;text-wrap:balance}
.turn-a{color:var(--text-muted);margin-bottom:1.2rem}
.turn-b{color:var(--text)}
/* Base: the plate sits behind, first image only. The pair only cross-fades
   where scroll timelines exist, and the captions only appear with them, so a
   fallback reader is never told about a second image they cannot see. */
.turn-media{position:absolute;inset:0;z-index:0;overflow:hidden}
/* ⛔ BOTH PLATES ARE POSITIONED IDENTICALLY. The two drawings share the same
   geometry, so if the plates differed by a single pixel the curve would jump
   during the swap and the whole effect would collapse into a slideshow. Same
   box, same padding, same alignment. Do not style one without the other. */
.turn-plate{position:absolute;inset:0;display:flex;align-items:center;
            justify-content:flex-end;padding:clamp(1.5rem,5vw,6rem)}
.turn-plate-b{opacity:0}
.turn-diagram{width:min(60%,1000px);height:auto;max-height:72%}

/* Beat one: the live quarry fills the plate, biased right so it never fights
   the copy. The section drawing sits under it and fades out once tiles land,
   which also makes it the honest fallback when the scene cannot run at all. */
.turn-plate-a{padding:0;justify-content:stretch}
/* Centred on the page, not biased right. It was inset 22% from the left to
   keep clear of the copy, which threw the composition off: the model has to
   sit in the middle of the screen and the type sits over it. */
#quarryScene{position:absolute;inset:0;opacity:0;
             transition:opacity 1.4s var(--ease-out)}
#quarryScene.ready{opacity:1}
#quarryScene canvas{width:100%!important;height:100%!important;display:block}
.turn-fallback{position:absolute;top:50%;right:clamp(1.5rem,5vw,6rem);translate:0 -50%;
               width:min(60%,1000px);height:auto;max-height:72%;
               opacity:1;transition:opacity 1s var(--ease-out)}
.turn-fallback.gone{opacity:0}
.turn-scrim{position:absolute;inset:0;
  background:
    linear-gradient(100deg,rgba(11,13,12,0.94) 0%,rgba(11,13,12,0.86) 34%,rgba(11,13,12,0.55) 66%,rgba(11,13,12,0.35) 100%),
    linear-gradient(to bottom,var(--bg) 0%,rgba(11,13,12,0) 22%,rgba(11,13,12,0) 78%,var(--bg) 100%)}
.turn-stage .wrap{position:relative;z-index:1}
/* Sentences, not labels. These were mono caps at 0.72rem, which is a caption
   treatment, and a caption cannot carry a feeling. Set as readable lines so
   they land as the human half of each beat. */
.turn-cap{display:none;font-size:clamp(1rem,1.05vw,1.2rem);line-height:1.5;
          color:var(--text-muted);margin:1.8rem 0 0;max-width:42ch;text-wrap:pretty}
.turn-cap-b{color:var(--text)}

/* ══ 3 · WHAT YOU WERE TOLD ═════════════════════════════════════════════ */
.told{padding:var(--band-y) 0;background:var(--ink-850);border-top:1px solid var(--divider)}
.told-grid{display:grid;gap:clamp(2rem,5vw,5rem);
           grid-template-columns:minmax(0,0.85fr) minmax(0,1.15fr);align-items:start}
.told-stick{position:sticky;top:clamp(6rem,14vh,9rem)}
.told-stick h2{font-size:clamp(1.9rem,3.4vw,3.2rem)}
.told-note{margin:clamp(1.1rem,2.4vh,1.8rem) 0 0;max-width:34ch;color:var(--text-muted);
           font-size:0.96rem;line-height:1.55;
           padding-top:clamp(1rem,2.2vh,1.6rem);border-top:1px solid var(--hairline-tool)}
.told-list{display:flex;flex-direction:column;gap:clamp(3rem,9vh,7rem)}
.lie{border-top:1px solid var(--hairline-tool);padding-top:clamp(1.4rem,3vh,2.2rem)}
.lie-claim{font-family:var(--font-display);font-style:italic;font-weight:700;
           font-size:clamp(1.35rem,2.6vw,2.3rem);line-height:1.18;color:var(--text-muted);
           margin-bottom:1.2rem;text-wrap:balance}
.lie-truth{margin:0 0 1.1rem;color:var(--text);max-width:56ch}
/* The itch. Corrects nothing further: it names the how, the when and the why
   as things taught rather than things told, so the reader leaves the section
   knowing they were misled AND knowing they still can't do it yet. */
.lie-more{margin:0;max-width:52ch;color:var(--accent);font-size:0.96rem;
          padding-left:1rem;border-left:1px solid var(--hairline-tool)}
.told-close{margin:clamp(1rem,3vh,2rem) 0 0;font-family:var(--font-display);font-weight:800;
            font-size:clamp(1.25rem,2.2vw,2rem);line-height:1.25;letter-spacing:-0.02em;
            text-wrap:balance;color:var(--text)}

/* ══ 4/7 · CINEMA ═══════════════════════════════════════════════════════
   Base: full-bleed plate behind the copy. Enhanced: the plate PINS and the
   words travel over it, which is what stops it reading as another panel. */
.cinema{position:relative;overflow:clip;background:var(--bg)}
/* A cinema band with no plate behind it yet. Keeps the type and rhythm of its
   siblings so the page does not develop a hole while we wait for an asset. */
.cinema-bare{background:var(--ink-850);border-block:1px solid var(--divider)}
.cinema-media{position:absolute;inset:0;z-index:0;overflow:hidden}
.cinema-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:scale(1.06)}
.cinema-scrim{position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(11,13,12,0.96) 0%,rgba(11,13,12,0.88) 38%,rgba(11,13,12,0.5) 68%,rgba(11,13,12,0.2) 100%)}
.cinema-right .cinema-scrim{background:linear-gradient(270deg,rgba(11,13,12,0.96) 0%,rgba(11,13,12,0.88) 38%,rgba(11,13,12,0.5) 68%,rgba(11,13,12,0.2) 100%)}
/* The split content is centred, not hard left, so a left-weighted scrim would
   leave the right hand column sitting on bare photograph. Even wash across the
   text, with the plate still readable out to the right edge. */
.cinema-fit .cinema-scrim{background:
  linear-gradient(90deg,rgba(11,13,12,0.95) 0%,rgba(11,13,12,0.88) 46%,rgba(11,13,12,0.74) 76%,rgba(11,13,12,0.56) 100%),
  linear-gradient(to bottom,var(--bg) 0%,rgba(11,13,12,0) 16%,rgba(11,13,12,0) 84%,var(--bg) 100%)}
.cinema-in{position:relative;z-index:1;max-width:60ch;
           padding-block:clamp(6rem,18vh,12rem)}

/* ── the split: claim left, account right ───────────────────────────────
   Sized to sit inside one viewport rather than being read while scrolling.
   The heading column is narrower than the copy column on purpose: a short
   heavy statement against a longer light one is what stops it feeling
   lop-sided, which two equal columns would not fix. */
.cinema-split{max-width:min(var(--maxw),1180px);display:grid;align-items:start;
              gap:clamp(1.8rem,3.6vw,4rem);
              grid-template-columns:minmax(0,0.92fr) minmax(0,1.08fr)}
.cinema-split h2{font-size:clamp(1.8rem,3vw,2.9rem);margin-bottom:1.4rem}
.cinema-split .lead-line{margin-bottom:0}
.cinema-split .cinema-copy p{max-width:none;font-size:clamp(0.98rem,0.95vw,1.08rem);
                             line-height:1.62;margin-bottom:0.95rem}
.cinema-split .sig{margin-top:1.2rem}
.cinema-right .cinema-in{margin-left:auto}
.cinema-in h2{margin-bottom:clamp(1.4rem,3vh,2.2rem)}
.cinema-copy p{color:var(--text-muted);max-width:56ch}
.cinema-copy strong{color:var(--text)}
/* The thesis line. Sits above the personal account and carries it, so it is
   sized and weighted as a statement rather than as the first paragraph. */
.lead-line{font-family:var(--font-display);font-weight:700;color:var(--text)!important;
           font-size:clamp(1.25rem,1.9vw,1.75rem);line-height:1.3;letter-spacing:-0.012em;
           max-width:30ch!important;margin-bottom:1.8rem;text-wrap:balance}
.sig{font-family:var(--font-mono);font-size:0.82rem;letter-spacing:0.06em;
     color:var(--accent-deep);margin-top:1.8rem}

/* ══ 5 · THE BELIEF ═════════════════════════════════════════════════════ */
.beat{padding:clamp(7rem,20vh,15rem) 0;background:var(--bg)}
.beat-gold{background:var(--ink-850);border-block:1px solid var(--divider)}
.beat-gold .statement{margin-bottom:clamp(2.5rem,6vh,4.5rem)}
.beat-cols{display:grid;gap:clamp(1.6rem,4vw,4rem);
           grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr));max-width:96ch}
.beat-cols p{color:var(--text-muted);margin:0}
.beat-cols strong{color:var(--text)}

/* ══ 6 · THE THREE DAYS — the rail ══════════════════════════════════════
   Base: a plain grid. Enhanced: pins and travels sideways so the four ideas
   arrive one at a time instead of being taken in at a glance. */
/* ⚠️ Bottom padding matters here. The section used to end flush against the
   next one, which is invisible while the rail is the last thing in it and
   very visible once a closing statement sits after the rail. */
.days{padding:var(--band-y) 0;background:var(--bg)}
.days h2{margin-bottom:1.6rem}
.days .lede{margin-bottom:clamp(3rem,7vh,5rem)}
.rail-track{padding-bottom:var(--band-y)}
.rail-row{display:grid;gap:0;grid-template-columns:repeat(auto-fit,minmax(min(100%,270px),1fr));
          border-top:1px solid var(--divider)}
.day{padding:clamp(2rem,3.5vw,3rem) clamp(1.2rem,2vw,2rem) clamp(2.4rem,4vw,3.4rem) 0;
     border-bottom:1px solid var(--divider)}
.day + .day{border-left:1px solid var(--divider);padding-left:clamp(1.4rem,2.4vw,2.4rem)}
.day-n{font-family:var(--font-mono);font-size:0.72rem;letter-spacing:var(--tracking-caps);
       color:var(--accent-deep);display:block;margin-bottom:1.4rem}
/* ⭐ The rail cards were a heading and a paragraph sitting at the bottom of a
   tall empty box, and the emptiness read as unfinished rather than as space.
   Each now carries a technical line mark in the top half.

   ⛔ EACH MARK DRAWS THE CARD'S STORY, NOT ITS SUBJECT MATTER. The first
   attempt drew the syllabus (a flight plan, a tolerance band) and the cards
   stopped making sense on their own: a tolerance band is a thing we teach, it
   is not a client conversation. Read the paragraph, draw what it is about.
   01 a chain, because the copy says chain. 02 a control point on the real
   ground with the delivered surface metres above it. 03 two people talking,
   one asking and one answering. 04 the invoice you actually have to send.

   ⛔ DRAWINGS, NOT ICONS. All four are on the same 200x120 grid with the same
   stroke, so they read as one set off a drawing board. A clipart set here
   would undo a page whose whole argument is that this trade overclaims.
   Masked so the mark fades out downward into the card rather than stopping at
   an edge, which is what keeps it a watermark and not a picture. */
.day-mark{display:block;width:clamp(104px,44%,230px);height:auto;
          margin:clamp(0.8rem,2vh,1.4rem) 0 clamp(1.4rem,3vh,2.2rem);
          color:var(--accent);opacity:0.34;
          fill:none;stroke:currentColor;stroke-width:2.4;
          stroke-linecap:round;stroke-linejoin:round;
          -webkit-mask-image:linear-gradient(180deg,#000 46%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 46%,transparent 100%)}
.day-mark .dm-ghost{opacity:0.5}
.day-mark .dm-dash{stroke-dasharray:5 6}
.day-mark .dm-dot{fill:currentColor;stroke:none}
/* The only heavy stroke in the set, and it is the total on the invoice. */
.day-mark .dm-strong{stroke-width:5.5}
.day-mark .dm-cur{fill:currentColor;stroke:none;font-family:var(--font-mono);
                  font-size:23px;font-weight:600}
.day h3{margin-bottom:0.7rem}
.day p{color:var(--text-muted);font-size:0.97rem;margin:0}
/* ⭐ The verdict that closes the section. It was a single left aligned line on
   a hairline, sitting in the space the pinned rail leaves behind, and it read
   as text somebody had forgotten to delete rather than as a point being made.
   Centred so it agrees with the cards above it, and scaled so it reads as a
   conclusion.

   ⛔ ONE gold phrase, once, at the end of the section. Gold marks the
   important thing; a second gold line here would spend it for nothing. */
.days-close{margin-top:0;text-align:center}
.days-close p{margin-inline:auto}
.days-close-lead{margin-block:0;font-family:var(--font-display);font-weight:800;
                 font-size:clamp(1.5rem,3.2vw,2.9rem);line-height:1.16;
                 letter-spacing:-0.015em;max-width:24ch;text-wrap:balance;color:var(--text)}
.days-close-lead .hit{color:var(--accent)}
.days-close-sub{margin-block:clamp(1rem,2.4vh,1.7rem) 0;max-width:58ch;
                color:var(--text-muted);font-size:clamp(1rem,1.05vw,1.15rem)}

/* ══ 8 · WHO ════════════════════════════════════════════════════════════ */
.who{padding:var(--band-y) 0;background:var(--ink-850);border-block:1px solid var(--divider)}
.who h2{margin-bottom:clamp(2.5rem,6vh,4rem)}
.who-grid{display:grid;gap:clamp(1rem,2vw,1.8rem);
          grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr))}
.whocard{background:var(--surface);border:1px solid var(--divider);border-radius:var(--radius-lg);
         padding:clamp(1.8rem,3vw,2.8rem);
         transition:border-color var(--dur-base),transform var(--dur-base) var(--ease-out)}
.whocard:hover{border-color:var(--hairline-tool);transform:translateY(-3px)}
.whocard h3{font-size:clamp(1.3rem,2vw,1.75rem);margin-bottom:1rem}
.whocard p{color:var(--text-muted)}
.whocard p:last-child{margin:0;font-size:0.9rem}

/* ══ 9 · PRICE ══════════════════════════════════════════════════════════ */
.price-band{padding:var(--band-y) 0;background:var(--bg)}
.price-band h2{margin-bottom:1.4rem}
.price-band .lede{margin-bottom:clamp(2.6rem,6vh,4rem)}
/* ── the diary: dates left, panel right ────────────────────────────────
   Ported from V1, which had the right shape, and wired to /api/courses so the
   admin drives it. The panel head does not move when you change selection:
   only the figure, the label and the face beneath it swap, so the layout never
   jumps under the cursor. */
.diary{display:grid;gap:clamp(1.2rem,2.2vw,2rem);align-items:start;
       grid-template-columns:minmax(0,1.05fr) minmax(0,0.95fr)}
.dates{display:flex;flex-direction:column;gap:clamp(0.7rem,1.2vw,1rem)}

.date-card{display:grid;grid-template-columns:auto 1fr auto;gap:clamp(1rem,2vw,1.8rem);
           align-items:center;text-align:left;width:100%;cursor:pointer;
           background:var(--surface);border:1px solid var(--divider);
           border-radius:var(--radius-lg);padding:clamp(1.1rem,1.9vw,1.6rem);
           color:inherit;font:inherit;
           transition:border-color var(--dur-base),background var(--dur-base),
                      transform var(--dur-base) var(--ease-out)}
.date-card:hover:not(.sold){border-color:var(--hairline-tool);transform:translateY(-2px)}
.date-card[aria-pressed="true"]{border-color:var(--accent);background:var(--surface-raised)}
.date-card.sold{opacity:0.5;cursor:not-allowed}

/* ⚠️ Widened and stepped down from clamp(1.5,2.4vw,2.1) when dates became
   ordinals. "17th – 19th" is more than twice the width of "17–19", and at the
   old size it wrapped mid-range or shoved the title out of the card. The
   quarter cards ("Q4") keep their own larger size below, since they are two
   characters and can afford it. */
.dc-when{text-align:center;min-width:8.5rem}
.dc-when .d{display:block;font-family:var(--font-display);font-weight:800;
            font-size:clamp(1.15rem,1.7vw,1.5rem);letter-spacing:-0.01em;
            line-height:1.05;white-space:nowrap}
/* A quarter label is two characters, so it keeps the display presence the
   full dates can no longer afford. */
.dc-when.q .d{font-size:clamp(1.5rem,2.4vw,2.1rem);letter-spacing:-0.02em}
.dc-when .m{display:block;font-family:var(--font-mono);font-size:0.68rem;
            letter-spacing:var(--tracking-caps);text-transform:uppercase;
            color:var(--text-faint);margin-top:0.35rem}
.dc-title{display:flex;align-items:center;gap:0.6rem;flex-wrap:wrap;margin-bottom:0.35rem}
.dc-title strong{font-family:var(--font-display);font-size:clamp(1rem,1.2vw,1.15rem)}
.dc-meta{color:var(--text-muted);font-size:0.88rem;margin:0}
.dc-side{text-align:right;display:flex;flex-direction:column;align-items:flex-end;gap:0.45rem}
.dc-note{font-family:var(--font-mono);font-size:0.7rem;color:var(--text-faint)}

.pill{font-family:var(--font-mono);font-size:0.64rem;letter-spacing:0.14em;
      text-transform:uppercase;padding:0.3rem 0.6rem;border-radius:var(--radius-sm,6px);
      border:1px solid currentColor;white-space:nowrap}
.pill.open,.pill.confirmed{color:var(--accent);background:rgba(232,192,104,0.1)}
.pill.few{color:var(--accent-strong);background:rgba(255,216,107,0.12)}
/* ⚠️ Muted, not red. A full course is good news badly timed, not an error.
   Red would read as something having gone wrong and make a sold-out
   course feel like a broken page. */
.pill.gone{color:var(--text-faint);background:rgba(255,255,255,0.04)}
.pill.tbc{color:var(--text-muted)}

.dpanel{background:var(--surface);border:1px solid var(--hairline-tool);
        border-radius:var(--radius-lg);padding:clamp(1.5rem,2.6vw,2.4rem);
        position:sticky;top:clamp(6rem,13vh,8rem)}
.dpanel .kicker{margin-bottom:0.6rem}
.dpanel .price{margin-bottom:0.4rem;display:flex;align-items:baseline;gap:0.5rem;flex-wrap:wrap}
.dpanel .price span:last-child{font-size:clamp(0.9rem,1.1vw,1.1rem);color:var(--text-muted);
                               font-weight:600;letter-spacing:0;vertical-align:baseline;margin:0}
.incl{list-style:none;margin:1.4rem 0 1.6rem;padding:0;display:flex;flex-direction:column;gap:0.6rem}
.incl li{position:relative;padding-left:1.1rem;font-size:0.93rem;color:var(--text-muted)}
.incl li::before{content:"";position:absolute;left:0;top:0.62em;width:5px;height:5px;
                 border-radius:50%;background:var(--accent-deep)}
.incl strong{color:var(--text);font-weight:700}
.face-lead{font-size:0.95rem;color:var(--text-muted);margin:1.2rem 0 1rem}
.minmeter{border:1px solid var(--divider);border-radius:var(--radius-md);padding:0.9rem 1rem}
.minmeter-head{display:flex;justify-content:space-between;align-items:baseline;
               font-size:0.85rem;color:var(--text-muted);margin-bottom:0.6rem}
.minmeter-head b{color:var(--accent);font-size:1.05rem}
.minbar{height:4px;border-radius:999px;background:var(--ink-700);overflow:hidden}
.minbar span{display:block;height:100%;width:0;background:var(--accent-cta);
             transition:width var(--dur-slow) var(--ease-out)}
.minnote{font-size:0.82rem;color:var(--text-faint);margin:0.7rem 0 0}
.dpanel-cta{width:100%}
.dpanel-cta:disabled{opacity:0.55;cursor:not-allowed;transform:none;box-shadow:none}
.chosen{font-family:var(--font-mono);font-size:0.72rem;letter-spacing:0.1em;
        text-transform:uppercase;color:var(--text-faint);margin:0.8rem 0 0;text-align:center}
.dpanel .caa{margin-top:1.6rem;border-left:0;border-top:1px solid var(--hairline-data);
             padding:1.3rem 0 0}

.price-card{display:grid;gap:clamp(1.6rem,4vw,4rem);align-items:start;
            grid-template-columns:minmax(0,0.9fr) minmax(0,1.1fr);
            border:1px solid var(--hairline-tool);border-radius:var(--radius-lg);
            padding:clamp(1.8rem,3.4vw,3.2rem);background:var(--surface)}
.price{font-family:var(--font-display);font-weight:800;letter-spacing:-0.02em;line-height:0.95;
       font-size:clamp(3.4rem,7vw,6rem);margin:0 0 0.6rem;color:var(--accent)}
.price span{font-size:clamp(0.95rem,1.2vw,1.2rem);color:var(--text-muted);font-weight:600;
            letter-spacing:0;margin-left:0.5rem;vertical-align:super}
.price-note{color:var(--text-muted);font-size:0.95rem;margin-bottom:1.8rem}
.caa{border-left:2px solid var(--hairline-data);padding-left:clamp(1.1rem,2vw,1.8rem)}
.caa h3{font-size:1rem;margin-bottom:0.7rem}
.caa p{margin:0;color:var(--text-muted);font-size:0.95rem}

/* ══ 10 · FAQ ═══════════════════════════════════════════════════════════ */
.band-faq{padding:var(--band-y) 0;background:var(--ink-850);border-top:1px solid var(--divider)}
.band-faq h2{margin-bottom:clamp(2.2rem,5vh,3.4rem)}
.faq{border-top:1px solid var(--divider);max-width:82ch}
.faq details{border-bottom:1px solid var(--divider)}
.faq summary{cursor:pointer;list-style:none;padding:1.3rem 2.5rem 1.3rem 0;position:relative;
             font-family:var(--font-display);font-weight:700;
             font-size:clamp(1rem,1.2vw,1.2rem);letter-spacing:-0.01em}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:0.4rem;top:50%;width:9px;height:9px;
  border-right:2px solid var(--accent-deep);border-bottom:2px solid var(--accent-deep);
  translate:0 -60%;rotate:45deg;transition:rotate var(--dur-base) var(--ease-out)}
.faq details[open] summary::after{rotate:-135deg}
.faq summary:hover{color:var(--accent)}
.faq details p{margin:0 0 1.4rem;color:var(--text-muted);max-width:72ch}
/* The hinge between the questions about us and the questions about surveying.
   Set apart from the rows so it reads as the page speaking rather than as an
   answer somebody forgot to attach a question to. */
.faq-note{margin:0;padding:1.6rem 0;max-width:66ch;color:var(--text-muted);
          font-size:0.95rem;line-height:1.6;border-bottom:1px solid var(--divider)}

/* ══ 11 · ASK ═══════════════════════════════════════════════════════════ */
.ask{padding:clamp(5rem,12vh,9rem) 0;background:var(--bg);text-align:center}
.ask .lede{margin:0 auto clamp(2rem,4vh,3rem)}
.ask h2{margin-bottom:1.3rem}

/* ── footer ─────────────────────────────────────────────────────────────── */
.foot{border-top:1px solid var(--divider);padding:4rem 0 2.5rem;background:var(--ink-850)}
.foot-grid{display:flex;justify-content:space-between;gap:2rem;flex-wrap:wrap;align-items:flex-start}
.foot-mark{width:170px;margin-bottom:1rem;opacity:0.9}
.foot-strap{font-family:var(--font-display);font-weight:800;letter-spacing:var(--tracking-caps);
            text-transform:uppercase;font-size:0.78rem;color:var(--text-faint)}
.foot a{color:var(--text-muted);text-decoration:none;font-size:0.9rem}
.foot a:hover{color:var(--accent)}
.foot-col{display:flex;flex-direction:column;gap:0.6rem}
/* A button that must READ as one of the links beside it, because that is what
   it is: a change of screen, not a submit. Kept a real <button> so the keyboard
   and screen readers are told the truth about what it does. */
.foot-col .foot-ask{background:none;border:0;padding:0;margin:0;font:inherit;
  color:inherit;text-align:left;cursor:pointer;text-decoration:none}
.foot-col .foot-ask:hover{color:var(--accent)}
.foot-col .foot-ask:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.legal{margin:3rem auto 0;padding-top:1.8rem;border-top:1px solid var(--divider);
       font-size:0.82rem;line-height:1.75;color:var(--text-muted);text-align:center;text-wrap:pretty}

/* ════════════════════════════════════════════════════════════════════════
   SCROLL MECHANICS

   Everything above renders a complete, readable page on its own. Everything
   below is the scroll experience, and it only switches on where the browser
   supports scroll timelines AND the visitor has not asked for reduced motion.
   ════════════════════════════════════════════════════════════════════════ */
@supports (animation-timeline:view()){
@media (prefers-reduced-motion:no-preference){

  /* ── the turn: one line leaves as the other arrives ─────────────────── */
  .turn-track{height:260svh;padding:0;view-timeline-name:--turn;view-timeline-axis:block}
  .turn-stage{position:sticky;top:0;height:100svh;place-content:center;overflow:hidden}
  /* ⛔ BOTH LINES SHARE ONE GRID CELL. They were previously one in flow and one
     absolutely positioned, so they did not land in the same place and the swap
     read as a shuffle rather than a replacement. Same cell, same alignment,
     same baseline: the second line arrives exactly where the first left. */
  .turn-stage .wrap{display:grid;align-items:center}
  .turn-a,.turn-b{grid-area:1/1;margin:0;align-self:center}
  .turn-a{animation:turnOut linear both;animation-timeline:--turn;
          animation-range:contain 2% contain 42%}
  .turn-b{animation:turnIn linear both;animation-timeline:--turn;
          animation-range:contain 34% contain 76%}

  /* The plate changes with the words, so the whole screen turns rather than
     just the type. Same ranges as the lines they belong to. The images also
     drift very slightly apart, which stops the swap looking like a slideshow. */
  /* Row 1 holds both statements stacked on each other. Row 2 holds both
     captions stacked on each other. Four elements, two cells. */
  .turn-cap{display:block;grid-area:2/1;align-self:start;margin:1.8rem 0 0}
  .turn-stage .wrap{grid-template-rows:auto auto;row-gap:0;align-content:center}
  .turn-cap-a{animation:capOut linear both;animation-timeline:--turn;
              animation-range:contain 2% contain 40%}
  .turn-cap-b{animation:capIn linear both;animation-timeline:--turn;
              animation-range:contain 36% contain 74%}
  @keyframes capOut{from{opacity:1}to{opacity:0}}
  @keyframes capIn{from{opacity:0}to{opacity:1}}

  /* ⛔ NEITHER PLATE MOVES. No scale, no translate, opacity only. The drawings
     are the same section from the same viewpoint, so the curve has to sit
     perfectly still while the truth appears beneath it. Any transform here
     turns a revelation back into a slideshow. */
  .turn-plate-a{animation:plateOut linear both;animation-timeline:--turn;
                animation-range:contain 6% contain 48%}
  .turn-plate-b{animation:plateIn linear both;animation-timeline:--turn;
                animation-range:contain 30% contain 70%}
  @keyframes plateOut{from{opacity:1}to{opacity:0}}
  @keyframes plateIn{from{opacity:0}to{opacity:1}}
  @keyframes turnOut{
    0%{opacity:1;transform:none;filter:blur(0)}
    100%{opacity:0;transform:translateY(-38px) scale(0.97);filter:blur(6px)}
  }
  @keyframes turnIn{
    0%{opacity:0;transform:translateY(46px) scale(0.97);filter:blur(8px)}
    100%{opacity:1;transform:none;filter:blur(0)}
  }

  /* ── the rail: pin, then travel sideways ──────────────────────────────
     ⛔ THE CARDS ARE SIZED IN vw ON PURPOSE. They were capped at 440px, and
     on a wide monitor all four then fitted on screen at once: the row had
     nothing to travel, so the section pinned for three screens and did
     absolutely nothing. Four cards at 40vw is 160vw, so the row is wider than
     the viewport at every screen size and there is always something to move.

     The min(0px, …) guard is belt and braces: if the row ever did end up
     narrower than the viewport, the travel clamps to zero rather than sliding
     the content off to the right, which is what threw the alignment. */
  .rail-track{height:250svh;padding-bottom:0;view-timeline-name:--rail;view-timeline-axis:block}
  .rail-stage{position:sticky;top:0;height:100svh;display:flex;align-items:center;overflow:hidden}
  .rail-row{display:flex;grid-template-columns:none;border-top:0;gap:clamp(1rem,2vw,2.4rem);
            padding-inline:var(--pad);will-change:transform;
            animation:railX linear both;animation-timeline:--rail;
            animation-range:contain 0% contain 100%}
  /* ⛔ THE TRAVEL IS MEASURED IN JS, NOT CALCULATED IN CSS, and that is the
     whole point of --rail-travel. This used to be
       min(0px, calc(-100% + 100vw - (2 * var(--pad))))
     where 100% is the row's own width and 100vw may or may not include the
     scrollbar depending on the engine. Chrome agreed with that sum; Safari did
     not, so the rail pinned, travelled part way and stopped with cards still
     off screen. site.js measures scrollWidth against the stage and sets the
     exact pixels, which every engine agrees on because there is nothing left
     to interpret. Falls back to 0 if the script never runs, which is a rail
     that does not move rather than a rail that hides half its content. */
  @keyframes railX{
    from{transform:translateX(0)}
    to{transform:translateX(var(--rail-travel,0px))}
  }
  /* ⚠️ BELT AND BRACES FOR AN ENGINE THAT PINS BUT WILL NOT TRAVEL. If a
     browser claims animation-timeline and then does nothing useful with it,
     the row can still be dragged or swiped sideways and every card is
     reachable. It costs nothing where the animation works, because there is
     no overflow left to scroll once the row has travelled. */
  .rail-stage{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
  .rail-stage::-webkit-scrollbar{display:none}
  .rail-row .day{flex:0 0 clamp(290px,40vw,780px);border:1px solid var(--divider);
                 border-radius:var(--radius-lg);background:var(--surface);
                 padding:clamp(1.8rem,3vw,3.2rem);display:flex;flex-direction:column;
                 align-items:center;text-align:center;min-height:min(66svh,620px)}
  .rail-row .day + .day{border-left:1px solid var(--divider);
                        padding-left:clamp(1.8rem,3vw,3.2rem)}
  .rail-row .day h3{font-size:clamp(1.4rem,2.4vw,2.4rem);margin-bottom:0.9rem}
  .rail-row .day p{font-size:clamp(0.98rem,1.05vw,1.2rem);max-width:42ch;margin-inline:auto}

  /* ⭐ TWO auto margins, and that is the whole placement trick. Flexbox splits
     a flex line's free space equally between every auto margin it finds, so
     one after the number and one after the mark gives the number the top, the
     mark the optical centre of the void, and the text block the bottom.

     ⛔ The text has to stay pinned to the bottom. It is what makes the four
     cards agree with each other as the rail travels past; centre the whole
     stack instead and every heading sits at a different height because every
     paragraph is a different length. */
  .rail-row .day-n{margin-bottom:auto;font-size:0.8rem}
  /* ⛔ No mask in the rail. The downward fade existed to sink a top-left mark
     into the card, and on a centred symmetrical composition it reads lopsided
     instead. Even opacity makes it a drawing rather than a fading watermark. */
  .rail-row .day-mark{width:clamp(150px,50%,330px);margin:0 0 auto;
                      -webkit-mask-image:none;mask-image:none}

  /* ⛔ THE BALANCE FIX, and it is arithmetic rather than taste. The cards are
     centred in a 100svh sticky stage, so releasing the pin leaves
     (100svh - card height) / 2 of empty stage under them. The section carries
     NO bottom padding in this mode, so the closing statement inherited a
     screen of black above it and nothing at all below: it read as a half
     empty panel with the words crushed into the bottom quadrant.

     Mirroring that leftover as the section's bottom padding centres the
     statement optically in the space it was already sitting in, with no
     negative margins and no risk of it riding up over the pinned cards.

     ⚠️ The 66svh / 620px here MUST track .rail-row .day min-height above.
     Change one and the section goes lopsided again with nothing to show why. */
  .days{padding-bottom:calc((100svh - min(66svh,620px)) / 2)}
  .days-close{margin-top:0}

  /* ── cinema: the plate holds, the words move over it ────────────────── */
  .cinema-media{position:sticky;top:0;height:100svh;margin-bottom:-100svh}
  /* ⚠️ DEAD AS WRITTEN, and left here only because it hurts nothing while the
     one remaining band is .cinema-bare with no plate in it. view() on the img
     resolves against .cinema-media, which is overflow:hidden and therefore a
     scroll container that never scrolls, so this never runs. When the quarry
     plate lands, move this to the wrapper the way .cinema-fit does below. */
  .cinema-media img{animation:plate linear both;animation-timeline:view();
                    animation-range:entry 0% exit 100%}
  @keyframes plate{
    from{transform:scale(1.16) translate3d(0,-3%,0)}
    to{transform:scale(1.04) translate3d(0,3%,0)}
  }
  .cinema-in{padding-block:clamp(9rem,26vh,18rem)}

  /* ⛔ .cinema-fit OPTS OUT OF THE PIN. The hold only works when the copy is
     taller than the screen and has somewhere to travel. This section is
     deliberately sized to fit one view, so pinning it would give the same
     dead-scroll the rail had: a section held for two screens doing nothing.
     The plate carries the movement instead, see below. */
  .cinema-fit .cinema-media{position:absolute;height:100%;margin-bottom:0}
  .cinema-fit .cinema-in{padding-block:clamp(4rem,9vh,7rem)}

  /* ⭐ Not pinned, so the plate earns its keep by arriving and leaving: it
     fades up as the section comes on, holds while you read, fades away as you
     move on to the next one. That is the whole effect. Nothing else moves.

     ⛔ THE ANIMATION IS ON THE WRAPPER, NOT ON THE IMG, AND THAT IS THE WHOLE
     REASON THIS WORKS. `.cinema-media` sets overflow:hidden, which makes it a
     scroll container, and view() resolves against the nearest ancestor scroll
     container. Put the animation on the img inside it and the timeline is
     inactive, so the effect never applies and the plate sits there static with
     no error anywhere. The wrapper's own nearest scroll container is the page,
     because .cinema uses overflow:clip, which is NOT a scroll container.
     Anything scroll-driven added inside a cinema band has the same trap. */
  .cinema-fit .cinema-media{
    animation:plateFade linear both;
    animation-timeline:view();
    animation-range:cover 0% cover 100%;
  }
  @keyframes plateFade{
    0%{opacity:0}
    25%{opacity:1}
    75%{opacity:1}
    100%{opacity:0}
  }

  /* ── statements and cards arrive rather than appear ─────────────────── */
  .beat-gold .statement{animation:rise linear both;animation-timeline:view();
                        animation-range:entry 8% cover 34%}
  .whocard,.price-card{animation:rise linear both;animation-timeline:view();
                       animation-range:entry 12% cover 42%}
  @keyframes rise{from{opacity:0;transform:translateY(48px)}to{opacity:1;transform:none}}

  /* ── the falsehoods dim until they are the one you're reading ───────── */
  .lie{animation:focusIn linear both;animation-timeline:view();
       animation-range:entry 6% cover 30%}
  @keyframes focusIn{from{opacity:0.25;transform:translateY(30px)}to{opacity:1;transform:none}}
}
}

/* ── responsive ─────────────────────────────────────────────────────────── */
@media (max-width:1000px){
  .told-grid,.price-card,.cinema-split,.diary{grid-template-columns:1fr}
  .dpanel{position:static}
  .cinema-split{gap:1.4rem}
  .told-stick{position:static}
  .caa{border-left:0;border-top:1px solid var(--hairline-data);padding-left:0;padding-top:1.4rem}
  .day + .day{border-left:0;padding-left:0}
  .cinema-right .cinema-in{margin-left:0}
}
@media (max-width:820px){
  .hide-md{display:none}
  .cinema-scrim,.cinema-right .cinema-scrim{
    background:linear-gradient(180deg,rgba(11,13,12,0.72) 0%,rgba(11,13,12,0.9) 55%,var(--bg) 100%)}
  /* ⛔ The rail and the turn both pin, and pinning on a short phone screen
     traps the reader. Below this width they revert to plain stacked reading. */
  @supports (animation-timeline:view()){
    .rail-track,.turn-track{height:auto;view-timeline-name:none}
    .rail-stage,.turn-stage,.cinema-media{position:static;height:auto;margin-bottom:0}
    /* No pin down here, so no leftover stage to mirror. Back to plain rhythm,
       or the section carries half a screen of padding for no reason. */
    .days{padding-bottom:var(--band-y)}
    .days-close{margin-top:clamp(2rem,6vh,3.5rem)}
    .rail-row{display:grid;grid-template-columns:1fr;animation:none;transform:none}
    .cinema-media{position:absolute;inset:0;height:100%}
    .turn-a,.turn-b{animation:none;opacity:1;transform:none;filter:none}
    /* On a phone the pair stacks and reads in order: photograph, words,
       diagram. No cross-fade, nothing hidden behind an effect. */
    .turn-media{position:static;height:auto}
    .turn-plate{position:static;opacity:1;padding:1.5rem 0 0;
                justify-content:flex-start;animation:none}
    .turn-diagram{width:100%;max-height:none;animation:none;opacity:1;transform:none}
    .turn-scrim{display:none}
    .turn-cap{display:block;grid-area:auto;margin:0.8rem 0 2rem}
    .cinema-in{padding-block:clamp(5rem,14vh,8rem)}
  }
}
@media (max-width:640px){
  .hero{min-height:92svh}
  .hero-foot{position:static;margin-top:2.5rem;flex-direction:column;align-items:flex-start}
  .scroll-cue{display:none}
  .legal{text-align:left}
  .btn-lg{width:100%}
}

/* ── the booking dialog ───────────────────────────────────────────────────
   ⛔ Restrained on purpose. This is the moment of belief, and a checkout that
   tries to be clever reads as a phishing page. Same tokens as everything
   else, so it is obviously still us. */
.bdlg{border:1px solid var(--hairline-tool);border-radius:var(--radius-lg);
      background:var(--surface);color:var(--text);padding:0;
      width:min(92vw,30rem);max-height:88vh;overflow:auto}
.bdlg::backdrop{background:rgba(4,6,5,0.72);backdrop-filter:blur(3px)}
.bdlg > *{padding-inline:clamp(1.4rem,4vw,2.2rem)}
.bdlg h3{margin:clamp(1.6rem,4vh,2.2rem) 0 0.4rem;font-family:var(--font-display);
         font-weight:800;font-size:clamp(1.3rem,2.4vw,1.7rem);letter-spacing:-0.015em}
.bdlg-sub{margin:0 0 1.4rem;color:var(--text-muted);font-size:0.95rem}
.bdlg-x{padding:0;position:sticky;top:0;display:flex;justify-content:flex-end}
.bdlg-x button{background:none;border:0;color:var(--text-muted);font-size:1.6rem;
               line-height:1;cursor:pointer;padding:0.6rem 0.9rem}
.bdlg-x button:hover{color:var(--text)}
.bdlg-form{display:flex;flex-direction:column;gap:0.9rem;
           padding-bottom:clamp(1.6rem,4vh,2.2rem)}
/* ⛔ BLOCK, NOT A FLEX COLUMN, and the difference is visible. As a flex column
   the label's bare text and the "optional" span became two separate flex
   items, so every optional field read as two stacked lines:

       Company
       optional
       [input]

   which looks like a field labelled "optional" sitting under a heading. Block
   layout lets the text and the tag sit on one line as written. This was live
   on the booking dialog, not just the new one. */
.bdlg-form label{display:block;font-size:0.82rem;color:var(--text-muted)}
.bdlg-form label > input,
.bdlg-form label > textarea{margin-top:0.35rem;width:100%}
.bdlg-form .opt{color:var(--text-faint,var(--text-muted));opacity:0.7}
.bdlg-form input,
.bdlg-form textarea{padding:0.7rem 0.85rem;border-radius:9px;
                 border:1px solid var(--divider);background:var(--bg);
                 color:var(--text);font-size:1rem;font-family:inherit}
.bdlg-form input:focus,
.bdlg-form textarea:focus{outline:none;border-color:var(--accent-deep)}
/* ⚠️ A textarea defaults to `vertical-align:baseline` and an inline display,
   which leaves a stray gap under it inside a flex column, and it inherits a
   monospace face in several browsers unless told otherwise. Both are the sort
   of small wrongness that reads as an unfinished form. */
.bdlg-form textarea{display:block;resize:vertical;min-height:6.5rem;
                    line-height:1.5}
.bdlg-form ::placeholder{color:var(--text-faint);opacity:1}

/* ⚠️ CHROME PAINTS ITS OWN BACKGROUND ON AUTOFILLED FIELDS and will not let a
   background-color override it — which on a dark form means name and email
   come back pale blue while every field below them stays black. It looks like
   two of the inputs are broken.
   The inset shadow is the standard way through: it is drawn over the browser's
   fill, and -webkit-text-fill-color is the only thing that moves autofilled
   text colour. The long transition delay is belt and braces for the moment
   between paint and our style landing. */
.bdlg-form input:-webkit-autofill,
.bdlg-form input:-webkit-autofill:hover,
.bdlg-form input:-webkit-autofill:focus,
.bdlg-form textarea:-webkit-autofill{
  -webkit-box-shadow:inset 0 0 0 1000px var(--bg);
  box-shadow:inset 0 0 0 1000px var(--bg);
  -webkit-text-fill-color:var(--text);
  caret-color:var(--text);
  transition:background-color 100000s ease-in-out 0s}
.bdlg-form .btn{margin-top:0.5rem;justify-content:center;width:100%}
.bdlg-err{margin:0;color:#e08d8a;font-size:0.9rem}
.bdlg-note{margin:0.2rem 0 0;color:var(--text-muted);font-size:0.82rem;line-height:1.55}
/* The honeypot. Off-screen rather than display:none, because some bots skip
   anything that is not rendered. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}

/* ── the claim card, on /booked ───────────────────────────────────────────
   ⭐ GOLD BORDER BECAUSE IT IS A TOOL. Rule 6: gold-bordered means something
   the visitor operates, white-bordered means something they read. This is the
   one thing on the page they DO, and it should be obvious at a glance which
   part of a confirmation page wants their attention. */
.claim{border:1px solid var(--hairline-tool);border-radius:var(--radius-lg);
       background:var(--surface);padding:clamp(1.4rem,3.5vw,2rem);
       margin:0 0 2rem;max-width:34rem}
.claim h3{margin:0 0 0.45rem}
.claim-sub{margin:0 0 1.3rem;color:var(--text-muted);font-size:0.95rem;line-height:1.55}
.claim-form{gap:0.9rem;padding:0}
/* .bdlg-form sets a horizontal padding for the dialog it lives in. Inside a
   card that already has its own, that would inset the fields twice. */
.claim .bdlg-form{padding-inline:0;padding-bottom:0}
.claim-done{display:flex;flex-direction:column;gap:0.7rem;align-items:flex-start}
.claim-ok{margin:0;font-family:var(--font-display);font-weight:800;
          font-size:1.1rem;color:var(--accent)}
.claim-done .btn{margin-top:0.4rem}

/* ⚠️ Referenced by booked.html since it was written and never actually
   defined, so the "Back to the course" button has been rendering as bare text
   on a transparent border this whole time. */
.btn-ghost{border-color:var(--divider);color:var(--text);background:transparent}
.btn-ghost:hover{border-color:var(--hairline-tool);color:var(--accent)}
