/* TERNE. NIGHT WATER. The seven-beat sea passage B0 FIRST LIGHT -> B6 MOORING.
   One dark theme, radius --r, warm ink on cool near-black ground, one amber
   accent. Panels are semi-opaque or pre-blurred (F8): NEVER backdrop-filter
   over moving media on phone. Per-section scroll contract with min-heights
   (F5), no scroll hijacking anywhere.

   CRAFT CONTRACT (2026-07-24, from production sites probed the same day):
   - every margin, padding and gap resolves through the --sp-* 4px grid;
   - every font-size and line-height comes from the --t-* / --lh-* scale, and
     every leading is a multiple of 4;
   - tracking rides the ramp: display -0.06em, mid -0.04em, body -0.02em,
     caps +0.08em (the .wordmark is the one documented exception, a logotype);
   - display type is never bold; size carries hierarchy;
   - ONE transition duration and ONE curve, granted once at the bottom of this
     file and only under prefers-reduced-motion: no-preference;
   - radius stays in the 0 to 6px band, capsules excepted as a deliberate
     overlay-chip language;
   - shadows are 1px hairline rings, never drop shadows. */

/* ===================== film stage: fixed, behind everything ================ */
.film-stage{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;background:var(--ground)}
.film-stage #poster,.film-stage #film{position:absolute;inset:0;width:100%;height:100%;display:block}
.film-stage #poster{object-fit:cover;transition-property:opacity}
.film-stage #film{opacity:0;transition-property:opacity}
.film-ready #film{opacity:1}
.film-ready #poster{opacity:0}
.film-off #poster{opacity:1}
/* readability scrim: a top band behind the fixed header + hero headline and a
   bottom band behind the HUD, the hero spec triplet and the CTA. Grey secondary
   ink (#9A958A) and amber only clear AA over near-black, and these run over the
   bright dawn frames; the scrim gives them a dark backing without a panel box.
   Neutral (no hue), gentle fades, so the film still reads alive (G16, G19). */
.film-stage::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(to bottom, rgba(8,10,12,.9) 0, rgba(8,10,12,.9) 46px, rgba(8,10,12,0) 150px),
    linear-gradient(to top, rgba(8,10,12,.82) 0, rgba(8,10,12,.82) 62px, rgba(8,10,12,0) 320px)}
main{position:relative;z-index:1}

/* ===================== header: one line, <=72px (G17) ====================== */
/* Reveal-on-scroll: shown at the top and on scroll-up, slid away on scroll-down
   (js/config.js toggles .hd-away and display).
   The bar itself is FULLY OPAQUE. It used to be a ground-to-transparent wash, and
   on every scroll-up the page content underneath stayed legible straight through
   it: measured at 26.6% of the header band's pixels over the yard and 25.6% over
   the drawings. Text over text is the defect a client screenshots back to you.
   The seam that an opaque bar would otherwise cut across the film is carried off
   by ::after, a short fade BELOW the bar, outside its own geometry. */
.site-header{position:fixed;top:0;left:0;right:0;z-index:40;height:var(--hd);
  display:flex;align-items:center;transition-property:transform;
  background:var(--ground)}
.site-header::after{content:"";position:absolute;top:100%;left:0;right:0;height:var(--sp-8);
  pointer-events:none;
  background:linear-gradient(to bottom, var(--ground) 0%, rgba(12,14,16,0) 100%)}
.site-header.hd-away{transform:translateY(-100%)}
.hd-inner{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter);
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
/* THE ONE TRACKING EXCEPTION. A letterspaced logotype is not a caps label; this
   is the marque, and it is set wide on purpose. Everything else obeys the ramp. */
/* The hit area is 44px tall, the glyphs are still 24px. It measured 84.5 x 24
   at 390, the one interactive control left under the bar once the view chips
   were fixed, and it is the control a reader taps to get back to the top. */
.wordmark{font-family:var(--font-display);font-size:var(--t-d5);line-height:var(--t-d5);
  letter-spacing:.22em;text-transform:uppercase;color:var(--ink);text-decoration:none;
  display:inline-flex;align-items:center;min-height:44px}
.hd-nav{display:flex;gap:var(--sp-6)}
.hd-nav a{color:var(--ink-2);text-decoration:none;
  font-size:var(--t-sm);line-height:var(--lh-sm);transition-property:color}
.hd-nav a:hover{color:var(--ink)}

/* phone-only header cluster: a persistent Reserve pill and a compact menu. Shown
   only where .hd-nav is hidden (<=900), so exactly one nav is reachable at every
   width. Buttons meet the 44px touch target. */
.hd-phone{display:none;align-items:center;gap:var(--sp-2);position:relative}
.hd-reserve-pill{min-height:44px;padding:0 var(--sp-4);font-size:var(--t-sm)}
.hd-menu-btn{min-height:44px;min-width:44px;padding:0 var(--sp-4);
  background:transparent;color:var(--ink);border:1px solid var(--hairline);
  border-radius:var(--r);font:inherit;font-size:var(--t-sm);line-height:var(--lh-sm);
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  transition-property:border-color}
.hd-menu-btn:hover{border-color:var(--ink-2)}
/* the menu used to carry a 0 12px 30px drop shadow. Hairline ring instead: the
   measured premium band has essentially no drop shadows in it at all. */
.hd-menu{position:absolute;top:calc(100% + var(--sp-2));right:0;z-index:50;min-width:12rem;
  display:flex;flex-direction:column;
  background:var(--panel);border:1px solid var(--hairline);border-radius:var(--r);
  padding:var(--sp-1);box-shadow:0 0 0 1px rgba(0,0,0,.55)}
.hd-menu[hidden]{display:none}
.hd-menu a{color:var(--ink);text-decoration:none;
  font-size:var(--t-body);line-height:var(--lh-body);
  padding:var(--sp-3);border-radius:var(--r);min-height:44px;display:flex;align-items:center;
  transition-property:background-color,color}
.hd-menu a:hover{background:rgba(232,161,61,.08);color:var(--ink)}
/* backdrop scrim behind the open phone menu, plus a body scroll lock. The scrim
   dims the page and catches an outside tap; the lock stops the page scrolling
   under the open menu. */
/* z-index 35 sits ABOVE the page (main is z-index 1) but BELOW the header
   (z-index 40). The menu is a child of the header, so it shares the header's
   stacking context and renders above this scrim; at z-index 45 the scrim used to
   paint over the menu (the header's whole context is below 45), so a trusted tap
   on a menu link hit the scrim instead of the link and the menu appeared dead.
   Outside taps on the page still land on the scrim and close the menu. */
.hd-scrim{position:fixed;inset:0;z-index:35;background:rgba(6,8,10,.55);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.hd-scrim[hidden]{display:none}
body.menu-open{overflow:hidden}

/* ===================== buttons: one shape, one CTA style =================== */
.btn{display:inline-flex;align-items:center;justify-content:center;
  min-height:48px;padding:0 var(--sp-6);border-radius:var(--r);
  font:inherit;font-weight:500;font-size:var(--t-body);line-height:var(--t-body);
  letter-spacing:var(--track-body);
  text-decoration:none;white-space:nowrap;cursor:pointer;border:1px solid transparent;
  transition-property:background-color,color,border-color}
.btn-primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.btn-primary:hover{background:#f0ad4d}
.btn-quiet{background:transparent;color:var(--ink);border-color:var(--hairline)}
.btn-quiet:hover{border-color:var(--ink-2)}

/* ===================== Reserve dialog (honest completion) ================== */
.reserve-dialog{border:1px solid var(--hairline);border-radius:var(--r);
  background:var(--panel);color:var(--ink);padding:0;max-width:30rem;
  width:calc(100% - var(--sp-8))}
.reserve-dialog::backdrop{background:rgba(6,8,10,.72)}
.reserve-inner{padding:var(--sp-8)}
.reserve-title{font-family:var(--font-display);font-size:var(--t-d4);
  line-height:var(--t-d4);letter-spacing:var(--track-mid);margin:0}
.reserve-summary{margin-top:var(--sp-4);color:var(--ink);
  font-size:var(--t-body);line-height:var(--lh-body);
  font-variant-numeric:tabular-nums lining-nums}
.reserve-note{margin-top:var(--sp-4);color:var(--ink-2);
  font-size:var(--t-sm);line-height:var(--lh-sm)}
.reserve-contact{margin-top:var(--sp-4);color:var(--ink-2);
  font-size:var(--t-sm);line-height:var(--lh-sm)}
.reserve-actions{margin-top:var(--sp-7);display:flex;justify-content:flex-end}

/* ===================== shared beat scaffolding ============================= */
.beat{position:relative}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
.kicker{font-family:var(--font-sans);font-size:var(--t-label);line-height:var(--lh-label);
  font-weight:500;letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--accent);margin:0 0 var(--sp-4)}
/* discrete display steps, not a clamp: see the note on the type scale in
   tokens.css. Tracking follows the size across the breakpoints below. */
.beat h2{font-size:var(--t-d2);line-height:var(--lh-d2);
  letter-spacing:var(--track-display);max-width:20ch}
.beat .body{margin-top:var(--sp-5);color:var(--ink-2);max-width:52ch;
  font-size:var(--t-body-lg);line-height:var(--lh-body-lg)}

/* copy PANEL over film (F8): solid #14171A at 86% on every device; desktop
   gets a pre-blur enhancement only where it cannot fight moving phone media. */
.panel{background:rgba(20,23,26,.86);border:1px solid var(--hairline);
  border-radius:var(--r);padding:var(--sp-8)}
@supports (backdrop-filter:blur(8px)){
  @media (min-width:781px){
    /* raised from .62 so the grey body copy clears AA where the panel rides over
       the brightest dawn frames; the blur keeps it reading as glass, not a slab. */
    .panel{background:rgba(20,23,26,.88);backdrop-filter:blur(12px) saturate(1.08)}
  }
}

/* ===================== B0 FIRST LIGHT (hero) ============================== */
/* film-runway wraps B0..B3: the scrub progresses across this whole span. */
#film-runway{position:relative}

.b-firstlight{min-height:100dvh;display:flex;align-items:center;position:relative}
/* hero copy scrim: the headline and sub are light ink and the spec labels are
   grey; frame 0 has bright water patches on the left where the copy sits. A soft
   left-weighted wash gives every hero line a dark enough backing for AA while the
   right ~40% keeps the live film clear (G16). Hero is scroll 0 only, so this
   never touches any other beat. */
.b-firstlight::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(105deg, rgba(8,10,12,.76) 0%, rgba(8,10,12,.6) 58%, rgba(8,10,12,0) 85%)}
.hero{padding-top:var(--hd)}
.hero h1{font-size:var(--t-d1);line-height:var(--lh-d1);
  letter-spacing:var(--track-display);max-width:14ch}
.hero .sub{margin-top:var(--sp-6);color:var(--ink);max-width:34ch;
  font-size:var(--t-lead);line-height:var(--lh-lead);
  text-shadow:0 1px 20px rgba(0,0,0,.55)}
.hero .cta-row{margin-top:var(--sp-8);display:flex;gap:var(--sp-3);flex-wrap:wrap}
.spec-triplet{margin-top:var(--sp-10);display:flex;gap:var(--sp-6);flex-wrap:wrap;
  color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}
.spec-triplet b{color:var(--ink);font-weight:500}

/* ===================== B1 THE RISE (signature) + HUD ====================== */
/* FILM PACING: 230vh and 200vh are DELIBERATE, and the shortening the evening
   audit asked for was tried and reverted on the measurement (2026-07-24 night,
   d6-tap-runway.mjs). Cut to 170/150vh the runway does shrink, 3,440px of scrub
   to 2,560px, but the share of it with no copy on screen goes UP, 36.1 percent
   to 44.3 at 1280 and 37.7 to 45.9 at 390. The dead zone is not the beat length:
   it is the sticky pin release at each beat boundary, a fixed ONE VIEWPORT of
   scrolling (800px at 1280x800) during which the panel has faded and the next
   beat has not started. Shortening the beats leaves that 800px untouched and
   takes the cut out of the copy instead: readable scroll falls 2,198px to
   1,426px, a 35 percent loss, to save 108px of empty scroll. The audit's premise
   has also moved: it argued from 57 percent copy-free and the panel-vis
   breathing has already brought that to 36. The real lever is the pin release,
   and changing that means overriding the copy-free breathing decision, which is
   Hugh's call and not a night-run one. */
.b-rise{min-height:230vh}
/* the hull sits centre-right through the rise, so the copy anchors lower-LEFT
   and clears it. Smaller than a full-height slab. */
.b-rise .pin{position:sticky;top:0;min-height:100dvh;display:flex;
  align-items:flex-end;padding-bottom:var(--sp-16)}
.b-rise .panel{max-width:26rem;margin-right:auto}
/* keep the column full width inside the flex pins so the panel anchors to a real
   column edge (auto margin) rather than the flex item shrinking and re-centring.
   .b-firstlight is a flex container too, so .wrap.hero belongs in this list: as a
   shrink-to-fit flex item it re-centred on its own content and put the hero copy
   287px off the site grid at 1280, 1440 and 1920 (measured). */
.b-rise .pin .wrap,.b-thread .pin .wrap,.b-night .wrap,.b-firstlight .wrap{width:100%}

/* copy-free breathing: the beat panels ride the moving film only through the
   middle of each beat's scroll span. film.js sets --panel-vis (0..1) from the
   beat's own scroll progress; the panel fades and lifts at the beat ends so the
   film plays clean between beats. Transitioned for smoothness, disabled under
   reduced motion (where film.js never drives it). */
.b-rise .panel,.b-thread .panel{
  opacity:var(--panel-vis,1);
  transform:translateY(calc((1 - var(--panel-vis,1)) * 14px));
  transition-property:opacity,transform;will-change:opacity,transform}

/* HUD: corner-placed, amber, tabular figures (E-HUD). aria-hidden; the .vh
   #hud-alt carries the live text alternative. */
.hud{position:fixed;right:var(--gutter);bottom:var(--sp-8);z-index:20;
  display:flex;gap:var(--sp-6);opacity:0;transition-property:opacity;pointer-events:none}
.hud.hud-live{opacity:1}
.hud .cell{text-align:right}
.hud .val{font-family:var(--font-sans);font-weight:500;color:var(--accent);
  font-size:var(--t-d4);line-height:var(--t-d4);letter-spacing:var(--track-mid);
  font-feature-settings:"tnum" 1,"lnum" 1;font-variant-numeric:tabular-nums lining-nums}
.hud .lbl{margin-top:var(--sp-1);color:var(--ink-2);
  font-size:var(--t-micro);line-height:var(--lh-micro);
  letter-spacing:var(--track-caps);text-transform:uppercase}

/* ===================== B2 THE THREAD ===================================== */
.b-thread{min-height:200vh}
/* copy on the RIGHT this beat, so the eye alternates side to side down the film
   and the hull stays visible on the left. */
.b-thread .pin{position:sticky;top:0;min-height:100dvh;display:flex;align-items:center}
.b-thread .panel{max-width:32rem;margin-left:auto}
.panel-figs{margin-top:var(--sp-6);display:flex;gap:var(--sp-6);flex-wrap:wrap;
  color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}
.panel-figs b{color:var(--ink);font-weight:500}

/* ===================== film bands (lazy Kling loops) ===================== */
.filmband{position:relative;height:72vh;min-height:22rem;overflow:hidden;
  background:var(--ground);display:flex;align-items:flex-end}
.filmband video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.filmband .cap{position:relative;z-index:1;color:var(--ink-2);
  font-size:var(--t-xs);line-height:var(--lh-xs);padding:var(--sp-4) var(--gutter);
  background:linear-gradient(to top,rgba(12,14,16,.7),transparent)}

/* ===================== B3 NIGHT MODE (full-bleed video + panel) =========== */
/* the quietest copy of the page: anchored lower-LEFT and smaller so most of the
   night water reads clean. */
.b-night{position:relative;min-height:100dvh;display:flex;align-items:flex-end;
  background:var(--ground);overflow:hidden;padding-bottom:var(--sp-20)}
.b-night .night-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:.85}
.b-night .wrap{position:relative;z-index:1}
.b-night .panel{max-width:28rem;margin-right:auto}
/* night-grade legibility lift: the darkest night frames sit under this panel,
   so its copy gets a firmer backing and a soft text-shadow so the grey body and
   amber kicker clear AA on the blackest frames (F contrast). */
.b-night .panel{background:rgba(16,19,22,.92)}
.b-night .panel .kicker,.b-night .panel h2,.b-night .panel .body{
  text-shadow:0 1px 10px rgba(0,0,0,.6)}
@supports (backdrop-filter:blur(8px)){
  @media (min-width:781px){
    .b-night .panel{background:rgba(16,19,22,.9);backdrop-filter:blur(12px) saturate(1.05)}
  }
}

/* ===================== HOW IT FLIES (the explanation) ==================== */
/* The one band with no boat in it: the page stops showing and starts teaching,
   so it is set in type alone. Same register language as the drawings that follow
   (ground colour, hairline rules, the technical mono on figures only), without a
   drawing. Nothing here moves, so nothing here needs the motion gate.
   The bottom padding is shorter than the top on purpose: it lands against the
   drawings' own 96px, and 96 + 96 opened a 192px void between two bands of the
   same ground colour. 80 + 96 is the gap the night beat already hands to the
   drawings, so the page rhythm is unchanged by this section arriving. */
.b-flies{background:var(--ground);padding:var(--sp-24) 0 var(--sp-20)}
.flies-inner{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
/* the thesis paragraph carries full ink, not the secondary grey: it is the one
   sentence the section exists to land. */
.flies-lead{margin-top:var(--sp-6);color:var(--ink);max-width:52ch;
  font-size:var(--t-lead);line-height:var(--lh-lead)}

/* three stages, three columns, a rule over each. The figure is the only thing
   in the technical mono, matching the hero spec triplet. */
.flies-steps{margin:var(--sp-16) 0 0;padding:0;list-style:none;
  display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-10)}
.flies-steps li{border-top:1px solid var(--hairline);padding-top:var(--sp-5);min-width:0}
.flies-n{color:var(--accent);font-size:var(--t-d5);line-height:var(--lh-d5);
  letter-spacing:var(--track-mid);
  font-feature-settings:"tnum" 1,"lnum" 1;font-variant-numeric:tabular-nums lining-nums}
/* Sans, not the display serif: these are spec statements, the same voice as the
   build sheet, and the serif stays with the section headings. Balanced, because
   each title is two sentences and the second one kept landing as a two-word last
   line ("water." on its own); balance is a layout choice, not motion, so it sits
   outside the reduced-motion gate legitimately. */
.flies-steps h3{margin-top:var(--sp-3);font-family:var(--font-sans);font-weight:500;
  color:var(--ink);font-size:var(--t-body-lg);line-height:var(--lh-body-lg);
  max-width:40ch;text-wrap:balance}
.flies-body{margin-top:var(--sp-3);color:var(--ink-2);
  font-size:var(--t-body);line-height:var(--lh-body);max-width:42ch}

/* the close: the caveat that is also the most interesting fact, and the two ride
   heights it lands on. The figures agree with the foil comparison in the yard. */
.flies-close{margin-top:var(--sp-16);border-top:1px solid var(--hairline);
  padding-top:var(--sp-8);display:grid;grid-template-columns:1.5fr 1fr;
  gap:var(--sp-12);align-items:start}
.flies-caveat{color:var(--ink-2);max-width:56ch;
  font-size:var(--t-body-lg);line-height:var(--lh-body-lg)}
.flies-pull-row{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap}
.flies-pull-row + .flies-pull-row{margin-top:var(--sp-3)}
.flies-pull-row b{color:var(--ink);font-weight:500;
  font-size:var(--t-d5);line-height:var(--lh-d5);letter-spacing:var(--track-mid);
  font-feature-settings:"tnum" 1,"lnum" 1;font-variant-numeric:tabular-nums lining-nums}
.flies-pull-row span{color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}
.flies-pull-note{margin-top:var(--sp-4);color:var(--ink-2);
  font-size:var(--t-xs);line-height:var(--lh-xs);max-width:32ch;text-wrap:balance}

/* ===================== THE DRAWINGS (naval design register) =============== */
/* Replaces the retired fit-out section. Vellum sheets, naval draughting voice.
   Horizontally scrollable frames at narrow widths. */
.b-drawings{background:var(--ground);padding:var(--sp-24) 0}
.drawings-head{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
.drawings-intro{margin-top:var(--sp-4);color:var(--ink-2);max-width:56ch}
.drawings-rail{max-width:var(--maxw);margin:var(--sp-12) auto 0;padding:0 var(--gutter);
  display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-6)}
.sheet{margin:0}
/* the vellum frame: a warm mat and thin rule around the drawing, so the sheet
   reads as a physical drawing pinned to a board rather than a UI panel.
   FIXED HEIGHT, contained image. The four sheets are drawn at four different
   aspect ratios (1412x571, 996x686, 1400x360, 1414x588), so a height:auto vellum
   made them 248 / 398 / 170 / 254 tall: the captions landed on four different
   lines and the grid rows left tall voids of black under the shorter sheets. A
   fixed mat with object-fit:contain is what a real drawing board does anyway, and
   the surplus mat reads as matting rather than as a gap.
   The drop shadow that used to sit under it is now a hairline ring. */
.vellum{display:flex;align-items:center;justify-content:center;
  width:100%;height:320px;padding:var(--sp-4);
  background:#F0EBE0;border:1px solid var(--hairline);border-radius:var(--r);
  box-shadow:inset 0 0 0 1px rgba(31,36,41,.14);
  overflow:hidden;position:relative;cursor:zoom-in;font:inherit;color:inherit;
  transition-property:box-shadow}
.vellum img{display:block;width:100%;height:100%;object-fit:contain}
/* the enlarge affordance: the sheets are drawn at 1400px and shown at ~530, so
   the station numbers are unreadable until they are opened. */
.vellum::after{content:"Enlarge";position:absolute;right:var(--sp-2);bottom:var(--sp-2);
  font-size:var(--t-micro);line-height:var(--lh-micro);
  letter-spacing:var(--track-caps);text-transform:uppercase;
  color:#F0EBE0;background:rgba(20,23,26,.86);border-radius:999px;
  padding:var(--sp-1) var(--sp-3);opacity:0;transition-property:opacity}
.vellum:hover::after,.vellum:focus-visible::after{opacity:1}
.vellum:hover{box-shadow:inset 0 0 0 1px rgba(31,36,41,.30)}
.sheet figcaption{margin-top:var(--sp-3);display:flex;flex-direction:column;gap:var(--sp-1)}
.sheet figcaption b{color:var(--ink);font-weight:500;
  font-size:var(--t-body);line-height:var(--lh-body)}
.sheet figcaption span{color:var(--ink-2);font-size:var(--t-xs);line-height:var(--lh-xs)}

/* ---- drawing zoom dialog ---- */
.zoom-dialog{border:1px solid var(--hairline);border-radius:var(--r);
  background:var(--panel);color:var(--ink);padding:0;
  width:min(96vw,1100px);max-width:none;max-height:92vh}
.zoom-dialog::backdrop{background:rgba(6,8,10,.82)}
.zoom-inner{padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-4)}
.zoom-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-4)}
.zoom-title{color:var(--ink);font-size:var(--t-body);line-height:var(--lh-body)}
.zoom-close{font:inherit;font-size:var(--t-xs);line-height:var(--lh-micro);
  letter-spacing:var(--track-caps);text-transform:uppercase;
  color:var(--ink-2);background:transparent;
  border:1px solid var(--hairline);border-radius:var(--r);
  min-height:44px;padding:0 var(--sp-4);cursor:pointer;
  display:inline-flex;align-items:center;transition-property:color,border-color}
.zoom-close:hover{color:var(--ink);border-color:var(--ink-2)}
.zoom-plate{background:#F0EBE0;border-radius:var(--r);padding:var(--sp-6);
  box-shadow:inset 0 0 0 1px rgba(31,36,41,.14)}
.zoom-plate img{display:block;width:100%;height:auto;max-height:72vh;object-fit:contain}

/* ===================== B5 THE YARD (configurator centrepiece) ============= */
/* Near-full-viewport, its own scroll stop. The boat large and centred on the
   turntable stage, a quiet option rail at one side, the build sheet beneath it. */
.b-yard{background:var(--ground);min-height:100dvh;display:flex;align-items:center}
.yard-inner{max-width:var(--maxw);margin:0 auto;padding:var(--sp-20) var(--gutter);width:100%}
.yard-head{max-width:44rem}
.yard-intro{margin-top:var(--sp-4);color:var(--ink-2);max-width:52ch}
/* stage large on the left, the option rail + build sheet stacked on the right */
.yard-layout{margin-top:var(--sp-10);display:grid;grid-template-columns:1.35fr .65fr;
  gap:var(--sp-10);align-items:start}
.cfg-stage-zone{position:sticky;top:calc(var(--hd) + var(--sp-4))}
.yard-side{display:flex;flex-direction:column;gap:var(--sp-8);min-width:0}

/* ---- the turntable stage ---- */
.cfg-stage{position:relative;aspect-ratio:3/2;min-height:18rem;
  border-radius:var(--r);overflow:hidden;border:1px solid var(--hairline);
  background:var(--panel)}
/* the drag surface: fills the stage, focusable, the accessible slider */
.cfg-turntable{position:absolute;inset:0;cursor:grab;touch-action:pan-y;
  outline-offset:-2px}
.cfg-turntable:active{cursor:grabbing}
.cfg-turntable:focus-visible{outline:2px solid var(--focus);outline-offset:-3px}
.cfg-turntable[hidden]{display:none}
/* stacked frame layers: crisp still on top at rest, low-res proxy underneath
   and shown during motion. An absent asset shows the panel colour, no broken
   icon (the yard-v4 assets render overnight). */
.cfg-frame{position:absolute;inset:0;background-size:cover;background-position:center;
  background-repeat:no-repeat;background-color:var(--panel)}
.cfg-crisp{opacity:1;transition-property:opacity;will-change:opacity}
.cfg-hint{position:absolute;left:var(--sp-3);bottom:var(--sp-3);z-index:2;
  color:var(--ink-2);font-size:var(--t-micro);line-height:var(--lh-micro);
  letter-spacing:var(--track-caps);text-transform:uppercase;
  background:rgba(12,14,16,.55);border-radius:999px;padding:var(--sp-1) var(--sp-3);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);pointer-events:none;
  transition-property:opacity}
/* The hint retires when the READER has actually driven the stage, never because
   the idle drift happens to be running. Keyed to .cfg-inmotion it sat at opacity
   0 exactly when a visitor arrived, which is the one moment it exists for. */
.cfg-interacted .cfg-hint{opacity:0}
/* detail view: a single composed still, named by aria-label */
.cfg-detailview{z-index:1}
.cfg-detailview[hidden]{display:none}

/* segmented view controls: Turntable + the three detail views. Turntable is the
   obvious way back. Keyboard reachable, amber active + focus. */
.cfg-controls{position:absolute;top:var(--sp-3);left:var(--sp-3);right:var(--sp-3);z-index:3;
  display:flex;flex-wrap:wrap;gap:var(--sp-2)}
/* Every view control is the same 44px-tall capsule, at every width. They were
   25.9px tall on phone and Turntable was a 329.6px full-width banner sat above
   three small chips, which read as a section header rather than as the peer it
   is. Capsules are kept deliberately: they are the page's overlay-chip language
   (see .cfg-hint), not the 10-16px rounded-card template look. */
.cfg-view-btn{font-family:var(--font-sans);font-size:var(--t-xs);
  line-height:var(--lh-micro);letter-spacing:var(--track-body);
  color:var(--ink-2);background:rgba(12,14,16,.6);border:1px solid var(--hairline);
  border-radius:999px;padding:0 var(--sp-4);min-height:44px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  transition-property:color,border-color,background-color}
.cfg-view-btn:hover{color:var(--ink);border-color:var(--ink-2)}
.cfg-view-btn[aria-pressed="true"]{color:var(--on-accent);background:var(--accent);
  border-color:var(--accent);font-weight:500}
.cfg-view-btn:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.cfg-stage-cap{margin:var(--sp-4) 0 0;color:var(--ink-2);
  font-size:var(--t-xs);line-height:var(--lh-xs)}

/* ---- option rail ---- */
.cfg-groups{display:flex;flex-direction:column;gap:var(--sp-7)}
.cfg-group{border:0;margin:0;padding:0;min-inline-size:0}
.cfg-group legend{padding:0;color:var(--ink-2);
  font-size:var(--t-label);line-height:var(--lh-label);
  letter-spacing:var(--track-caps);text-transform:uppercase;margin-bottom:var(--sp-3)}
.opts{display:flex;flex-direction:column;gap:var(--sp-2)}
.opt{position:relative;display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-3);border:1px solid var(--hairline);border-radius:var(--r);
  cursor:pointer;transition-property:border-color,background-color}
.opt:hover{border-color:var(--ink-2)}
/* margin:0 kills the UA default 3px 5px, which was the only off-grid spacing
   left on the page once everything else moved onto the scale. */
.opt input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
/* FLAT MATERIAL CHIPS, not rendered macro crops. The crops sampled three of the
   four hull finishes within 4 RGB points of each other and rendered "Nordlys
   White" as mid grey (measured means: nordlys 46,43,42 / basalt 24,19,12 /
   dypvann 9,10,13 / ember 9,9,9), because a macro crop of a curved dark hull in
   a dim studio is mostly shadow whatever colour the paint is. The paint values
   below were already in this file as the fallback tones; they are now the chip
   itself, and they are the only honest way to tell four finishes apart at 36px. */
.opt .swatch{position:relative;width:36px;height:36px;border-radius:var(--r);
  overflow:hidden;border:1px solid var(--hairline);flex:0 0 auto;
  background-color:var(--panel);transition-property:border-color}
/* subtle gloss: one soft highlight raking across the chip, so it reads as a
   painted panel catching light rather than a flat swatch of colour. */
.opt .swatch::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(155deg,
    rgba(255,255,255,.30) 0%, rgba(255,255,255,.05) 38%,
    rgba(255,255,255,0) 55%, rgba(0,0,0,.16) 100%)}
/* true paint and timber values */
.opt .sw-nordlys{background-color:#E6E9EA}
.opt .sw-basalt{background-color:#3A3E42}
.opt .sw-dypvann{background-color:#16283C}
.opt .sw-ember{background-color:#8A4A1F}
.opt .sw-ash{background-color:#6E5A3C}
.opt .sw-cork{background-color:#8C6A46}
/* Both foil packages are the same carbon, so a colour difference would be a lie.
   What actually differs is the strut rake, so the chips carry the rake: 7 and 15
   degrees off vertical, the same two figures the comparison drawing is built on. */
.opt .sw-cruise,.opt .sw-sport{background-color:#2A2E33}
.opt .sw-cruise{background-image:linear-gradient(97deg,transparent calc(50% - 1px),
  #9A958A calc(50% - 1px),#9A958A calc(50% + 1px),transparent calc(50% + 1px))}
.opt .sw-sport{background-image:linear-gradient(105deg,transparent calc(50% - 1px),
  #E9E6DF calc(50% - 1px),#E9E6DF calc(50% + 1px),transparent calc(50% + 1px))}
.opt .name{color:var(--ink);font-weight:500}
.opt .meta{margin-left:auto;color:var(--ink-2);text-align:right;
  font-size:var(--t-sm);line-height:var(--lh-sm)}
/* SELECTION and FOCUS are deliberately different treatments, not two shades of
   the same amber. They were near-identical: selection was an amber border with an
   amber wash, focus an amber ring, so a keyboard reader could not tell which row
   was chosen and which was merely under the cursor.
   Selection now reads as a filled, permanent state: a solid amber bar on the
   leading edge, a light ink border and a lifted label.
   Focus stays the one designed ring: amber, offset, transient. The two stack
   legibly when a selected row is also focused. */
.opt:has(input:checked){border-color:var(--ink);background:rgba(233,230,223,.055)}
.opt:has(input:checked)::before{content:"";position:absolute;left:0;top:0;bottom:0;
  width:3px;background:var(--accent);border-radius:var(--r) 0 0 var(--r)}
.opt:has(input:checked) .name{font-weight:500}
.opt:has(input:checked) .swatch{border-color:var(--ink)}
.opt:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:3px}

/* ---- foil comparison graphic ---- */
.foil-compare{margin:var(--sp-4) 0 0;padding:var(--sp-4);border:1px solid var(--hairline);
  border-radius:var(--r);background:rgba(20,23,26,.5)}
.foil-compare svg{display:block;width:100%;height:auto}
.foil-compare text{font-family:var(--font-sans)}
.fc-name{fill:var(--ink);font-size:12px;font-weight:500;letter-spacing:.08em}
.fc-name-sport{fill:var(--accent)}
.fc-val{font-size:19px;font-weight:500;font-feature-settings:"tnum" 1,"lnum" 1;
  letter-spacing:-0.02em}
.fc-val-cruise{fill:var(--ink-2)}
.fc-val-sport{fill:var(--accent)}
.fc-unit{fill:var(--ink-2);font-size:9px;letter-spacing:.08em}
.fc-rake{fill:var(--ink-2);font-size:10px;font-feature-settings:"tnum" 1,"lnum" 1}
.fc-rake-sport{fill:var(--accent)}
.fc-water{fill:var(--ink-2);font-size:9px;letter-spacing:.08em;text-transform:uppercase}
.foil-compare figcaption{margin-top:var(--sp-3);color:var(--ink-2);
  font-size:var(--t-xs);line-height:var(--lh-xs)}

/* ---- build sheet ---- */
.build-sheet{border:1px solid var(--hairline);border-radius:var(--r);
  background:var(--panel);padding:var(--sp-6)}
.build-sheet-label{margin:0 0 var(--sp-4);color:var(--ink-2);
  font-size:var(--t-label);line-height:var(--lh-label);
  letter-spacing:var(--track-caps);text-transform:uppercase}
.build-spec{margin:0}
.build-spec .row{display:flex;justify-content:space-between;gap:var(--sp-4);
  padding:var(--sp-3) 0;border-top:1px solid var(--hairline)}
.build-spec .row:first-child{border-top:0;padding-top:0}
.build-spec dt{color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}
.build-spec dd{margin:0;color:var(--ink);font-weight:500;text-align:right}
/* itemised cost lines: base plus any upcharges, above the total. Live: the
   upcharge rows are toggled by config.js as options change. */
.build-costs{margin-top:var(--sp-5);border-top:1px solid var(--hairline);
  padding-top:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-2)}
.build-costs .cost{display:flex;justify-content:space-between;gap:var(--sp-4);
  color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm);
  font-variant-numeric:tabular-nums lining-nums}
.build-costs .cost[hidden]{display:none}
.build-costs .cost .amt{color:var(--ink)}
.cfg-readout-wrap{margin-top:var(--sp-5);border-top:1px solid var(--hairline);
  padding-top:var(--sp-5);display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--sp-4);flex-wrap:wrap}
.cfg-readout{color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}
.cfg-price{font-family:var(--font-display);color:var(--ink);
  font-size:var(--t-d4);line-height:var(--lh-d4);letter-spacing:var(--track-mid);
  font-variant-numeric:tabular-nums lining-nums}
.cfg-cta{margin-top:var(--sp-6)}
.cfg-cta .btn{width:100%}

/* ===================== B6 MOORING (the closing plate) ==================== */
/* The close used to be a stack of centred paragraphs on black, and the website
   audit named it as one of five cheap-looking elements. The problem was not the
   copy: it was that the last thing a reader sees sat OUTSIDE the page's own
   technical register, at exactly the moment that register is the asset. The
   drawings, the spec triplet and the build sheet all speak in ruled rows and
   tabular figures; the close spoke in centred marketing shape.
   It is now an end plate on the site grid. Two parts, each under its own rule:
   the COMMITMENT on the left, a DELIVERY TERMS ledger on the right set exactly
   like the build sheet in the yard. The disclosure and the colophon close it.
   There is no scarcity device here by decision, not by omission. */
.b-mooring{background:var(--ground);padding:var(--sp-24) 0 var(--sp-16)}
.mooring-inner{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
.mooring-plate{display:grid;grid-template-columns:1.15fr .85fr;gap:var(--sp-16);
  align-items:start}
/* one rule over each column, the drawing-sheet device the explanation section
   already uses over each of its three stages (.flies-steps li). Same padding on
   both so the two rules and the two first lines sit on the same optical band. */
.mooring-commit,.mooring-terms{border-top:1px solid var(--hairline);
  padding-top:var(--sp-6);min-width:0}
.b-mooring h2{max-width:20ch}
.deposit{margin-top:var(--sp-8);font-family:var(--font-display);color:var(--ink);
  font-size:var(--t-d5);line-height:var(--lh-d5);letter-spacing:var(--track-mid);
  font-variant-numeric:tabular-nums lining-nums}
.mooring-cta{margin-top:var(--sp-6)}

/* ---- the delivery terms ledger ---- */
/* Deliberately the build sheet's row shape (.build-spec) without the panel box:
   caps micro-label, a hairline between every line, label left in the secondary
   ink, value right in full ink with the FIGURE in the technical mono and any
   qualifier beside it in the sans. Terms, not urgency. */
.terms-label{margin:0 0 var(--sp-4);color:var(--ink-2);
  font-size:var(--t-label);line-height:var(--lh-label);
  letter-spacing:var(--track-caps);text-transform:uppercase}
.terms-spec{margin:0}
.terms-spec .row{display:flex;justify-content:space-between;align-items:baseline;
  gap:var(--sp-4);padding:var(--sp-3) 0;border-top:1px solid var(--hairline)}
.terms-spec .row:first-child{border-top:0;padding-top:0}
.terms-spec dt{color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}
.terms-spec dd{margin:0;color:var(--ink);text-align:right}
.terms-spec dd b{font-weight:500}

/* ---- the disclosure, closing the commitment column ---- */
/* It GREW here. It used to be 14px of secondary grey sitting below a full-ink
   provenance line, so on a page that discloses honestly the honest sentence was
   the quietest thing in the section; it is now full ink at body size, directly
   under the Reserve control. That placement is also what keeps F10: below the
   whole plate it held at 1280 and broke at 390 once the ledger sat between the
   CTA and the line. */
.disclosure{margin-top:var(--sp-8);color:var(--ink);max-width:56ch;
  font-size:var(--t-body);line-height:var(--lh-body)}

/* ---- the colophon ---- */
.mooring-colophon{margin-top:var(--sp-16);border-top:1px solid var(--hairline);
  padding-top:var(--sp-8);display:flex;flex-wrap:wrap;
  align-items:baseline;justify-content:space-between;gap:var(--sp-2) var(--sp-6)}
.provenance{color:var(--ink)}
.contact{color:var(--ink-2);font-size:var(--t-sm);line-height:var(--lh-sm)}

/* ===================== footer ============================================ */
.site-footer{position:relative;z-index:1;background:var(--ground);
  border-top:1px solid var(--hairline);padding:var(--sp-10) var(--gutter);text-align:center}
.site-footer p{margin:var(--sp-1) 0;color:var(--ink-2);
  font-size:var(--t-xs);line-height:var(--lh-xs)}

/* ===================== responsive ======================================== */
@media (max-width:1024px){
  /* the display steps come down together, leading stays 1.0, tracking stays on
     the display step because both sizes are still 40px or above. */
  .hero h1{font-size:64px;line-height:64px}
  .beat h2{font-size:40px;line-height:40px}
}
@media (max-width:900px){
  .hd-nav{display:none}
  .hd-phone{display:flex}
  /* At narrow widths the hero copy spans the FULL column, so a left-weighted
     diagonal wash leaves the right end of every line sitting over open film.
     Once the sub grew to 20px on the type scale it measured 3:1 out there
     (8.31:1 before, AA needs 4.5). The wash becomes vertical here and covers the
     whole copy block, leaving the top of the frame open for the sky and hull. */
  .b-firstlight::before{
    background:linear-gradient(180deg, rgba(8,10,12,.28) 0%, rgba(8,10,12,.76) 24%,
      rgba(8,10,12,.88) 56%, rgba(8,10,12,.88) 100%)}
  /* the stage stops being sticky and stacks above the option rail + build sheet */
  .yard-layout{grid-template-columns:1fr;gap:var(--sp-7)}
  .cfg-stage-zone{position:relative;top:auto}
  /* min-width:0 keeps the aspect-ratio stage from growing past its track and
     forcing a horizontal overflow on phones. */
  .cfg-stage{min-width:0;min-height:0}
  /* the explanation stacks: three 233px columns at 829 would set the step copy
     at about 28 characters a line, which is a column of orphans. */
  .flies-steps{grid-template-columns:1fr;gap:var(--sp-8)}
  .flies-close{grid-template-columns:1fr;gap:var(--sp-8)}
  /* stacked, the column no longer sets the measure, so the step copy does */
  .flies-body{max-width:56ch}
  /* the closing plate stacks on the same breakpoint as the explanation, so the
     two ruled columns become two ruled blocks rather than a 300px ledger with
     "Hull and foil warranty" wrapping onto three lines. */
  .mooring-plate{grid-template-columns:1fr;gap:var(--sp-10)}
}
@media (max-width:768px){
  :root{--gutter:16px}
  /* h2 drops out of the display band into the mid band, so its tracking steps
     with it: -0.06em at 40px and above, -0.04em at 24 to 32. */
  .beat h2{font-size:var(--t-d4);line-height:var(--lh-d4);letter-spacing:var(--track-mid)}
  .panel{padding:var(--sp-6)}
  /* drawings become a horizontal scroller: one sheet at a time, swipeable. */
  .drawings-rail{display:flex;gap:var(--sp-4);overflow-x:auto;scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;padding-bottom:var(--sp-2);
    scrollbar-width:thin}
  .drawings-rail .sheet{flex:0 0 82%;scroll-snap-align:start}
  /* the mat comes down with the column: at 82% of a 390 viewport a 320px mat is
     mostly mat. The sheets stay equal-height, so the captions still line up. */
  .vellum{height:240px;padding:var(--sp-3)}
  /* beat copy anchors to the BOTTOM third as a compact card, never centred over
     the hull. Cap width and height; shortened bodies keep it clear of the cap. */
  .b-rise .pin,.b-thread .pin{align-items:flex-end;padding-bottom:var(--sp-12)}
  .b-night{padding-bottom:var(--sp-12)}
  .b-rise .panel,.b-thread .panel,.b-night .panel{max-width:86vw;max-height:52vh;
    overflow:hidden;padding:var(--sp-5);margin-left:auto;margin-right:auto}
  /* The narrative h2 was 24.8px against a 32px section h2, so on phone the
     emotional beats sat below the utility headings in the hierarchy: the hull
     leaving the water read as less important than "Yours to draw." They are the
     same 32px now, on the mid tracking step. The panel cap rises from 34vh to
     52vh so the taller headings do not clip against overflow:hidden. */
  .b-rise .panel h2,.b-thread .panel h2,.b-night .panel h2{
    font-size:var(--t-d4);line-height:var(--lh-d4);letter-spacing:var(--track-mid)}
  .b-rise .panel .body,.b-thread .panel .body,.b-night .panel .body{
    font-size:var(--t-body);line-height:var(--lh-body);margin-top:var(--sp-3)}
  .b-thread .panel-figs{margin-top:var(--sp-4);gap:var(--sp-4)}
  /* The hero triplet wrapped 2 + 1 at 390 (tops 580, 580, 631), which reads as a
     mistake rather than as a layout. Three equal columns, figure over label, so
     it is one clean row at any phone width. */
  .spec-triplet{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-4);
    margin-top:var(--sp-6);font-size:var(--t-xs);line-height:var(--lh-xs)}
  .spec-triplet span{display:flex;flex-direction:column;gap:var(--sp-1)}
  .spec-triplet b{font-size:var(--t-lead);line-height:var(--sp-6)}
  /* On phone the copy panels anchor to the BOTTOM of the viewport, so a
     bottom-right HUD sat on top of THE RISE and THE THREAD paragraphs (Sol's
     collision). Move the HUD to the TOP-right, below the header, where the
     bottom-anchored panels never reach. Still capped to the viewport, labels
     never wrap, so the whole readout sits inside the phone frame. */
  .hud{right:var(--sp-3);left:auto;top:calc(var(--hd) + var(--sp-2));bottom:auto;
    gap:var(--sp-4);max-width:calc(100vw - var(--sp-6));flex-wrap:nowrap;text-align:right;
    /* the top of the frame is bright dawn sky, so the HUD carries its own dark
       instrument chip (like the cfg-hint pill) to clear AA over any film frame. */
    background:rgba(10,12,14,.9);border:1px solid var(--hairline);border-radius:var(--r);
    padding:var(--sp-2) var(--sp-3);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
  .hud .cell{text-align:right}
  .hud .val{font-size:var(--t-d5);line-height:var(--t-d5)}
  .hud .lbl{white-space:nowrap}
  /* configurator: tighten the surround so the boat renders larger. */
  .yard-inner{padding:var(--sp-12) var(--gutter)}
  .yard-layout{margin-top:var(--sp-7);gap:var(--sp-6)}
  /* four equal peers on one row. Turntable used to take a full-width row of its
     own above the other three, which read as a banner heading rather than as one
     of the four views, and every chip was 25.9px tall. */
  .cfg-controls{gap:var(--sp-1)}
  .cfg-view-btn{font-size:var(--t-xs);flex:1 1 0;min-width:0;padding:0 var(--sp-1)}
  /* the section band stays on the drawings' rhythm; only the internal gaps come
     in, and the lead drops a step so it is not set 23 characters to the line. */
  .flies-lead{font-size:var(--t-body-lg);line-height:var(--lh-body-lg)}
  .flies-steps{margin-top:var(--sp-10)}
  .flies-close{margin-top:var(--sp-12);padding-top:var(--sp-6)}
  /* 48 + the drawings' 96 is the phone gap the night beat already hands on */
  .b-flies{padding-bottom:var(--sp-12)}
}
@media (max-width:560px){
  .hero h1{font-size:44px;line-height:44px}
}

/* short viewport + landscape phone: never trap scroll. Unpin the tall sticky
   beats and let content flow (F5). */
@media (max-height:670px){
  .b-rise,.b-thread{min-height:auto}
  .b-rise .pin,.b-thread .pin{position:static;min-height:auto;padding:var(--sp-16) 0}
  .b-firstlight,.b-night{min-height:auto;padding-top:calc(var(--hd) + var(--sp-8));
    padding-bottom:var(--sp-12)}
  .b-yard{min-height:auto;display:block}
  .cfg-stage-zone{position:relative;top:auto}
  /* the pins are static here, so there is no scroll runway for the panel fade:
     hold the copy fully visible (film.js also guards this, this is the CSS net,
     mirroring the reduced-motion rule). Fixes the intermediate-width band where
     the collapsed beats left the copy stuck at opacity 0. */
  .b-rise .panel,.b-thread .panel{opacity:1;transform:none}
  /* the beats are in normal flow now, so a fixed corner HUD would float over the
     static copy. Drop it into the flow like the reduced-motion treatment, so copy
     and HUD never share pixels in the short-viewport regime. */
  .hud{position:static;opacity:1;justify-content:flex-start;
    right:auto;left:auto;top:auto;bottom:auto;margin:var(--sp-6) 0 0}
}
/* PHONE CONFIGURATOR: pin a SHORT stage rather than unpinning it.
   Measured at a real 390x844 before this rule: with the stage unpinned by the
   900px stack rule, the boat was 239px fully visible at Hull finish but 0px at
   Foil package (top -309) and 0px at Deck (top -784). The two options that cost
   money, Sport at +$14,000 and Cork at +$3,500, were the two that changed a
   boat entirely off screen, so the centrepiece interaction on the majority
   device was "tap a swatch, see nothing happen".

   Reverting line 646 alone does NOT work, for two reasons. (1) The stack rule
   puts the stage in its own grid ROW, and a grid item's sticky containing block
   is its grid area, so a re-stuck stage has zero runway; the layout becomes a
   block flow here so the runway is the whole .yard-layout, which spans the
   option rail and the build sheet. (2) A blanket revert would re-pin a tall
   stage on a short landscape viewport and reintroduce the scroll trap that the
   max-height:670 rule above (F5) exists to stop. Hence min-height:560px: a
   landscape phone keeps the F5 unpin, a portrait phone gets the pinned stage.
   This block sits AFTER that rule on purpose, so at 390x670, where both match,
   source order lets the pin win.

   Pinned block measures 72 header + 8 + 239 stage + 12 = about 331, well inside
   the viewport, so it cannot trap scroll the way a full-height pin would. */
@media (max-width:640px) and (min-height:560px){
  .yard-layout{display:block}
  /* top:0 with the header height carried as PADDING, not as an offset. The
     header hides itself on scroll down (js/config.js sets display:none), so a
     sticky top of var(--hd) left a 72px band above the pinned stage with the
     option rail scrolling through it: the first shot of the live fix caught a
     half-clipped "Nordlys White" row above the boat. Padding keeps that band
     opaque and keeps the stage at the same height whether the header is there
     or away, so nothing jumps when it toggles. */
  .cfg-stage-zone{position:sticky;top:0;z-index:3;
    background:var(--ground);padding:calc(var(--hd) + var(--sp-2)) 0 var(--sp-3)}
  /* The boat stays CONTAINED, never cropped. The frames are background-size:
     cover, so capping the stage HEIGHT would slice the top and bottom off the
     hull; capping the WIDTH instead keeps the 3/2 ratio and shrinks the whole
     stage. 54vh of width is 36vh of height, the cap the spec asks for, and it
     only bites below about a 690px-high viewport. */
  .cfg-stage{width:min(100%,54vh);margin-inline:auto}
  .yard-side{margin-top:var(--sp-6)}
}
@media (orientation:landscape) and (max-height:520px){
  .b-firstlight .hero h1{font-size:40px;line-height:40px}
}

/* ===================== the technical mono ================================ */
/* ONE variable, four places, figures only. A monospace paired with the display
   face for spec data is a recurring signal across verified winners; setting any
   PROSE in it would be the opposite of the signal, so this block is the whole
   of its reach and it is deliberately the last thing in the file.
   Revert = drop this block, --font-mono, the @font-face and the woff2. */
.spec-triplet b,
.panel-figs b,
.flies-n,
.flies-pull-row b,
.terms-spec dd b,
.hud .val,
.hud .lbl,
.build-costs .cost .amt,
.cfg-price,
.sheet figcaption,
.zoom-title{font-family:var(--font-mono)}

/* ===================== motion: opt-in, one duration, one curve ============ */
/* Every transition above declares only its PROPERTY. The duration and the curve
   are granted here, once, and only when the reader has not asked for less
   motion. That is why there is exactly one of each on the whole page: measured
   across production sites, each standardises on a single pair (Stripe ships
   300ms cubic-bezier(0.25,1,0.5,1) in 437 places). This page had five durations
   and two curves before. */
@media (prefers-reduced-motion:no-preference){
  .film-stage #poster,.film-stage #film,
  .site-header,.hd-nav a,.hd-menu a,.hd-menu-btn,
  .btn,.opt,.opt .swatch,.cfg-view-btn,.cfg-crisp,.cfg-hint,
  .vellum,.vellum::after,.zoom-close,
  .b-rise .panel,.b-thread .panel,.hud{
    transition-duration:var(--dur);
    transition-timing-function:var(--ease)}
}

/* ===================== reduced motion ==================================== */
/* Belt and braces: with motion opt-in above, nothing here has a duration to
   begin with. These rules also collapse the tall sticky runways so a reader on
   reduced motion gets a short, static page rather than a scrubbed film. */
@media (prefers-reduced-motion:reduce){
  .b-rise,.b-thread{min-height:auto}
  .b-rise .pin,.b-thread .pin{position:static;min-height:auto;padding:var(--sp-16) 0}
  .b-firstlight{min-height:auto;padding-top:calc(var(--hd) + var(--sp-12));
    padding-bottom:var(--sp-16)}
  .hud{opacity:1;position:static;justify-content:flex-start;margin:var(--sp-6) 0 0}
  .b-night{min-height:auto;padding:var(--sp-20) 0}
  /* the configurator centrepiece: no forced full-height, no idle drift or
     momentum (also guarded in js/config.js), no frame/hint transitions. */
  .b-yard{min-height:auto;display:block}
  .b-rise .panel,.b-thread .panel{opacity:1;transform:none}
}
