/* ===========================================================================
   RTD Services · holiday lighting landing page · the page stylesheet
   ---------------------------------------------------------------------------
   v3 (2026-10-08). One page stylesheet plus motion.css (the scroll
   choreography, loaded right after this file). Sections, in cascade order
   (later wins):
     0. FONTS          self-hosted, latin-subset Fraunces + Inter (woff2)
     1. SCROLLCRAFT    the engine's taste floor (was scrollcraft.css, verbatim)
     2. PAGE           page styles: bar, CTA, cards, peak, steps band, rail
                       with quote cards, closing grid + footer band
     3. VIDEO HERO     the hero plate and its copy
     4. SPARKLE        (was sparkle.css, verbatim)
     5. REVIEW BITS    stars, outbound link, quote cards (from testimonials.css)
     6. V2 COMPONENTS  hours-aware actions, trust line, lead sheet, no-JS
     7. PHONE          every <= 860px rule, loaded last
   Bump the ?v= on the <link> in index.html (and html[data-v]) on every change.
   ========================================================================= */

/* ================================================================ 0. FONTS */
/* Fraunces (display) and Inter (text) as variable fonts, cut to the latin
   range and to the weights the page uses (Fraunces 300-400 with the full opsz
   axis, Inter 400-500). The roman Fraunces is preloaded in index.html. */
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 300 400; font-display: swap;
  src: url("fonts/fraunces-roman.woff2?v=20261008a") format("woff2");
}
@font-face {
  font-family: "Fraunces"; font-style: italic; font-weight: 300 400; font-display: swap;
  src: url("fonts/fraunces-italic.woff2?v=20261008a") format("woff2");
}
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 500; font-display: swap;
  src: url("fonts/inter.woff2?v=20261008a") format("woff2");
}

/* ========================================================== 1. SCROLLCRAFT */
/* ============================================================================
   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%);
  }
}

/* ================================================================= 2. PAGE */
/* ===========================================================================
   RTD Services · holiday lighting landing page
   Page styles only. scrollcraft.css owns the device mechanism; nothing here
   restyles .sc-stage, .sc-copy or any [data-sc-*] selector.
   ========================================================================= */

:root {
  --sc-canvas: #070B16;
  --sc-surface: #0F172A;
  --sc-ink: #F4EEE3;
  --sc-ink-soft: #A9A498;
  --sc-accent: #E7C077;
  --sc-accent-ink: #1A1408;

  --sc-font-display: "Fraunces", "Cormorant Garamond", Georgia, serif;
  --sc-font-text: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  --sc-measure: 60ch;
  --sc-shadow-color: 220 55% 3%;

  /* Plain values, not color-mix: a computed oklab() colour is unreadable to
     any tool that parses getComputedStyle().color as rgb, the contrast pass
     among them, and it reports every such line as near-black ink. */
  --sc-ink-mid: #DDD7CC;
  --ink-dim: #7C786F;
  --bar-h: 68px;
  /* The promo strip is gone; the property stays at zero so the calc() that
     positions the peak rail under the chrome still computes. */
  --promo-h: 0px;
}

html { background: var(--sc-canvas); }
body { font-weight: 400; }

/* Optical sizing is the reason this face is here. */
.display,
.display--xl,
.display--lg,
.display--md,
.display--sm {
  font-family: var(--sc-font-display);
  font-optical-sizing: auto;
  font-weight: 300;
  line-height: var(--sc-leading-tight);
  letter-spacing: var(--sc-track-snug);
  text-wrap: balance;
  margin: 0;
  color: var(--sc-ink);
}
.display--xl { font-size: clamp(2.6rem, 1.5rem + 3.1vw, 4.6rem); line-height: 1.02; letter-spacing: var(--sc-track-tight); }
.display--lg { font-size: clamp(2.2rem, 1.4rem + 2.2vw, 3.5rem); line-height: 1.06; }
.display--md { font-size: clamp(1.8rem, 1.3rem + 1.5vw, 2.6rem); }
.display--sm { font-size: clamp(1.25rem, 1.05rem + 0.7vw, 1.6rem); line-height: 1.2; }

.lede {
  font-size: var(--sc-t-lg);
  line-height: 1.5;
  color: var(--sc-ink-mid);
  max-width: 34ch;
  margin: 0;
}
.body {
  max-width: var(--sc-measure);
  color: var(--sc-ink-soft);
  line-height: 1.68;
  letter-spacing: 0.002em;
  text-wrap: pretty;
  margin: 0;
}
.body--turn { color: var(--sc-ink); }

.wrap { width: 100%; max-width: var(--sc-maxw); margin-inline: auto; padding-inline: var(--sc-gutter); }

.skip {
  position: fixed; top: 8px; left: 8px; z-index: 200;
  padding: 10px 14px; border-radius: var(--sc-r-sm);
  background: var(--sc-surface); color: var(--sc-ink);
  transform: translateY(-160%);
  transition: transform 160ms var(--sc-ease-out);
}
.skip:focus-visible { transform: translateY(0); }

/* ------------------------------------------------------------ chrome --- */

.bar {
  position: fixed; inset: 0 0 auto 0; z-index: var(--sc-z-chrome);
  height: var(--bar-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sc-5);
  padding-inline: clamp(1rem, 3vw, 2.5rem);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 300ms var(--sc-ease-out), border-color 300ms var(--sc-ease-out);
}
.bar.is-landed {
  background: color-mix(in oklab, var(--sc-canvas) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom-color: var(--sc-hairline);
}
/* Density under the chrome only: a band the height of the bar, gone by 130px.
   The mark and the phone sit on a lit tree at p 0 otherwise. */
.bar::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 130px; z-index: -1;
  pointer-events: none;
  background: linear-gradient(to bottom,
    color-mix(in oklab, var(--sc-canvas) 82%, transparent) 0%,
    color-mix(in oklab, var(--sc-canvas) 46%, transparent) 48%,
    transparent 100%);
  transition: opacity 300ms var(--sc-ease-out);
}
.bar.is-landed::before { opacity: 0; }
.bar__mark { display: flex; align-items: center; }
.bar__mark img { width: auto; height: 28px; filter: brightness(0) invert(1); opacity: 0.93; }
/* The early-bird line, centred in the space between the wordmark and the
   right cluster. One line, ellipsis rather than wrap or push. */
.bar__promo {
  flex: 1 1 auto; min-width: 0;
  margin: 0;
  text-align: center;
  font-size: 0.74rem; line-height: 1.2;
  letter-spacing: 0.01em;
  color: var(--sc-accent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bar__right { display: flex; align-items: center; gap: clamp(0.75rem, 1.6vw, 1.5rem); }
.bar__tel {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: var(--sc-t-sm); font-variant-numeric: tabular-nums;
  color: var(--sc-ink-mid);
  text-decoration: none;
  white-space: nowrap;
}
.bar__tel:hover { color: var(--sc-ink); text-decoration: underline; }
.bar__tel-glyph { opacity: 0.8; }

/* ------------------------------------------------------- the CTA ------- */
/* One label, two temperatures. Cool until the house is fully lit, then warm
   for the rest of the session. The change is the signature move, so it gets a
   real 600ms settle rather than a UI-speed flick. */

.cta {
  --cta-bg: transparent;
  --cta-ink: var(--sc-ink);
  --cta-edge: color-mix(in oklab, var(--sc-ink) 34%, transparent);
  --cta-glow: 0 0 0 0 transparent;
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap;
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-sm); font-weight: 500; letter-spacing: 0.01em; line-height: 1;
  padding: 0.85em 1.4em;
  border: 1px solid var(--cta-edge);
  border-radius: var(--sc-r-pill);
  background: var(--cta-bg);
  color: var(--cta-ink);
  cursor: pointer;
  box-shadow: var(--cta-glow);
  transition:
    background-color 600ms var(--sc-ease-out),
    border-color 600ms var(--sc-ease-out),
    color 600ms var(--sc-ease-out),
    box-shadow 600ms var(--sc-ease-out),
    transform 140ms var(--sc-ease-out);
}
.cta:hover { --cta-edge: color-mix(in oklab, var(--sc-ink) 60%, transparent); }
.cta:active { transform: translateY(1px); }
.cta.is-warm {
  --cta-bg: var(--sc-accent);
  --cta-ink: var(--sc-accent-ink);
  --cta-edge: var(--sc-accent);
  --cta-glow: 0 2px 10px -2px color-mix(in oklab, var(--sc-accent) 42%, transparent),
              0 8px 26px -10px color-mix(in oklab, var(--sc-accent) 34%, transparent);
}
.cta.is-warm:hover {
  --cta-bg: color-mix(in oklab, var(--sc-accent) 88%, white);
  --cta-edge: color-mix(in oklab, var(--sc-accent) 88%, white);
}
.cta--wide { width: 100%; padding-block: 1em; }
.cta--bar { padding: 0.75em 1.2em; }



/* ------------------------------------------------------------ stages --- */

.act { position: relative; }
.stage { background: var(--sc-canvas); }

.scene { position: absolute; inset: 0; overflow: clip; }
.scene__poster,
.scene__canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* The poster and the canvas are the same scene at DIFFERENT camera states, so
   cross-fading them prints a second, unscaled copy of every light. The canvas
   draws its first frame before it is revealed, then the two swap in one frame
   and the poster is taken out of the compositor entirely. */
.scene__canvas { opacity: 0; }
.scene__poster { opacity: 1; }
.scene.is-live .scene__canvas { opacity: 1; }
.scene.is-live .scene__poster { opacity: 0; visibility: hidden; }

/* --------------------------------------------------- 2 · recognition --- */

/* One testimonial, photo beside the quote. Compact on purpose: the hero
   should hand the visitor to the peak quickly, so this band stays around
   60vh and never fills the viewport. */
.act--recognition {
  background: var(--sc-canvas);
  padding-block: clamp(2.5rem, 5vw, 4.5rem);
}
.testimony {
  display: grid;
  grid-template-columns: minmax(0, 45%) minmax(0, 1fr);
  align-items: center;
  gap: clamp(1.75rem, 3.5vw, 3.5rem);
}
.testimony__photo {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 48vh;
  object-fit: cover;
  border-radius: 8px;
}
.testimony__fig { margin: 0; }
.testimony__quote {
  margin: 0;
  font-style: italic;
  max-width: 24ch;
}
.testimony__cap {
  margin-top: var(--sc-5);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sc-2) var(--sc-4);
}
.testimony__name {
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-sm);
  color: var(--sc-ink-mid);
}

@media (max-width: 860px) {
  .testimony { grid-template-columns: minmax(0, 1fr); }
  .testimony__photo { max-height: 38vh; }
}

/* The three service cards. Same type, padding and radius at every width;
   only the column count changes. Bodies are kept to equal lengths in copy and
   the grid stretches the boxes to one height. */
.cards {
  list-style: none;
  margin: 0 0 clamp(2.5rem, 5vw, 4rem);
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.85rem, 1.6vw, 1.5rem);
}
.card {
  display: flex; flex-direction: column; gap: 0.6rem;
  padding: 1.35rem 1.4rem 1.45rem;
  border: 1px solid rgb(231 192 119 / 0.26);
  border-radius: 12px;
  background: var(--sc-surface);
}
.card__title {
  margin: 0;
  font-family: var(--sc-font-display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: 1.4rem; line-height: 1.18;
  letter-spacing: var(--sc-track-snug);
  color: var(--sc-ink);
  text-wrap: balance;
}
.card__body {
  margin: 0;
  font-size: 0.9rem; line-height: 1.55;
  color: var(--sc-ink-mid);
  text-wrap: pretty;
}


/* ---------------------------------------------------------- 3 · peak --- */

/* The scene surface's own box. motion.css crops it (clip-path / a shorter
   box); the engine keeps measuring the stage, so nothing is rescaled. */
.peak__stage { position: absolute; inset: 0; }

.act--peak .stage { background: #050810; }

/* One opaque plate in the right gutter, top-aligned under the chrome and
   present for the whole pin: no cue, no fade-in. The scene stays full bleed
   underneath; a little overlap of the house is intended. */
.peak__rail {
  position: absolute; z-index: 20;
  left: auto;
  right: var(--sc-gutter);
  top: calc(var(--promo-h) + var(--bar-h) + clamp(1rem, 3vh, 2rem));
  width: min(25rem, 32vw);
  max-width: 25rem;
  background: var(--sc-canvas);
  border: 1px solid var(--sc-hairline);
  border-radius: 14px;
  padding: clamp(1.1rem, 2.4vh, 1.6rem) clamp(1.1rem, 1.6vw, 1.5rem);
  box-shadow: 0 20px 52px -24px rgb(0 0 0 / 0.85);
}
.peak__rail .lede { margin-top: var(--sc-4); }

/* --------------------------------------------------------- 4 · steps --- */
/* A band of its own: a lifted navy panel with a warm wash and gold hairlines,
   so the checklist reads as a separate beat. The spine runs down the number
   column; .steps__line (gold, drawn at full length) sits on it behind the
   numbers and motion.css reveals it with a scale from --steps-progress.
   Unlit steps are dimmed only when JS is on and motion is allowed; every
   other case shows them all lit. */

.act--steps {
  --steps-num: 3rem;
  --steps-band: #0D1830;
  position: relative;
  background:
    radial-gradient(90% 60% at 50% 0%, rgb(231 192 119 / 0.08), transparent 70%),
    var(--steps-band);
  border-block: 1px solid rgb(231 192 119 / 0.2);
  padding-block: clamp(4.5rem, 9vw, 8rem);
}
.steps__wrap { max-width: 48rem; }
.steps__head { text-align: center; }
.steps__head .display--lg { font-size: clamp(2.2rem, 1.4rem + 2.2vw, 3.4rem); }
.steps__sub {
  margin: 0.9rem auto 0;
  font-size: var(--sc-t-lg); line-height: 1.45;
  color: var(--sc-ink-mid);
}
.steps__track {
  position: relative;
  margin: clamp(2.75rem, 6vw, 4.5rem) 0 0;
}
/* The unlit spine: a faint track the gold line fills. */
.steps__track::before,
.steps__line {
  content: "";
  position: absolute; z-index: 0;
  left: calc(var(--steps-num) / 2 - 1px);
  top: calc(var(--steps-num) / 2);
  width: 2px;
  border-radius: 1px;
}
.steps__track::before {
  bottom: 0;
  background: rgb(231 192 119 / 0.16);
}
.steps__line {
  /* Full length here; motion.css scales it (page.js measures it unscaled). */
  height: calc(100% - var(--steps-num) / 2);
  background: linear-gradient(to bottom, #F1D49A, var(--sc-accent));
  box-shadow: 0 0 10px rgb(231 192 119 / 0.45);
}
.steps {
  list-style: none;
  margin: 0; padding: 0;
  position: relative; z-index: 1;
  display: grid;
  gap: clamp(2.25rem, 5vw, 3.5rem);
}
.step {
  display: grid;
  grid-template-columns: var(--steps-num) minmax(0, 1fr);
  column-gap: clamp(1.1rem, 2.5vw, 1.75rem);
  align-items: start;
}
.step__num {
  grid-row: span 2;
  display: grid; place-items: center;
  width: var(--steps-num); height: var(--steps-num);
  border-radius: 50%;
  border: 1px solid var(--sc-accent);
  background: var(--steps-band);
  box-shadow: 0 0 0 6px var(--steps-band), 0 0 22px -4px rgb(231 192 119 / 0.5);
  font-family: var(--sc-font-display);
  font-optical-sizing: auto;
  font-weight: 400; font-size: 1.35rem; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--sc-accent);
}
.step__title {
  margin: 0.45rem 0 0.4rem;
  font-family: var(--sc-font-display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: clamp(1.4rem, 1.15rem + 0.8vw, 1.85rem); line-height: 1.15;
  letter-spacing: var(--sc-track-snug);
  color: #F3DDB0;
}
.step__body {
  margin: 0;
  max-width: 46ch;
  font-size: var(--sc-t-base); line-height: 1.6;
  color: var(--sc-ink-mid);
  text-wrap: pretty;
}
.steps__finale {
  margin: clamp(3.5rem, 8vw, 5.5rem) 0 0;
  text-align: center;
  font-family: var(--sc-font-display);
  font-optical-sizing: auto;
  font-weight: 300; font-style: italic;
  font-size: clamp(2.3rem, 1.3rem + 3.6vw, 4.4rem);
  line-height: 1.05;
  letter-spacing: var(--sc-track-tight);
  color: var(--sc-accent);
  text-wrap: balance;
}
.step__num, .step__title, .step__body, .steps__finale {
  transition: opacity 480ms var(--sc-ease-out), color 480ms var(--sc-ease-out),
              border-color 480ms var(--sc-ease-out), box-shadow 480ms var(--sc-ease-out);
}
/* Unlit (JS on, motion allowed, the script has not reached it yet). */
@media (prefers-reduced-motion: no-preference) {
  html.js:not(.is-static) .step:not(.is-lit) .step__num {
    opacity: 0.4;
    border-color: rgb(231 192 119 / 0.4);
    box-shadow: 0 0 0 6px var(--steps-band);
  }
  html.js:not(.is-static) .step:not(.is-lit) .step__title { opacity: 0.4; color: var(--sc-ink); }
  html.js:not(.is-static) .step:not(.is-lit) .step__body { opacity: 0.45; }
  html.js:not(.is-static) .steps__finale:not(.is-lit) { opacity: 0.22; color: var(--sc-ink); }
}
/* Everything lit, line full: no JS, static mode, reduced motion. */
html:not(.js) .steps__line,
html.is-static .steps__line { height: calc(100% - var(--steps-num) / 2); }
@media (prefers-reduced-motion: reduce) {
  .steps__line { height: calc(100% - var(--steps-num) / 2) !important; }
  .step__num, .step__title, .step__body, .steps__finale { transition: none; }
}
/* --------------------------------------------------------- 5 · work --- */
/* A free horizontal scroller at every width: no pin, no wheel capture. Photo
   items and quote cards share one height so the rail holds a straight line. */

.act--trust {
  --rail-h: clamp(18rem, 44vh, 27rem);
  background: var(--sc-canvas);
  padding-block: clamp(4rem, 8vw, 7rem) clamp(3rem, 6vw, 5rem);
}
.trust__top {
  display: grid; gap: 0.6rem; justify-items: start;
  padding-inline: var(--sc-gutter);
  margin-bottom: clamp(1.5rem, 3.5vw, 2.5rem);
}
.trust__all { margin: 0; }
.trust__all .tlink { font-size: var(--sc-t-sm); color: var(--sc-ink-mid); }
.rail {
  list-style: none;
  margin: 0;
  display: flex; align-items: stretch;
  gap: clamp(0.75rem, 1.4vw, 1.25rem);
  padding: 0 var(--sc-gutter) 1rem;
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--sc-gutter);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgb(244 238 227 / 0.22) transparent;
}
.rail__item {
  flex: 0 0 auto;
  width: 26vw;
  height: var(--rail-h);
  scroll-snap-align: start;
}
.rail__item img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: var(--sc-r-sm);
  filter: saturate(0.78) sepia(0.1) brightness(0.94) contrast(1.02);
  -webkit-user-drag: none;
}
.rail__quote { width: clamp(20rem, 24vw, 26rem); }
/* --------------------------------------------------------- 6 · close --- */
/* Two columns at 861px and up: the call to action on the illustrated frame
   (image + snow canvas live inside .close__cta only), then the fine print in
   a solid band. Phones stack them (PHONE section). */

.act--close { background: var(--sc-canvas); }
.close__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.75fr) minmax(19rem, 1fr);
  min-height: min(88vh, 52rem);
}
.close__cta {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: flex-start;
  padding: clamp(5rem, 13vh, 8rem) clamp(2rem, 5vw, 5rem) clamp(3rem, 8vh, 5rem);
  background: #050810;
}
.close__art { position: absolute; inset: 0; z-index: -1; }
.close__ground { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%; z-index: 0; }
/* Snow sits on the frame, under the copy. Painted by footer-snow.js only
   while the section is on screen. */
.close__snow { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }
.is-static .close__snow { display: none; }
@media (prefers-reduced-motion: reduce) { .close__snow { display: none; } }
/* Density only where the type is: the dark sky band at the top of the frame. */
.close__art::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom,
    rgb(7 11 22 / 0.94) 0%, rgb(7 11 22 / 0.78) 30%, rgb(7 11 22 / 0.18) 60%, transparent 76%);
}
.close__copy {
  position: relative; z-index: 1;
  display: grid; justify-items: start; gap: var(--sc-5);
  max-width: 38rem;
}
.close__copy .display--lg { font-size: clamp(2.1rem, 1rem + 2.5vw, 3.5rem); text-shadow: 0 2px 18px rgb(0 0 0 / 0.5); }
.close__copy .lede { max-width: 32ch; color: var(--sc-ink); }
.close__act { margin: 0.35rem 0 0; }
.close__act .cta { min-height: 56px; font-size: 1rem; padding-inline: 1.6em; }

/* The fine print: a solid band, never on the illustration. */
.foot--band {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  align-content: center;
  gap: 2rem clamp(1.5rem, 2.5vw, 2.5rem);
  padding: clamp(3rem, 8vh, 5rem) clamp(1.75rem, 3vw, 3rem);
  background: #0A1020;
  border-left: 1px solid rgb(231 192 119 / 0.16);
  font-size: 0.86rem; line-height: 1.6;
  color: #A39E94;
}
.foot__col { display: grid; gap: 0.9rem; align-content: start; }
.foot p { margin: 0; }
.foot__name {
  font-family: var(--sc-font-display); font-optical-sizing: auto;
  font-weight: 400; font-size: 1.25rem; line-height: 1.2;
  color: var(--sc-ink);
}
.foot__links { display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; }
.foot a { color: var(--sc-ink-mid); text-decoration-color: rgb(244 238 227 / 0.3); }
.foot a:hover { color: var(--sc-ink); text-decoration-color: currentColor; }

/* ------------------------------------------------- fallbacks + motion --- */

.is-static .scene__canvas { display: none; }
.is-static .scene__poster { opacity: 1; visibility: visible; }
.is-static [data-sc-cue] { opacity: 1 !important; transform: none !important; }
.is-static [data-sc-in] > *, .is-static [data-sc-in] { opacity: 1 !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .cta { transition-duration: 1ms; }
}
/* =========================================================== 3. VIDEO HERO */
/* V2: a single video plate. Only snow has independent depth or drift. */
.video-hero { height: 400vh; }
.video-hero__stage { isolation: isolate; }
.video-hero__media,
.video-hero__snow,
.video-hero__shade,
.video-hero__veil { position: absolute; inset: 0; width: 100%; height: 100%; }
.video-hero__media { object-fit: cover; object-position: 50% 50%; background: #070b16; }
#hero-video { opacity: 0; }
.is-video-ready #hero-video { opacity: 1; }
.is-video-ready .video-hero__poster { visibility: hidden; }
.video-hero__snow { z-index: 1; pointer-events: none; }
.video-hero__shade {
  z-index: 2; pointer-events: none;
  opacity: var(--video-copy-opacity, 1);
  background: linear-gradient(270deg, rgba(7,11,22,.92), rgba(7,11,22,.72) 26%, rgba(7,11,22,.12) 62%, transparent 74%);
}
.video-hero__copy {
  position: absolute; z-index: 4;
  width: min(35%, 31rem); right: 5%; top: max(110px, 18vh);
}
.video-hero__copy > * + * { margin-top: 1.35rem; }
.video-hero__copy .display--xl { font-size: clamp(2.1rem, 3vw, 3.7rem); }
.video-hero__copy .lede { font-size: clamp(.95rem, 1.15vw, 1.1rem); max-width: 35ch; }

/* The exit veil dims only the film: it sits above the media, snow and shade
   but below .video-hero__copy (z-index 4), so the H1 and the subhead stay at
   full strength through the crossfade. */
.video-hero__veil { z-index: 3; background: #070b16; opacity: 0; pointer-events: none; }
#hero.is-video-static { height: 100svh !important; min-height: 620px; }
#hero.is-video-static .video-hero__stage { position: relative; height: 100%; min-height: inherit; }
.video-hero a:focus-visible, .video-hero button:focus-visible { outline: 2px solid #e7c077; outline-offset: 5px; }
/* Phone rules for the hero live in the PHONE section below. */

@media (prefers-reduced-motion: reduce) {
  #hero { height: 100svh !important; min-height: 620px; }
  .video-hero__snow { display: none; }
}

/* ============================================================== 4. SPARKLE */
/* ===========================================================================
   SPARKLE CURSOR
   ---------------------------------------------------------------------------
   A fixed, full-viewport canvas that draws the snow-sparkle trail behind the
   pointer. sparkle.js creates the element; this file only places it.

   z-index: above the page chrome (--sc-z-chrome: 60) so the trail reads over
   the header and the footer, and below the lead <dialog>,
   which the browser promotes into the top layer and which therefore always
   wins regardless of the number here.
   =========================================================================== */

.sparkle-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 90;
  pointer-events: none;
  /* The canvas is transparent; never let it paint a ground of its own. */
  background: transparent;
  /* Keep it off the compositor's critical path and out of hit testing. */
  contain: strict;
}

/* Belt and braces: if the stylesheet loads on a device or in a mode where the
   trail has no business running, the canvas is not drawn even if it exists. */
@media (prefers-reduced-motion: reduce) {
  .sparkle-canvas { display: none; }
}
@media (hover: none), (pointer: coarse) {
  .sparkle-canvas { display: none; }
}
.is-static .sparkle-canvas { display: none; }

/* ========================================================= 5. REVIEW BITS */
/* --------------------------------------------------------- the stars --- */

.tstars {
  color: var(--sc-accent);
  letter-spacing: 0.14em;
  font-size: 0.95em;
  line-height: 1;
  white-space: nowrap;
}

/* ------------------------------------------------- the outbound link --- */

/* Quiet by default, underlined on hover, ringed on keyboard focus. Never
   purple: :visited is pinned to the same ink as :link. */
.tlink,
.tlink:link,
.tlink:visited {
  color: var(--sc-ink-soft);
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-xs);
  letter-spacing: 0.02em;
  text-decoration: none;
  border-radius: 3px;
  white-space: nowrap;
  transition: color 160ms ease;
}
.tlink:hover,
.tlink:focus-visible {
  color: var(--sc-accent);
  text-decoration: underline;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}
.tlink:focus-visible {
  outline: 2px solid var(--sc-accent);
  outline-offset: 3px;
}
/* --------------------------------------------------- the quote card --- */
/* A plaque hung between two frames on the same wall: same dark ground, same
   hairline, same height as the photographs (the rail item sets the height).
   The estimate button stays the loudest thing on the page. */
.quote-card {
  margin: 0;
  height: 100%;
  display: flex; flex-direction: column; justify-content: space-between;
  gap: var(--sc-4);
  padding: clamp(1.4rem, 2.4vh, 2rem) clamp(1.4rem, 1.8vw, 2rem);
  background: var(--sc-surface);
  border: 1px solid var(--sc-hairline);
  border-radius: var(--sc-r-sm);
  box-shadow: inset 0 1px 0 rgb(244 238 227 / 0.05);
}
.quote-card__quote {
  /* Auto block margins centre the quote in whatever space the caption leaves. */
  margin: auto 0;
  font-family: var(--sc-font-display);
  font-optical-sizing: auto;
  font-weight: 300;
  font-size: clamp(1.05rem, 0.92rem + 0.45vw, 1.4rem);
  line-height: 1.34;
  letter-spacing: var(--sc-track-snug);
  color: var(--sc-ink);
  text-wrap: pretty;
}
.quote-card__cap {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 0.4rem;
  padding-top: clamp(0.8rem, 1.6vh, 1.1rem);
  border-top: 1px solid var(--sc-hairline);
}
.quote-card__name {
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide);
  text-transform: uppercase;
  color: var(--sc-ink-soft);
}
@media (prefers-reduced-motion: reduce) {
  .tlink { transition: none; }
}

/* ======================================================== 6. V2 COMPONENTS */

/* ===========================================================================
   LANDING PAGE V2 (2026-10-07): hours-aware actions, trust line, the lead
   sheet, and the no-JS fallback. Desktop and phone; the phone-only
   overrides live in the PHONE section at the end of this file.
   ========================================================================= */

/* A class display rule outranks the UA's [hidden] { display: none }. */
[hidden] { display: none !important; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------- hero copy (v3) --- */
/* H1 + subhead only. Two classes deep so the margin:0 reset on .lede holds. */
.video-hero .video-hero__copy > * { margin-bottom: 0; }
.video-hero .video-hero__copy > * + * { margin-top: 1rem; }
.video-hero .video-hero__copy > .hero__sub { margin-top: 0.9rem; color: var(--sc-ink); }

/* ------------------------------------------- the two hours-aware actions --- */
/* Spec §5. Open (Mon-Fri 8-5 Central): "Call" is filled gold and comes first.
   Closed (or "auto", i.e. the hours are unknown): the estimate is filled and
   comes first. Pure CSS off html[data-hours], so the server-stamped first paint
   is right with JS off; lead.js only keeps the attribute current. */
.duo { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 0; }
.cta--call, .cta--est { min-height: 48px; padding-inline: 1.35em; text-decoration: none; }
html[data-hours="open"] .cta--call,
html:not([data-hours="open"]) .cta--est,
.cta--go {
  --cta-bg: var(--sc-accent);
  --cta-ink: var(--sc-accent-ink);
  --cta-edge: var(--sc-accent);
  --cta-glow: 0 2px 10px -2px color-mix(in oklab, var(--sc-accent) 42%, transparent),
              0 8px 26px -10px color-mix(in oklab, var(--sc-accent) 34%, transparent);
}
html[data-hours="open"] .cta--call:hover,
html:not([data-hours="open"]) .cta--est:hover,
.cta--go:hover:not(:disabled) {
  --cta-bg: color-mix(in oklab, var(--sc-accent) 88%, white);
  --cta-edge: color-mix(in oklab, var(--sc-accent) 88%, white);
}
/* The outline (secondary) action needs a ground over a photograph. */
html[data-hours="open"] .cta--est,
html:not([data-hours="open"]) .cta--call {
  --cta-bg: color-mix(in oklab, var(--sc-canvas) 55%, transparent);
  --cta-edge: color-mix(in oklab, var(--sc-ink) 46%, transparent);
}
html:not([data-hours="open"]) .duo .cta--est { order: -1; }

html:not([data-hours="open"]) .lead__aside--open { display: none; }

/* --------------------------------------------------------- trust line --- */
.trustline {
  list-style: none;
  margin: clamp(1.75rem, 4vw, 2.75rem) 0 0;
  padding: clamp(1rem, 2vw, 1.25rem) 0 0;
  border-top: 1px solid var(--sc-hairline);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.4rem 0;
  font-size: var(--sc-t-xs);
  letter-spacing: var(--sc-track-wide);
  text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.trustline li + li::before { content: "·"; margin: 0 0.8rem; color: var(--sc-accent); }
.trustline__rating { color: var(--sc-ink); text-decoration: none; white-space: nowrap; }
.trustline__rating:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.trustline__rating .tstars { letter-spacing: 0; margin-right: 0.15em; }

/* ------------------------------------------------------- the lead sheet --- */
/* A <dialog>: a centred modal at 861px and up, a bottom sheet below (PHONE
   section). The panel scrolls inside itself; the stage's action row is sticky
   to the panel's bottom edge, so the submit button stays reachable with the
   keyboard up. lead.js sets data-stage / data-method on the dialog. */
.sheet {
  border: 0; padding: 0; margin: auto;
  background: transparent; color: var(--sc-ink);
  width: 100%;
  max-width: min(30rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  overflow: visible;
}
.sheet::backdrop { background: color-mix(in srgb, #03060D 74%, transparent); backdrop-filter: blur(3px); }
.sheet__panel {
  position: relative;
  max-height: inherit;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background: var(--sc-surface);
  border: 1px solid var(--sc-hairline);
  border-radius: var(--sc-r-lg);
  box-shadow: var(--sc-e3), var(--sc-edge);
  padding: 0.9rem clamp(1.25rem, 3vw, 2rem) clamp(1.25rem, 3vw, 1.75rem);
}
.sheet[open] { animation: sheet-in 220ms var(--sc-ease-out); }
@keyframes sheet-in { from { opacity: 0; transform: translateY(10px) scale(0.985); } }

.sheet__top { display: flex; align-items: center; justify-content: space-between; min-height: 44px; }
.sheet__dots { display: flex; gap: 6px; margin: 0; padding: 0; list-style: none; }
.sheet__dots li {
  width: 22px; height: 4px; border-radius: 2px;
  background: color-mix(in oklab, var(--sc-ink) 18%, transparent);
  transition: background-color 240ms var(--sc-ease-out);
}
.sheet[data-stage="1"] .sheet__dots li:nth-child(-n+1),
.sheet[data-stage="2"] .sheet__dots li:nth-child(-n+2),
.sheet[data-stage="3"] .sheet__dots li,
.sheet[data-stage="4"] .sheet__dots li { background: var(--sc-accent); }
.sheet__close {
  display: grid; place-items: center;
  width: 44px; height: 44px; margin-right: -10px;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--sc-ink-soft); cursor: pointer;
}
.sheet__close:hover { color: var(--sc-ink); background: color-mix(in oklab, var(--sc-ink) 8%, transparent); }

.lead { margin: 0; display: grid; gap: var(--sc-4); }
.lead__title { margin: 0.25rem 0 0; }
.lead__stage { margin: 0; padding: 0; border: 0; min-width: 0; display: grid; gap: var(--sc-4); }
.lead__q {
  padding: 0; margin: 0 0 0.25rem;
  font-family: var(--sc-font-display); font-optical-sizing: auto;
  font-weight: 400; font-size: 1.3rem; line-height: 1.25;
  color: var(--sc-ink);
}
.lead__sub { margin: 0; color: var(--sc-ink-mid); font-size: var(--sc-t-base); line-height: 1.5; }
.lead__aside { margin: 0; font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }
.lead__aside a { color: var(--sc-ink); display: inline-block; padding-block: 0.6rem; }
.lead__done { display: grid; gap: var(--sc-3); padding: 0.25rem 0 0.5rem; }
.lead__done:focus { outline: none; }

.lead__choices { display: grid; gap: 0.75rem; }
.lead__choice {
  min-height: 56px; width: 100%;
  border: 1px solid var(--sc-hairline-strong);
  border-radius: var(--sc-r-md);
  background: color-mix(in oklab, var(--sc-canvas) 60%, transparent);
  color: var(--sc-ink);
  font-size: 1.05rem; font-weight: 500;
  cursor: pointer;
  transition: border-color 160ms var(--sc-ease-out), background-color 160ms var(--sc-ease-out);
}
.lead__choice:hover, .lead__choice[aria-pressed="true"] {
  border-color: color-mix(in oklab, var(--sc-accent) 85%, transparent);
  background: color-mix(in oklab, var(--sc-accent) 16%, transparent);
}
.lead__radio { display: flex; align-items: center; gap: 0.6rem; min-height: 48px; font-size: 1rem; }
.lead__radio input { width: 20px; height: 20px; }

.lead__field { display: grid; gap: 0.4rem; min-width: 0; }
.lead__label {
  font-size: var(--sc-t-xs); letter-spacing: var(--sc-track-wide); text-transform: uppercase;
  color: var(--sc-ink-soft);
}
.lead__opt { text-transform: none; letter-spacing: 0; color: var(--ink-dim); }
.lead__box { position: relative; display: block; }
.lead input[type="text"], .lead input[type="tel"], .lead input[type="email"] {
  width: 100%;
  min-height: 52px;
  /* 16px minimum: anything smaller and iOS zooms the page on focus. */
  font-size: 16px;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--sc-hairline-strong);
  border-radius: var(--sc-r-sm);
  background: color-mix(in oklab, var(--sc-canvas) 70%, transparent);
  color: var(--sc-ink);
  transition: border-color 160ms var(--sc-ease-out), box-shadow 160ms var(--sc-ease-out);
}
.lead__box input { padding-right: 2.75rem; }
.lead input::placeholder { color: #5C5952; }
.lead input:hover { border-color: color-mix(in oklab, var(--sc-ink) 34%, transparent); }
.lead input:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 1px; }
/* Valid: green border and a check inside the field (spec §3). */
.lead__ok {
  position: absolute; right: 0.85rem; top: 50%;
  translate: 0 -50%; scale: 0.6;
  color: #5ED38B; opacity: 0;
  transition: opacity 180ms var(--sc-ease-out), scale 180ms var(--sc-ease-out);
  pointer-events: none;
}
.lead__box.is-valid input { border-color: #5ED38B; box-shadow: inset 0 0 0 1px #5ED38B; }
.lead__box.is-valid .lead__ok { opacity: 1; scale: 1; }
.lead__msg { font-size: var(--sc-t-xs); color: #F2B8A2; }
.lead__msg:empty { display: none; }
.lead__check {
  display: flex; align-items: flex-start; gap: 0.65rem;
  margin-top: 0.5rem; min-height: 44px;
  font-size: var(--sc-t-sm); line-height: 1.45; color: var(--sc-ink-soft);
  cursor: pointer;
}
.lead__check input { flex: 0 0 auto; width: 22px; height: 22px; margin: 0.05rem 0 0; }
.lead__addr { display: grid; grid-template-columns: minmax(0, 1fr) 7.5rem; gap: var(--sc-3); }
.lead__error { margin: 0; font-size: var(--sc-t-sm); line-height: 1.45; color: #F2B8A2; }
.lead__retry {
  margin-left: 0.4rem; padding: 0.55rem 0.9rem; min-height: 44px;
  border: 1px solid currentColor; border-radius: var(--sc-r-pill);
  background: transparent; color: inherit; font-size: var(--sc-t-sm); cursor: pointer;
}
.lead__actions {
  display: grid; gap: 0.25rem;
  position: sticky; bottom: -1px;   /* sticks to the panel's bottom edge */
  margin-inline: -0.25rem; padding: 0.75rem 0.25rem 0.25rem;
  background: var(--sc-surface);
}
.cta--go { min-height: 52px; font-size: 1rem; }
.cta--go:disabled { opacity: 0.42; cursor: not-allowed; box-shadow: none; }
.cta--go[aria-busy="true"] { opacity: 0.75; cursor: progress; }
.lead__skip {
  min-height: 44px; border: 0; background: none;
  color: var(--sc-ink-soft); font-size: var(--sc-t-sm);
  text-decoration: underline; text-underline-offset: 0.2em; cursor: pointer;
}
/* Honeypot: off screen, out of the tab order, ignored by screen readers. */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* Which stage shows (JS on). One question at a time. */
html.js .lead__stage { display: none; }
html.js .sheet[data-stage="1"] .lead__stage[data-stage="1"],
html.js .sheet[data-stage="2"] .lead__stage[data-stage="2"],
html.js .sheet[data-stage="3"] .lead__stage[data-stage="3"],
html.js .sheet[data-stage="4"] .lead__done { display: grid; }
html.js .sheet[data-stage="4"] .lead,
html.js .sheet:not([data-stage="1"]) .lead__title { display: none; }
.sheet[data-method="email"] [data-for="call"],
.sheet[data-method="call"] [data-for="email"] { display: none; }
/* Prefilled address (server-side, never in the page): no address inputs. */
html[data-addr-prefill] .lead__addr,
html[data-addr-prefill] .lead__q--ask,
html:not([data-addr-prefill]) .lead__q--known,
html:not([data-addr-prefill]) .lead__note { display: none; }
html.js .nojs-only { display: none !important; }
html:not(.js) .js-only { display: none !important; }

html.sheet-open { overflow: hidden; }
/* Anchor targets (#estimate, #thanks) clear the fixed top bar. */
.sheet, #thanks { scroll-margin-top: calc(var(--bar-h) + 1rem); }

/* ------------------------------------------------------ no-JS fallback --- */
/* Without JS: content visible from the start, stages unpinned, and the lead
   form rendered inline as an ordinary section with every field showing. */
html:not(.js) [data-sc-cue],
html:not(.js) [data-sc-in],
html:not(.js) [data-sc-stagger] > * { opacity: 1 !important; transform: none !important; }
html:not(.js) [data-sc-stage] { position: relative; min-height: 100vh; min-height: 100svh; }
html:not(.js) #hero-video, html:not(.js) .video-hero__snow { display: none; }
html:not(.js) .sheet:not([open]) {
  display: block; position: static;
  max-width: 34rem; max-height: none;
  margin: 0 auto; padding: var(--sc-section) var(--sc-gutter);
}
html:not(.js) .sheet__panel { max-height: none; overflow: visible; }
html:not(.js) .sheet__top { display: none; }
html:not(.js) .lead__stage[data-stage="1"] .lead__q { font-size: 1.1rem; }
html:not(.js) #thanks:not(:target) { display: none; }
html:not(.js) #thanks:target ~ .lead { display: none; }

@media (prefers-reduced-motion: reduce) {
  .sheet[open] { animation: none; }
  .lead__ok, .lead input, .sheet__dots li { transition: none; }
}
/* ================================================================ 7. PHONE */

/* ===========================================================================
   PHONE (<= 860px), v3 (2026-10-08)
   ---------------------------------------------------------------------------
   One clean column in DOM order: hero -> cards + review + trust line -> peak
   -> steps band -> rail with quotes -> closing CTA -> footer band. The rules
   below are the static stacked layout (what shows with JS off and with
   reduced motion). motion.css pins #hero and #peak on top of this when motion
   is allowed, so the generic flow rules here stay generic on purpose.

   Everything except the .mobile-bar / .bar__lead base declarations is behind
   a max-width query, so the desktop page is untouched by this section.
   ========================================================================= */

/* The bottom bar does not exist on the desktop page. */
.mobile-bar { display: none; }
.lbl-short { display: none; }

/* The phone bar's wordmark + promo wrapper. `display: contents` keeps the
   desktop bar's flex children exactly as they were. */
.bar__lead { display: contents; }

/* Between 861 and 959px the early-bird line would truncate; whole line or none. */
@media (min-width: 861px) and (max-width: 959px) {
  .bar__promo { display: none; }
}

@media (max-width: 860px) {

  :root {
    --bar-h: 60px;
    /* Bottom bar: 48px targets + 16px padding + the home indicator. */
    --mbar-h: calc(65px + env(safe-area-inset-bottom, 0px));
    /* Hero photo height: most of the first screen, never taller than 4:5. */
    --hero-img-h: min(54svh, 125vw);
  }

  /* --------------------------------------------------------- top bar --- */
  /* Wordmark left, the promo right in a smaller size: one line if it fits,
     otherwise two balanced lines, never touching the mark. */
  .bar {
    height: 60px;
    padding-block: 8px;
    padding-inline: clamp(1rem, 4vw, 1.5rem);
    gap: 0.6rem;
  }
  .bar__lead { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-width: 0; flex: 1 1 auto; }
  .bar__mark { flex: 0 0 auto; min-height: 44px; }
  .bar__mark img { height: 20px; }
  .bar__promo {
    flex: 0 1 auto;
    max-width: 14.5rem;
    text-align: right;
    font-size: 0.7rem;
    line-height: 1.3;
    letter-spacing: 0.01em;
    white-space: normal; overflow: visible; text-overflow: clip;
    text-wrap: balance;
  }
  .bar__right { display: none; }

  /* ------------------------------------------------------ bottom bar --- */
  .mobile-bar {
    position: fixed; left: 0; right: 0; bottom: 0;
    z-index: var(--sc-z-chrome);
    display: grid; grid-template-columns: 1fr 1fr; align-items: stretch;
    gap: 0.5rem;
    padding: 8px clamp(0.75rem, 4vw, 1.25rem);
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    background: color-mix(in oklab, var(--sc-canvas) 94%, transparent);
    border-top: 1px solid var(--sc-hairline);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }
  .mobile-bar .cta {
    min-width: 0; min-height: 48px;
    gap: 0.45rem;
    padding-inline: 0.5rem;
    font-size: clamp(0.8rem, 3.6vw, 0.95rem);
  }
  .mobile-bar .bar__tel-glyph { opacity: 0.9; flex: 0 0 auto; }
  /* Closed: the estimate leads and takes the wider column; "Call" shrinks. */
  html:not([data-hours="open"]) .mobile-bar { grid-template-columns: 1.65fr 1fr; }
  html:not([data-hours="open"]) .mobile-bar__est { order: -1; }
  html:not([data-hours="open"]) .mobile-bar__call .lbl-long { display: none; }
  html:not([data-hours="open"]) .mobile-bar__call .lbl-short { display: inline; }
  /* After a request: "Request sent ✓ · Call". */
  .mobile-bar__sent {
    display: none; margin: 0;
    align-items: center; justify-content: center;
    min-height: 48px;
    font-size: clamp(0.85rem, 3.7vw, 0.98rem); font-weight: 500;
    color: var(--sc-ink);
  }
  html.lead-sent .mobile-bar { grid-template-columns: 1.4fr 1fr; }
  html.lead-sent .mobile-bar__est { display: none; }
  html.lead-sent .mobile-bar__sent { display: flex; order: -1; }
  html.lead-sent .mobile-bar__call .lbl-long { display: none; }
  html.lead-sent .mobile-bar__call .lbl-short { display: inline; }
  /* Hidden while the sheet is open (the sheet has its own actions). */
  html.sheet-open .mobile-bar { display: none; }


  /* ------------------------------------------------------ one column --- */
  main { display: flex; flex-direction: column; padding-bottom: var(--mbar-h); }

  /* No scroll choreography in the static layout: every act is a plain block.
     motion.css overrides these for #hero and #peak when motion is allowed. */
  .act, #hero { height: auto !important; min-height: 0; }
  [data-sc-stage] { position: relative; height: auto; min-height: 0; overflow: visible; }
  [data-sc-cue] { opacity: 1 !important; transform: none !important; }

  /* ------------------------------------------------------------ hero --- */
  .video-hero__stage { display: flex; flex-direction: column; background: var(--sc-canvas); }
  .video-hero__snow, .video-hero__veil { display: none; }
  .video-hero__poster {
    position: relative; inset: auto;
    width: 100%; height: var(--hero-img-h);
    object-fit: cover; object-position: 50% 30%;
  }
  /* The film slot sits exactly over the poster (opacity 0 until
     .is-video-ready); no bytes are fetched until video-hero.js sets a src. */
  #hero-video { inset: 0 0 auto 0; height: var(--hero-img-h); object-position: 50% 30%; }
  /* Text over a dark gradient: the photo fades into the canvas under the copy. */
  .video-hero__shade {
    inset: 0 0 auto 0; height: var(--hero-img-h);
    opacity: 1;
    background: linear-gradient(to bottom,
      rgb(7 11 22 / 0.55) 0%, rgb(7 11 22 / 0) 20%,
      rgb(7 11 22 / 0) 42%, rgb(7 11 22 / 0.78) 72%, var(--sc-canvas) 96%);
  }
  .video-hero__copy {
    position: relative; inset: auto; z-index: 4;
    width: auto;
    margin-top: calc(-1 * clamp(6.5rem, 30vw, 8.5rem));
    padding: 0 var(--sc-gutter) clamp(1.5rem, 6vw, 2.25rem);
  }
  .video-hero__copy .display--xl {
    font-size: clamp(1.9rem, 8vw, 2.6rem);
    line-height: 1.06;
    max-width: 17ch;
    text-shadow: 0 2px 18px rgb(0 0 0 / 0.55);
  }
  .video-hero .video-hero__copy > .hero__sub {
    margin-top: 0.7rem;
    font-size: clamp(1.02rem, 4.4vw, 1.2rem);
    font-family: var(--sc-font-display); font-style: italic; font-weight: 300;
    max-width: 30ch;
  }

  /* ------------------------------------- cards + review + trust line --- */
  .act--recognition { padding-block: clamp(2rem, 8vw, 3rem) clamp(2.5rem, 9vw, 3.25rem); }
  .cards { grid-template-columns: minmax(0, 1fr); gap: 0.75rem; margin-bottom: clamp(2.25rem, 9vw, 3rem); }
  .testimony { grid-template-columns: 1fr; gap: 1rem; }
  .testimony__photo {
    /* width/height attributes would otherwise win over aspect-ratio. */
    height: auto; aspect-ratio: 16 / 9; max-height: none; border-radius: 8px;
  }
  .testimony__quote { max-width: none; font-size: clamp(1.35rem, 6vw, 1.75rem); line-height: 1.24; }
  .testimony__cap { margin-top: var(--sc-4); gap: 0.2rem 0.9rem; }
  .testimony__cap .tlink { display: inline-flex; align-items: center; min-height: 44px; }
  .trustline { display: grid; gap: 0.15rem; margin-top: 1.25rem; font-size: 0.72rem; letter-spacing: 0.06em; }
  .trustline li { display: flex; align-items: center; min-height: 28px; }
  /* One item per line, each with a gold dot instead of the desktop "·". */
  .trustline li::before,
  .trustline li + li::before { content: ""; flex: 0 0 auto; width: 5px; height: 5px; margin: 0 0.6rem 0 0; border-radius: 50%; background: var(--sc-accent); }
  .trustline__rating { display: inline-flex; align-items: center; min-height: 44px; }

  /* ---------------------------------------- "From simple to complete" --- */
  .act--peak .stage {
    display: flex; flex-direction: column;
    padding: clamp(2.5rem, 10vw, 3.5rem) 0 0;
    background: var(--sc-canvas);
  }
  .act--peak .peak__stage { position: relative; inset: auto; }
  /* The portrait poster (media/peak-m/poster-lit.webp, 810x1080). */
  .act--peak .scene { position: relative; inset: auto; width: 100%; aspect-ratio: 3 / 4; }
  .peak__rail {
    position: relative; inset: auto; z-index: 2;
    width: auto; max-width: none;
    margin: -2.25rem var(--sc-gutter) 0;
    padding: 1.1rem 1.15rem 1rem;
    border-radius: 12px;
  }
  .peak__rail .display--md { font-size: clamp(1.5rem, 6.4vw, 1.9rem); }
  .peak__rail .lede { margin-top: 0.55rem; font-size: clamp(0.9rem, 3.8vw, 1rem); max-width: none; }

  /* ------------------------------------------------------ steps band --- */
  .act--steps { --steps-num: 2.5rem; padding-block: clamp(3.25rem, 13vw, 4.5rem); margin-top: clamp(2.5rem, 10vw, 3.5rem); }
  .steps__head .display--lg { font-size: clamp(1.8rem, 7.6vw, 2.4rem); }
  .steps__sub { font-size: clamp(1rem, 4.2vw, 1.12rem); }
  .steps__track { margin-top: 2.25rem; }
  .steps { gap: 2rem; }
  .step { column-gap: 1rem; }
  .step__num { font-size: 1.1rem; box-shadow: 0 0 0 5px var(--steps-band), 0 0 18px -4px rgb(231 192 119 / 0.5); }
  .step__title { margin-top: 0.3rem; font-size: clamp(1.25rem, 5.4vw, 1.45rem); }
  .step__body { font-size: 0.95rem; line-height: 1.55; }
  .steps__finale { margin-top: 2.75rem; font-size: clamp(2rem, 9.4vw, 2.8rem); }

  /* ------------------------------------------- rail with quote cards --- */
  .act--trust { padding-block: clamp(2.75rem, 11vw, 3.5rem) 1rem; }
  .trust__head { font-size: clamp(1.6rem, 6.6vw, 2.1rem); }
  .trust__all .tlink { display: inline-flex; align-items: center; min-height: 44px; }
  .trust__top { gap: 0; margin-bottom: 0.75rem; }
  /* A native swipe strip. Every item takes the height of the tallest one
     (a quote card), so photos fill to the same line. */
  .rail {
    gap: 0.6rem;
    scroll-snap-type: x mandatory;
    padding-bottom: 0.5rem;
    scrollbar-width: none;
  }
  .rail::-webkit-scrollbar { display: none; }
  .rail__item { width: 72vw; height: auto; min-height: 54vw; }
  .rail__quote { width: 76vw; }
  .quote-card { padding: 1.15rem 1.15rem 1rem; }
  .quote-card__quote { font-size: 1.04rem; line-height: 1.38; }
  .quote-card__cap .tlink { display: inline-flex; align-items: center; min-height: 44px; }

  /* ------------------------------------------------------- lead sheet --- */
  /* A bottom sheet. --kb and --vvh come from lead.js (visualViewport): with
     the iOS keyboard up the sheet sits on top of it and never exceeds the
     visible area; the action row is sticky inside the panel. */
  .sheet {
    width: 100%; max-width: none;
    margin: auto 0 var(--kb, 0px);
    max-height: min(90dvh, calc(var(--vvh, 100dvh) - 12px));
  }
  .sheet__panel {
    border-radius: 18px 18px 0 0;
    border-bottom: 0;
    padding: 0.5rem 1.25rem calc(env(safe-area-inset-bottom, 0px) + 0.75rem);
  }
  .sheet__top::before {
    /* The grab handle. Decorative. */
    content: ""; position: absolute; left: 50%; top: 6px;
    width: 38px; height: 4px; margin-left: -19px; border-radius: 2px;
    background: color-mix(in oklab, var(--sc-ink) 22%, transparent);
  }
  .sheet[open] { animation: sheet-up 280ms var(--sc-ease-drawer); }
  .lead__addr { grid-template-columns: minmax(0, 1fr) 6.5rem; }
  html:not(.js) .sheet:not([open]) { padding: 2.5rem var(--sc-gutter); }
  html:not(.js) .sheet__panel { border-radius: 14px; border-bottom: 1px solid var(--sc-hairline); }


  /* ---------------------------------------------------------- closing --- */
  /* CTA centred and stacked on the illustration; the fine-print band below
     it, full width, solid, never on the frame. */
  .close__grid { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .close__cta {
    justify-content: center; text-align: center;
    padding: clamp(4.5rem, 20vw, 6rem) var(--sc-gutter) clamp(4rem, 18vw, 5.5rem);
  }
  .close__ground { object-position: 50% 45%; }
  .close__snow { display: none; }
  .close__art::after {
    background: linear-gradient(to bottom,
      var(--sc-canvas) 0%, rgb(7 11 22 / 0.66) 22%, rgb(7 11 22 / 0.74) 62%, rgb(7 11 22 / 0.92) 100%);
  }
  .close__copy { justify-items: center; gap: 0.9rem; margin-inline: auto; }
  .close__copy .display--lg { font-size: clamp(1.9rem, 8.4vw, 2.5rem); max-width: 15ch; }
  .close__copy .lede { font-size: clamp(1rem, 4.2vw, 1.12rem); max-width: none; }
  .close__act {
    width: 100%; max-width: 21rem;
    display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem;
    margin-top: 0.5rem;
  }
  .close__act .cta { min-height: 52px; font-size: 0.98rem; }
  .foot--band {
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    align-content: start;
    gap: 1.25rem 1.5rem;
    padding: 2rem var(--sc-gutter) 2.25rem;
    border-left: 0; border-top: 1px solid rgb(231 192 119 / 0.16);
    font-size: 0.8rem; line-height: 1.55;
  }
  .foot__col { gap: 0.6rem; }
  .foot__name { font-size: 1.1rem; }
  .foot a { display: inline-flex; align-items: center; min-height: 44px; }
  .foot p:has(a) { line-height: 1.3; }

  .skip { padding: 12px 16px; }
}

@keyframes sheet-up { from { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) {
  .sheet[open] { animation: none !important; }
}

/* ======================= 861-926px landscape (desktop layout, short screen) == */
@media (min-width: 861px) and (max-height: 560px) and (orientation: landscape) {
  .video-hero__copy { top: calc(var(--bar-h) + 8px); right: 4%; width: 45%; }
  .video-hero__copy .display--xl { font-size: 1.8rem; }
  .video-hero .video-hero__copy > * + * { margin-top: .6rem; }
  #hero.is-video-static { min-height: 440px; }
}
