/* scrollcraft engine */
/* ============================================================================
   scrollcraft.css: the taste floor
   ----------------------------------------------------------------------------
   Two layers, and the split matters:

     TOKENS   what you override per brand. Colour roles, the type ramp, the
              spacing scale, elevation, motion. A brand is ~12 values.
     DEVICES  what the engine drives. Do not restyle these to taste; they are
              the mechanism. Style your own markup instead.

   Nothing here draws a "component". There are no card, badge, or pill classes,
   because a stylesheet that ships those is how every page built on it ends up
   with the same shapes. You get a floor and a vocabulary; the composition is
   yours.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens -- */
:root {
  /* --- colour roles. Override these six and the page is rebranded. -------- */
  --sc-canvas:      #08090b;   /* the page ground. Drift interpolates this.   */
  --sc-surface:     #101217;   /* anything raised off the ground             */
  --sc-ink:         #f4f2ef;   /* primary text                               */
  --sc-ink-soft:    #9a9ba1;   /* secondary text. Tinted, never flat gray.   */
  --sc-accent:      #d8ff3e;   /* ONE accent. It owns a region, not confetti. */
  --sc-accent-ink:  #08090b;   /* text that sits on the accent               */

  --sc-hairline:    color-mix(in oklab, var(--sc-ink) 12%, transparent);
  --sc-hairline-strong: color-mix(in oklab, var(--sc-ink) 22%, transparent);

  /* --- type. Two families max. Display carries voice, text carries prose. - */
  --sc-font-display: "Instrument Sans", "Geist", system-ui, sans-serif;
  --sc-font-text:    "Geist", system-ui, sans-serif;
  --sc-font-mono:    "Geist Mono", ui-monospace, monospace;

  /* Fluid ramp. Tracking tightens as size grows because a face set at 6rem
     with 0 tracking reads loose; this is optical correction, not decoration. */
  --sc-t-xs:   clamp(0.75rem, 0.72rem + 0.15vw, 0.82rem);
  --sc-t-sm:   clamp(0.875rem, 0.84rem + 0.18vw, 0.95rem);
  --sc-t-base: clamp(1rem, 0.96rem + 0.22vw, 1.125rem);
  --sc-t-lg:   clamp(1.2rem, 1.1rem + 0.5vw, 1.5rem);
  --sc-t-xl:   clamp(1.6rem, 1.35rem + 1.2vw, 2.25rem);
  --sc-t-2xl:  clamp(2.1rem, 1.6rem + 2.4vw, 3.4rem);
  --sc-t-3xl:  clamp(2.8rem, 1.9rem + 4.2vw, 5rem);
  --sc-t-4xl:  clamp(3.4rem, 1.9rem + 6.6vw, 7.5rem);

  --sc-track-tight:  -0.035em;
  --sc-track-snug:   -0.02em;
  --sc-track-normal: -0.005em;
  --sc-track-wide:    0.08em;

  --sc-leading-none: 0.94;
  --sc-leading-tight: 1.06;
  --sc-leading-body: 1.62;

  --sc-measure: 62ch;

  /* --- space. 4px base: the useful middle steps an 8-only scale misses. --- */
  --sc-1: 0.25rem;  --sc-2: 0.5rem;   --sc-3: 0.75rem;  --sc-4: 1rem;
  --sc-5: 1.5rem;   --sc-6: 2rem;     --sc-7: 3rem;     --sc-8: 4rem;
  --sc-9: 6rem;     --sc-10: 8rem;    --sc-11: 12rem;

  /* Section rhythm is fluid so a phone doesn't inherit desktop air. */
  --sc-section: clamp(4.5rem, 9vw, 11rem);
  --sc-gutter:  clamp(1.25rem, 5vw, 5.5rem);
  --sc-maxw:    82rem;

  /* --- radius. Pick one scale for the page and hold it. ------------------- */
  --sc-r-sm: 6px;  --sc-r-md: 12px;  --sc-r-lg: 20px;  --sc-r-pill: 999px;

  /* --- elevation. Every shadow has an offset AND a soft blur, and is tinted
         to the canvas hue. A zero-offset coloured halo is decoration, not
         depth, so there isn't one here. ---------------------------------- */
  --sc-shadow-color: 220 40% 2%;
  --sc-e1: 0 1px 2px hsl(var(--sc-shadow-color) / 0.28),
           0 2px 6px -1px hsl(var(--sc-shadow-color) / 0.20);
  --sc-e2: 0 2px 4px hsl(var(--sc-shadow-color) / 0.24),
           0 8px 18px -4px hsl(var(--sc-shadow-color) / 0.30);
  --sc-e3: 0 4px 8px hsl(var(--sc-shadow-color) / 0.22),
           0 18px 40px -8px hsl(var(--sc-shadow-color) / 0.38),
           0 48px 90px -24px hsl(var(--sc-shadow-color) / 0.30);

  /* Edge light: a 1px top highlight sells a raised surface better than any
     amount of blur, because real raised things catch light on their lip. */
  --sc-edge: inset 0 1px 0 color-mix(in oklab, var(--sc-ink) 10%, transparent);

  /* --- motion. Built-in CSS easings are too weak for UI. ------------------ */
  --sc-ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --sc-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --sc-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --sc-d-fast: 160ms;  --sc-d-base: 240ms;  --sc-d-slow: 420ms;

  --sc-z-stage: 1; --sc-z-copy: 20; --sc-z-chrome: 60;
}

/* --------------------------------------------------------------- reset -- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--sc-canvas);
  color: var(--sc-ink);
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-base);
  line-height: var(--sc-leading-body);
  letter-spacing: var(--sc-track-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none;
  overflow-x: clip;
}
img, video, canvas, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }

/* ------------------------------------------------- the browser surfaces --
   The parts you did not draw still carry the design. Selection, caret, focus
   ring, scrollbar and tabular numerals all ship with defaults that belong to no
   design system. Theming them is the cheapest signal that a page was built
   rather than assembled, and it is the step that gets skipped most reliably. */
::selection { background: var(--sc-accent); color: var(--sc-accent-ink); }
:root { caret-color: var(--sc-accent); accent-color: var(--sc-accent); }
:focus-visible {
  outline: 2px solid var(--sc-accent);
  outline-offset: 3px;
  border-radius: var(--sc-r-sm);
}
:where(a) { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
@supports (scrollbar-color: auto) {
  html { scrollbar-color: color-mix(in oklab, var(--sc-ink) 26%, transparent) transparent; scrollbar-width: thin; }
}
:where(table, .sc-nums, [data-sc-count]) { font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------- typography -- */
.sc-display {
  font-family: var(--sc-font-display);
  font-weight: 500;
  line-height: var(--sc-leading-none);
  letter-spacing: var(--sc-track-tight);
  text-wrap: balance;
  margin: 0;
}
.sc-display--xl { font-size: var(--sc-t-4xl); }
.sc-display--lg { font-size: var(--sc-t-3xl); }
.sc-display--md { font-size: var(--sc-t-2xl); letter-spacing: var(--sc-track-snug); }
.sc-lede {
  font-size: var(--sc-t-lg);
  line-height: 1.44;
  letter-spacing: var(--sc-track-snug);
  color: var(--sc-ink);
  max-width: 46ch;
  text-wrap: pretty;
  margin: 0;
}
.sc-body { max-width: var(--sc-measure); color: var(--sc-ink-soft); text-wrap: pretty; margin: 0; }
.sc-label {
  font-family: var(--sc-font-mono);
  font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide);
  text-transform: uppercase;
  color: var(--sc-ink-soft);
}

/* ---------------------------------------------------------------- layout -- */
.sc-wrap { width: 100%; max-width: var(--sc-maxw); margin-inline: auto; padding-inline: var(--sc-gutter); }
.sc-section { padding-block: var(--sc-section); }
/* More space above a heading than below it: the gap belongs to the boundary,
   not to the pair. */
.sc-stack > * + * { margin-top: var(--sc-4); }
.sc-stack > :is(h1,h2,h3) { margin-top: var(--sc-7); }
.sc-stack > :is(h1,h2,h3):first-child { margin-top: 0; }
.sc-rule { height: 1px; border: 0; background: var(--sc-hairline); margin: 0; }

/* =============================================================== DEVICES ==
   Driven by the engine. Restyle your own markup, not these.                */

.sc-act--pinned { position: relative; }
.sc-stage {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: clip;
  z-index: var(--sc-z-stage);
}

/* scrub / sequence media */
.sc-stage :is(video[data-sc-scrub], canvas[data-sc-sequence], .sc-stage__poster) {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
video[data-sc-scrub] { opacity: 0; transition: opacity 380ms var(--sc-ease-out); }
.sc-has-clip video[data-sc-scrub] { opacity: 1; }
/* The poster is a live frame-holder, not a placeholder: it stays up until a
   real video frame has painted, which is what stops the blank-stage flash. */
.sc-stage__poster { z-index: 0; transition: opacity 380ms var(--sc-ease-out); }
.sc-has-clip .sc-stage__poster { opacity: 0; }

/* A scrim only where text sits. A full-frame darkening layer flattens the
   image everywhere to fix contrast in one corner. */
.sc-scrim {
  position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background: linear-gradient(
    var(--sc-scrim-angle, 180deg),
    color-mix(in oklab, var(--sc-canvas) var(--sc-scrim-a, 78%), transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 30%, transparent) 42%,
    transparent 68%);
}
/* Point the scrim at the copy. A scrim gradient that darkens the top while the
   copy sits at the bottom fixes contrast nowhere and flattens the image
   everywhere, which is the most common way text-over-video goes wrong. */
.sc-scrim--bottom { --sc-scrim-angle: 0deg; }
.sc-scrim--left   { --sc-scrim-angle: 90deg; }
.sc-scrim--right  { --sc-scrim-angle: 270deg; }

/* Corner scrims, for copy anchored to a corner. An edge gradient has to darken
   a whole band across the frame to cover one corner; a corner gradient puts the
   density where the text is and leaves the rest of the image alone. Pair with
   .sc-copy--lead / .sc-copy--trail. */
.sc-scrim--lead {
  background: linear-gradient(to top right,
    color-mix(in oklab, var(--sc-canvas) 94%, transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 72%, transparent) 30%,
    color-mix(in oklab, var(--sc-canvas) 30%, transparent) 52%,
    transparent 72%);
}
.sc-scrim--trail {
  background: linear-gradient(to top left,
    color-mix(in oklab, var(--sc-canvas) 94%, transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 72%, transparent) 30%,
    color-mix(in oklab, var(--sc-canvas) 30%, transparent) 52%,
    transparent 72%);
}
/* A band across the bottom, for copy that spans the full width of the frame.
   That is what both corner anchors become below 860px, and it is also the right
   shape whenever the copy block is wider than a corner. */
.sc-scrim--band {
  background: linear-gradient(to top,
    color-mix(in oklab, var(--sc-canvas) 94%, transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 74%, transparent) 22%,
    color-mix(in oklab, var(--sc-canvas) 30%, transparent) 42%,
    transparent 58%);
}
.sc-scrim--vignette {
  background: radial-gradient(120% 90% at 50% 45%, transparent 40%,
              color-mix(in oklab, var(--sc-canvas) 70%, transparent) 100%);
}

/* copy over a stage.
   max-width is in rem, never ch. A `ch` on this container resolves against the
   CONTAINER's font-size (body size), not the display size of the heading inside
   it, so `max-width: 20ch` here silently produces a ~180px column and wraps a
   hero headline to six lines. Set a ch measure on the text element itself. */
.sc-copy {
  position: absolute; z-index: var(--sc-z-copy);
  inset-inline: var(--sc-gutter);
  max-width: min(46rem, 76vw);
  will-change: opacity, transform;
}
.sc-copy--lead   { left: var(--sc-gutter); bottom: clamp(3rem, 12vh, 9rem); }
/* inset-inline FIRST. It is the shorthand for left+right, so declaring it after
   `left: 50%` resets left to auto and the block drifts off the left edge. */
.sc-copy--center { inset-inline: auto; left: 50%; top: 50%; translate: -50% -50%; text-align: center; }
.sc-copy--trail  { inset-inline: auto; right: var(--sc-gutter); bottom: clamp(3rem, 12vh, 9rem); text-align: right; }

/* cue defaults: the engine writes opacity/transform inline, these are the
   pre-paint state so nothing flashes before the first read() */
[data-sc-cue] { opacity: 0; will-change: opacity, transform; }
.sc-ready [data-sc-cue] { transition: none; }

/* kinetic split */
.sc-split { display: inline-block; overflow: hidden; vertical-align: top; }
/* Descenders live below the baseline; a line mask clipped to the line box eats
   the tails off g, y, p, j. The padding buys them room back. */
.sc-split--line { display: block; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.sc-split__i { display: inline-block; will-change: transform, opacity; }
.sc-is-split { opacity: 1 !important; }

/* horizontal rail */
[data-sc-pan] { display: flex; will-change: transform; }

/* reveal + parallax */
[data-sc-reveal] { will-change: clip-path; }
[data-sc-parallax] { will-change: transform; }

/* flow reveal (fires once) */
[data-sc-in], [data-sc-stagger] > * {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: opacity 620ms var(--sc-ease-out), transform 620ms var(--sc-ease-out);
}
[data-sc-in].sc-in, [data-sc-stagger] > .sc-in { opacity: 1; transform: none; }

/* pointer devices */
[data-sc-tilt] { transform-style: preserve-3d; will-change: transform; }
[data-sc-magnet] { will-change: transform; }
/* isolation always; position only if nothing more specific already set it.
   Written with :where() (zero specificity) on purpose: a plain `position:
   relative` here has the same weight as `.sc-stage` and, being later in the
   file, silently wins. A stage carrying both attributes then stops being
   sticky and the whole act scrolls away instead of pinning. */
[data-sc-spotlight] { isolation: isolate; }
:where([data-sc-spotlight]) { position: relative; }
[data-sc-spotlight]::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(
    28rem 28rem at calc(var(--sc-mx, 0.5) * 100%) calc(var(--sc-my, 0.5) * 100%),
    color-mix(in oklab, var(--sc-accent) 16%, transparent), transparent 70%);
  opacity: 0; transition: opacity var(--sc-d-slow) var(--sc-ease-out);
}
[data-sc-spotlight]:hover::after { opacity: 1; }

/* =========================================================== WORLDFLIGHT ==
   One fixed stage for the whole page. The only thing in document flow is the
   spacer, and it is empty. If you find yourself adding a section here, you want
   act mode instead: the moment a real block scrolls past the fixed stage, the
   page has a seam again and the whole point is gone.                        */

[data-sc-mode="worldflight"] { position: relative; }

.sc-world {
  position: fixed; inset: 0;
  overflow: clip;
  z-index: var(--sc-z-stage);
  background: var(--sc-canvas);
}

/* Every leg is mounted for the life of the page and stacked in the same box.
   The engine owns opacity, visibility and z-index here; do not set them. */
.sc-world__seg {
  position: absolute; inset: 0;
  opacity: 0;
  will-change: opacity;
}
.sc-world__seg > :is(video, img, canvas) {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* The poster is the frame-holder AND the first camera move: the engine pushes
   it in slowly until a real decoded frame is available to replace it. */
.sc-world__poster {
  z-index: 0;
  transform-origin: 50% 50%;
  transition: opacity 420ms var(--sc-ease-out);
}
.sc-world__seg > video { z-index: 1; }
.sc-world__seg.sc-has-clip .sc-world__poster { opacity: 0; }
/* The act stylesheet lights a clip through its ancestor act. A worldflight leg
   has no act, so match the class the engine also writes on the clip itself. */
video[data-sc-scrub].sc-has-clip { opacity: 1; }

/* The copy layer is fixed too, and inert by default: the engine hands
   pointer-events back to a block only while it is actually legible. */
.sc-world__copy {
  position: fixed; inset: 0;
  z-index: var(--sc-z-copy);
  pointer-events: none;
}
.sc-world__scrim { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
[data-sc-copy] {
  opacity: 0;
  pointer-events: none;
  will-change: opacity, transform;
}
.sc-ready [data-sc-copy] { transition: none; }

/* The track. Empty on purpose. */
.sc-world__spacer { pointer-events: none; }

/* scroll progress */
[data-sc-progress] {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: var(--sc-z-chrome);
  background: var(--sc-accent); transform-origin: 0 50%; transform: scaleX(0);
  will-change: transform;
}

/* ----------------------------------------------------------- atmosphere --
   Depth is not only shadow. Grain keeps a flat dark ground from banding, and
   it is the difference between "a dark page" and "a lit room". */
.sc-grain { position: fixed; inset: 0; pointer-events: none; z-index: 3; opacity: 0.045; }
.sc-grain::before {
  content: ""; position: absolute; inset: -50%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}

/* -------------------------------------------------------- reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  /* Fewer and gentler, not zero. Opacity still carries the reveal so the page
     is comprehensible; every position change is dropped. */
  [data-sc-in], [data-sc-stagger] > * { transform: none; transition-duration: 220ms; }
  [data-sc-parallax], [data-sc-pan], .sc-split__i { transform: none !important; }
  /* A wipe is a position change too. Show reveal content settled. */
  [data-sc-reveal] { clip-path: none !important; }
  /* A rail's transform IS its navigation, not decoration. Zeroing it the way
     parallax and kinetic type are zeroed parks the act on its first screenful
     and makes everything past the fold unreachable: a device degrading into
     missing content. Hand the travel back to the reader as an ordinary scroll
     region instead, so the same items are all still gettable without motion.
     A build that would rather re-lay the rail out as a grid can still do that;
     this is the floor, not the ceiling. */
  [data-sc-act="pan"] .sc-stage,
  [data-sc-act="pan"] [data-sc-stage] {
    overflow-x: auto; overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
  }
  [data-sc-pan] > * { scroll-snap-align: center; }
  [data-sc-spotlight]::after { display: none; }
  /* A worldflight keeps its whole story here. No clip is ever fetched, so the
     posters are the film, and they cross-dissolve through exactly the same
     seams at exactly the same scroll positions. The push-in and the copy drift
     are the only things that go. */
  .sc-world__poster, [data-sc-copy] { transform: none !important; }
}

/* --------------------------------------------------------------- mobile -- */
@media (max-width: 860px) {
  .sc-copy { inset-inline: var(--sc-gutter); max-width: none; }
  .sc-copy--trail { text-align: left; }
  .sc-stage { height: 100svh; }
  /* .sc-copy--trail re-anchors to the left and spans the full width here, so a
     bottom-RIGHT corner gradient darkens the one corner the copy just left and
     guarantees a contrast failure over any bright clip. Point the density at
     the copy: the same band .sc-scrim--band paints. */
  .sc-scrim--trail {
    background: linear-gradient(to top,
      color-mix(in oklab, var(--sc-canvas) 94%, transparent) 0%,
      color-mix(in oklab, var(--sc-canvas) 74%, transparent) 22%,
      color-mix(in oklab, var(--sc-canvas) 30%, transparent) 42%,
      transparent 58%);
  }
}


/* harlem labs page */
/* ═══════════════════════════════════════════════════════════════════════════
   HARLEM LABS · harlemlabs.com
   Grammar: split stage (uniqueness.md 2.7), rotated ninety degrees.

   The split is horizontal bands rather than columns, so the divider can be a
   six week rail and travel can run rightward. Two grounds, one per band, and
   they HOLD: the grammar bans drift, so nothing here interpolates a colour.

   Band meaning is fixed for the whole page and never becomes decorative:
     ABOVE the rail  the same six weeks with someone who has been up this face
     BELOW the rail  the same six weeks alone
   By act four the lower band is the operator alone AGAIN, but now running the
   system unaided, which is what earns the collapse in act five.

   Type comes from app/layout.tsx via next/font/google, self hosted at build
   time and therefore font-src 'self' clean. Fallbacks are real, not decorative.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --hl-navy:     #0F1726;
  --hl-air:      #0B1728;   /* ground ABOVE the rail. cooler, thinner */
  --hl-base:     #070B12;   /* ground BELOW the rail. denser, heavier */
  --hl-teal:     #0F2940;
  --hl-steel:    #304C79;
  --hl-gold:     #DAB039;
  --hl-gold-dk:  #BE882C;
  --hl-light:    #F2F2F2;
  --hl-muted:    #8A9AB5;
  --hl-rule:     rgba(48, 76, 121, 0.42);

  --hl-display: var(--font-playfair), "Playfair Display", Georgia, serif;
  --hl-sans:    var(--font-dm-sans), "DM Sans", system-ui, -apple-system, sans-serif;
  --hl-mono:    var(--font-dm-mono), "DM Mono", ui-monospace, monospace;

  --hl-split:  50%;      /* where the rail sits. driven to 100% at the close */
  --hl-travel: 0px;      /* horizontal travel of the week field. set by page.js */
  --hl-station: 34vw;

  --hl-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; }

body {
  margin: 0;
  background: var(--hl-base);
  color: var(--hl-light);
  font-family: var(--hl-sans);
  font-weight: 300;
  overflow-x: hidden;
}

/* The two grounds. Fixed, so the rail is a real horizon rather than a border
   that scrolls. The split position is the only thing that ever moves. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(to bottom,
      var(--hl-air)  0, var(--hl-air)  var(--hl-split),
      var(--hl-base) var(--hl-split), var(--hl-base) 100%);
}

main { position: relative; z-index: 1; }

.hl-skip {
  position: absolute; left: 1rem; top: -4rem; z-index: 200;
  background: var(--hl-gold); color: var(--hl-navy);
  padding: 0.75rem 1.25rem; font-family: var(--hl-mono);
  font-size: 0.75rem; letter-spacing: 0.14em; text-transform: uppercase;
  text-decoration: none; transition: top 160ms var(--hl-ease);
}
.hl-skip:focus-visible { top: 1rem; }

/* ── THE DIVIDER · the chrome ────────────────────────────────────────────
   Split stage takes no top bar. This carries both side labels, the week
   readout, the wordmark, one CTA and the progress of the argument. */
.hl-divider {
  position: fixed;
  left: 0; right: 0;
  top: var(--hl-split);
  transform: translateY(-50%);
  z-index: 40;
  pointer-events: none;
  opacity: var(--hl-chrome, 1);
}
/* Fully retired chrome must not keep swallowing clicks on what is under it. */
.hl-divider[data-hl-gone] { visibility: hidden; }
.hl-divider__cap {
  /* Rides the rail, centred on it. Any floating corner island is eventually
     driven through by a version mark at altitude, because the field travels the
     full width. On the rail it is part of the divider, which is what the
     grammar says the chrome is, and the climb keeps the whole upper band.
     The ground behind is the split itself, mixed at the exact same stop, so the
     rule is interrupted rather than plated. */
  position: absolute;
  left: clamp(0.6rem, 3vw, 2.6rem);
  top: 50%; transform: translateY(-50%);
  z-index: 2;
  display: flex; align-items: center; gap: 1.1rem;
  padding: 0.55rem 1.1rem 0.55rem 0.4rem;
  background: linear-gradient(to bottom, var(--hl-air) 50%, var(--hl-base) 50%);
  pointer-events: auto;
}
.hl-divider__mark {
  display: flex; align-items: center; gap: 0.6rem;
  text-decoration: none; color: var(--hl-light);
}
.hl-mark { width: 2.5rem; height: 1.5rem; color: var(--hl-steel); flex: none; }
.hl-divider__wordmark {
  font-family: var(--hl-mono); font-size: 0.6875rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--hl-light);
}
.hl-divider__cta {
  font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--hl-gold); text-decoration: none;
  border: 1px solid var(--hl-rule); padding: 0.4rem 0.85rem;
  transition: border-color 200ms var(--hl-ease), color 200ms var(--hl-ease);
}
.hl-divider__cta:hover,
.hl-divider__cta:focus-visible { border-color: var(--hl-gold); color: var(--hl-light); }

.hl-divider__rail {
  position: relative;
  height: 1px;
  background: var(--hl-rule);
}
.hl-divider__progress {
  position: absolute; inset: 0;
  display: block; overflow: hidden;
}
.hl-divider__progress i {
  display: block; height: 100%; width: 100%;
  background: var(--hl-gold);
  transform-origin: 0 50%;
  transform: scaleX(var(--hl-prog, 0));
}
.hl-divider__side {
  position: absolute;
  font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--hl-muted); white-space: nowrap;
}
.hl-divider__week {
  font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--hl-gold); white-space: nowrap;
  font-variant-numeric: tabular-nums;
  padding-left: 0.4rem;
}
.hl-divider__side--up   { right: clamp(1rem, 3.4vw, 3rem); bottom: 0.7rem; }
.hl-divider__side--down { right: clamp(1rem, 3.4vw, 3rem); top: 0.7rem; }
.hl-divider__side--up   { color: #A9BBD8; }


/* ── ACTS ──────────────────────────────────────────────────────────────── */
/* The engine owns .sc-stage: position sticky, top 0, height 100vh, overflow
   clip. It adds that class to this element at mount. Declaring position or
   height here loads after scrollcraft.css at equal specificity and silently
   un-pins every act, which reads as a page that scrolls past its own content. */
.hl-stage { display: block; }

/* Every copy block is positioned against the rail, never against the page, so
   nothing can drift across the horizon. NOTE: no max-width lives on .hl-copy.
   A base max-width silently clamps every width override a child asks for. */
.hl-copy { position: absolute; z-index: 6; }

.hl-eyebrow {
  margin: 0 0 1.4rem;
  font-family: var(--hl-mono); font-size: 0.6875rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--hl-gold);
  display: flex; align-items: center; gap: 0.65rem;
}
.hl-eyebrow::before {
  content: ''; width: 1.75rem; height: 1px; background: var(--hl-gold); flex: none;
}
.hl-kicker {
  margin: 0 0 0.85rem;
  font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--hl-gold);
}

.hl-h1 {
  margin: 0 0 1.6rem;
  font-family: var(--hl-display); font-weight: 900;
  font-size: clamp(2.4rem, 5vw, 4.5rem);
  line-height: 1.02; letter-spacing: -0.025em; color: var(--hl-light);
}
.hl-h1 em, .hl-h2 em { font-style: normal; color: var(--hl-gold); }

.hl-h2 {
  margin: 0 0 1.5rem;
  font-family: var(--hl-display); font-weight: 900;
  font-size: clamp(2.1rem, 4.4vw, 3.7rem);
  line-height: 1.07; letter-spacing: -0.02em; color: var(--hl-light);
}
.hl-h2--sm    { font-size: clamp(1.8rem, 3.2vw, 2.7rem); }
.hl-h2--close { font-size: clamp(1.7rem, 3vw, 2.5rem); line-height: 1.14; }

.hl-lede {
  margin: 0; max-inline-size: 40ch;
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  line-height: 1.82; color: var(--hl-muted);
}
.hl-lede--wide { max-inline-size: 58ch; }

/* ── ACT 1 · THE SPLIT ─────────────────────────────────────────────────── */
.hl-band { position: absolute; left: 0; right: 0; z-index: 3; }
.hl-band--up   { top: 0; bottom: 50%; }
.hl-band--down { top: 50%; bottom: 0; }
.hl-band__label {
  position: absolute;
  right: clamp(1rem, 3.4vw, 3rem);
  margin: 0; max-inline-size: 22ch; text-align: right;
  font-family: var(--hl-mono); font-size: 0.6875rem;
  line-height: 1.9; letter-spacing: 0.06em; color: var(--hl-muted);
}
.hl-band--up   .hl-band__label { bottom: clamp(3.5rem, 8vh, 7rem); }
.hl-band--down .hl-band__label { top: clamp(3.5rem, 8vh, 7rem); }

/* Top anchored, never bottom anchored against the rail: a bottom anchor plus a
   tall headline pushes the first line off the top of the frame, and the landing
   view is the one screen every visitor sees. */
.hl-hero {
  left: clamp(1rem, 3.4vw, 3rem);
  right: clamp(1rem, 3.4vw, 3rem);
  top: clamp(4.5rem, 11vh, 7.5rem);
}
/* The second headline. Split stage wants both sides readable at once on the
   first screen, or the reader does not learn the format before they scroll. */
.hl-hero-b {
  left: clamp(1rem, 3.4vw, 3rem);
  right: clamp(1rem, 3.4vw, 3rem);
  top: calc(50% + clamp(3rem, 8vh, 5.5rem));
}
.hl-h2--counter {
  margin: 0;
  font-family: var(--hl-display); font-weight: 400; font-style: italic;
  font-size: clamp(1.5rem, 2.8vw, 2.4rem);
  line-height: 1.22; letter-spacing: -0.015em; color: var(--hl-muted);
}
.hl-scrollcue {
  margin: 2.2rem 0 0;
  font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--hl-muted);
  display: flex; align-items: center; gap: 0.7rem;
}
.hl-scrollcue::after {
  content: ''; width: clamp(2rem, 6vw, 5rem); height: 1px;
  background: linear-gradient(to right, var(--hl-gold), transparent);
}

/* ── ACT 2 · THE SIX WEEKS · the signature move ────────────────────────── */
.hl-field {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: calc(var(--hl-station) * 7);
  transform: translate3d(calc(var(--hl-travel) * var(--sc-p, 0) * -1), 0, 0);
  will-change: transform;
}

/* The two lines. The gold one is already complete because the face is known.
   The light one draws itself as the reader climbs. */
.hl-lines { position: absolute; left: 0; right: 0; top: 0; height: 50%; width: 100%; overflow: visible; }
.hl-lines__sherpa {
  stroke: var(--hl-gold); stroke-width: 1.4; opacity: 0.5;
  stroke-dasharray: 5 7; vector-effect: non-scaling-stroke;
}
.hl-lines__climb {
  stroke: #C6D4EC; stroke-width: 2.4; vector-effect: non-scaling-stroke;
  stroke-linecap: round; stroke-linejoin: round;
}

.hl-weeks {
  position: absolute; inset: 0; margin: 0; padding: 0;
  list-style: none; z-index: 4;
}
.hl-station {
  position: absolute;
  top: 0; bottom: 0;
  width: var(--hl-station);
  left: calc(var(--hl-station) * (var(--i) - 1) + var(--hl-station) * 0.55);
  padding-right: 2.4vw;
  box-sizing: border-box;
  opacity: var(--hl-vis, 0);
}
.hl-station[data-hl-station="1"] { --i: 1; }
.hl-station[data-hl-station="2"] { --i: 2; }
.hl-station[data-hl-station="3"] { --i: 3; }
.hl-station[data-hl-station="4"] { --i: 4; }
.hl-station[data-hl-station="5"] { --i: 5; }
.hl-station[data-hl-station="6"] { --i: 6; }

/* Grouping only. Every part is placed against the rail directly, because the
   outcome has to travel hundreds of pixels away from the intention and a shared
   flow would drag the intention with it. */
.hl-station__cell { display: contents; }

/* The week number is the divider's job. Kept in the DOM for reduced motion and
   for screen readers, hidden while the rail is doing the counting. */
.hl-station__wk {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0;
}

/* Sits directly on top of the rail. Both operators received this, identically,
   which is why it is stated once and never duplicated per band. */
.hl-station__intent {
  position: absolute; left: 0; bottom: calc(50% + 2.6rem);
  margin: 0; max-inline-size: 18ch;
  font-family: var(--hl-display); font-weight: 400;
  font-size: clamp(1.15rem, 1.85vw, 1.75rem);
  line-height: 1.26; letter-spacing: -0.012em; color: var(--hl-light);
}

/* Above the rail: worked, cleared, and all that stays is the version. It sits
   at the altitude that week bought. */
.hl-station__up {
  position: absolute; left: 0;
  bottom: calc(50% + var(--hl-lift, 70px));
  margin: 0;
  font-family: var(--hl-mono); font-size: 0.6875rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: #C6D4EC; white-space: nowrap;
  opacity: var(--hl-cleared, 0);
  transform: translateY(calc(10px * (1 - var(--hl-cleared, 0))));
  border-left: 2px solid var(--hl-gold);
  padding: 0.3rem 0 0.3rem 0.6rem;
}
.hl-station__up b { color: var(--hl-light); font-weight: 500; }
.hl-station__up span { color: var(--hl-gold); }

/* Below the rail: it stays. Each week settles deeper than the last. */
.hl-station__down {
  position: absolute; left: 0;
  top: calc(50% + var(--hl-sink, 70px));
  margin: 0;
  font-family: var(--hl-mono); font-size: 0.6875rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--hl-muted);
  opacity: calc(0.3 + 0.5 * var(--hl-vis, 0));
  padding-top: 0.55rem;
}
.hl-station__down::before {
  content: ''; position: absolute; left: 0; top: 0;
  width: 5.5rem; height: 1px; background: var(--hl-rule);
}
/* The sediment itself: wider and heavier every week nothing came back. */
.hl-station__down::after {
  content: ''; position: absolute; left: 0; top: 100%;
  margin-top: 0.7rem;
  width: calc(38% + 11% * var(--i));
  height: calc(2px + 2px * var(--i));
  background: var(--hl-steel);
  opacity: calc(0.16 + 0.05 * var(--i));
}

.hl-weekcopy {
  left: clamp(1rem, 3.4vw, 3rem);
  z-index: 8;
}
.hl-weekcopy               { bottom: calc(50% + clamp(12rem, 28vh, 17rem)); }
.hl-weekcopy--mid          { bottom: auto; top: calc(50% + 1.1rem); }
.hl-weekcopy--late         { bottom: auto; top: calc(50% + 1.1rem); }
.hl-weekline {
  margin: 0; max-inline-size: 30ch;
  font-family: var(--hl-display); font-weight: 400;
  font-size: clamp(1.3rem, 2.2vw, 2rem);
  line-height: 1.34; letter-spacing: -0.015em; color: var(--hl-light);
}

/* ── ACT 3 · THE GAP ───────────────────────────────────────────────────── */
.hl-creed {
  left: clamp(1rem, 3.4vw, 3rem);
  bottom: calc(50% + clamp(2.5rem, 6vh, 5rem));
}
.hl-proof {
  left: clamp(1rem, 3.4vw, 3rem);
  right: clamp(1rem, 3.4vw, 3rem);
  top: calc(50% + clamp(2.5rem, 6vh, 5rem));
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}
.hl-quote { margin: 0; }
.hl-quote blockquote {
  margin: 0 0 0.9rem;
  border-left: 2px solid var(--hl-gold);
  padding-left: 1rem;
  font-family: var(--hl-display); font-style: italic; font-weight: 400;
  font-size: clamp(0.98rem, 1.3vw, 1.1rem);
  line-height: 1.62; color: var(--hl-light);
}
.hl-quote figcaption {
  padding-left: 1rem;
  font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--hl-muted);
}
.hl-quote figcaption b { display: block; color: var(--hl-light); font-weight: 500; }
.hl-quote figcaption span { display: block; margin-top: 0.25rem; }
.hl-quote--wide blockquote { font-size: clamp(0.95rem, 1.2vw, 1.05rem); }

/* ── ACT 4 · WHAT THIS IS ──────────────────────────────────────────────── */
.hl-what {
  left: clamp(1rem, 3.4vw, 3rem);
  bottom: calc(50% + clamp(2rem, 5vh, 4rem));
}
.hl-steps { margin: 1.6rem 0 0; padding: 0; list-style: none; display: grid; gap: 1rem; max-inline-size: 46ch; }
.hl-steps li { display: grid; grid-template-columns: 5.5rem 1fr; gap: 1rem; align-items: baseline;
  border-top: 1px solid var(--hl-rule); padding-top: 0.85rem; }
.hl-steps b {
  font-family: var(--hl-mono); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--hl-gold);
}
.hl-steps span { font-size: 0.9375rem; line-height: 1.72; color: var(--hl-muted); }

.hl-outcome {
  left: clamp(1rem, 3.4vw, 3rem);
  right: clamp(1rem, 3.4vw, 3rem);
  top: calc(50% + clamp(2rem, 5vh, 4rem));
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: clamp(1.25rem, 2.6vw, 2.5rem);
  align-items: start;
}
.hl-facts { margin: 0; display: grid; gap: 1.25rem; }
.hl-facts div { display: grid; gap: 0.3rem; }
.hl-facts dt {
  font-family: var(--hl-display); font-weight: 900;
  font-size: clamp(2.2rem, 3.6vw, 3rem); line-height: 1; color: var(--hl-gold);
  font-variant-numeric: tabular-nums;
}
.hl-facts dd {
  margin: 0; font-family: var(--hl-mono); font-size: 0.625rem;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--hl-muted);
}
.hl-note {
  margin: 0; font-size: 0.875rem; line-height: 1.75; color: var(--hl-muted);
  border-top: 1px solid var(--hl-rule); padding-top: 0.85rem;
}

/* ── ACT 5 · THE COLLAPSE ──────────────────────────────────────────────── */
.hl-summit {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 2; opacity: var(--hl-summit-vis, 0);
}
.hl-summit path { vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; }
.hl-summit__left, .hl-summit__right { stroke: var(--hl-steel); stroke-width: 2; }
.hl-summit__notch { stroke: var(--hl-gold); stroke-width: 3; }

/* Top anchored inside the winning band, not centred on the stage. Centred, the
   block is still crossing the rail while the act slides in, and the divider
   eats its first line. Anchored, the copy holds still and the ground opens
   underneath it as the split collapses, which is a better collapse anyway. */
.hl-close {
  left: clamp(1rem, 3.4vw, 3rem);
  right: clamp(1rem, 3.4vw, 3rem);
  top: clamp(4.5rem, 12vh, 8rem);
  z-index: 8;
}
.hl-close .hl-h2--close { max-inline-size: 30ch; }
.hl-ctas { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1.9rem; }
.hl-btn {
  display: inline-flex; align-items: center; gap: 0.7rem;
  padding: 1rem 2rem;
  font-family: var(--hl-mono); font-size: 0.75rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; text-decoration: none;
  color: var(--hl-light); border: 1px solid var(--hl-rule);
  transition: border-color 200ms var(--hl-ease), color 200ms var(--hl-ease),
              background-color 200ms var(--hl-ease);
}
.hl-btn:hover, .hl-btn:focus-visible { border-color: var(--hl-gold); color: var(--hl-gold); }
.hl-btn--gold { background: var(--hl-gold); color: var(--hl-navy); border-color: var(--hl-gold); }
.hl-btn--gold:hover, .hl-btn--gold:focus-visible { background: var(--hl-gold-dk); border-color: var(--hl-gold-dk); color: var(--hl-navy); }
.hl-close__note { margin: 1.4rem 0 0; max-inline-size: 44ch; font-size: 0.875rem; line-height: 1.75; color: var(--hl-muted); }

:where(a, button):focus-visible { outline: 2px solid var(--hl-gold); outline-offset: 3px; }

/* ── PHONE ─────────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  :root { --hl-station: 78vw; }
  .hl-divider__side { font-size: 0.5625rem; max-inline-size: 9ch; white-space: normal; text-align: right; line-height: 1.5; }
  .hl-divider__wordmark { display: none; }
  /* The divider already says WITH A SHERPA / ON YOUR OWN. At this width the
     long form is the same statement crushed into a nine character column. */
  .hl-band__label { display: none; }
  .hl-hero { right: clamp(1rem, 3.4vw, 3rem); }
  .hl-proof, .hl-outcome { grid-template-columns: 1fr; gap: 1.1rem; }
  /* Stacked to one column these blocks are tall, and act four's stage is
     already on screen with greeted copy while act three is still fading out.
     Pulling them toward their own rail keeps the two apart through the whole
     crossfade instead of letting them touch for a few frames. */
  .hl-proof   { top: calc(50% + 1.2rem); }
  .hl-outcome { top: calc(50% + 1.2rem); }
  .hl-quote blockquote { font-size: 0.9rem; line-height: 1.55; margin-bottom: 0.5rem; }
  .hl-quote figcaption { font-size: 0.5625rem; }
  .hl-steps li { grid-template-columns: 1fr; gap: 0.3rem; }
  .hl-weekcopy { bottom: calc(50% + clamp(8rem, 30vh, 13rem)); }
  .hl-weekcopy--mid, .hl-weekcopy--late { bottom: auto; top: calc(50% + 1rem); }
}

/* ── REDUCED MOTION ────────────────────────────────────────────────────────
   Meaning survives. The field stops travelling and every station, both lines
   and all copy render at once as a static readable comparison. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  :root { --hl-split: 100%; }
  .hl-field { transform: none; width: 100%; }

  /* The divider stops being a horizon and becomes a plain top strip, because
     with no travel there is no split to sit between, and centred it printed
     straight through the middle of the table. */
  .hl-divider { top: 0; transform: none; }
  .hl-divider__cap {
    position: static; transform: none; background: none;
    padding: 0.9rem clamp(1rem, 3.4vw, 3rem);
  }
  .hl-divider__rail { position: static; height: auto; background: none;
    padding: 0 clamp(1rem, 3.4vw, 3rem) 0.8rem; }
  .hl-divider__progress { display: none; }
  .hl-divider__side {
    position: static; display: inline-block; margin: 0 1.6rem 0 0;
    opacity: 1;
  }
  .hl-divider__side--up { color: #C6D4EC; }
  .hl-divider__side--up::before  { content: 'Above the line: '; color: var(--hl-muted); }
  .hl-divider__side--down::before { content: 'Below the line: '; color: var(--hl-muted); }

  .hl-station {
    position: relative; left: auto; width: auto; opacity: 1;
    display: grid;
    grid-template-columns: 5.5rem minmax(0, 1fr) 11rem 7rem;
    gap: 1rem; align-items: baseline;
    border-top: 1px solid var(--hl-rule); padding: 0.7rem 0 0;
  }
  .hl-station__wk, .hl-station__intent, .hl-station__up, .hl-station__down {
    position: static; opacity: 1; transform: none; max-inline-size: none;
    margin: 0; padding: 0; border: 0;
  }
  /* Explicit placement: DOM order puts the outcome before the intention so the
     travelling layout can bottom align it, which in a table reads as the wrong
     column. The shared intention belongs second, where the eye starts. */
  .hl-station__wk     { grid-column: 1; grid-row: 1; }
  .hl-station__intent { grid-column: 2; grid-row: 1; }
  .hl-station__up     { grid-column: 3; grid-row: 1; }
  .hl-station__down   { grid-column: 4; grid-row: 1; }
  .hl-station__wk { width: auto; height: auto; clip-path: none;
    font-family: var(--hl-mono); font-size: 0.625rem; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--hl-gold); }
  .hl-station__cell { display: contents; }
  .hl-station__intent { font-size: 1rem; }
  .hl-station__down::before, .hl-station__down::after { display: none; }
  .hl-weeks {
    position: absolute; inset: auto 0 auto 0; top: 50%; transform: translateY(-50%);
    padding: 0 clamp(1rem, 3.4vw, 3rem); box-sizing: border-box;
  }
  .hl-lines, .hl-weekcopy { display: none; }
  .hl-summit { opacity: 0.35; }
  .hl-copy { transition: none; }
}
