@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("/assets/fonts/bricolage-grotesque-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


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

/* ====================================================================
   Freedom Terminal services pages. Tokens first (the engine derives
   everything from them), then the page's own markup. The engine's
   device selectors above are never restyled here.
   ==================================================================== */
:root {
  /* The icon's palette on a black ground: its electric blue is the one
     accent, its silver is the ink. Gold appears only as a hairline: the
     hero trace, the lead rules, the progress bar and the "you" pin on the
     map. Nothing else is yellow. */
  --sc-canvas:      #07080b;
  --sc-surface:     #0f1116;
  --sc-surface-2:   #15181f;
  --sc-ink:         #f2f3f5;
  --sc-ink-soft:    #9aa1ad;
  --sc-accent:      #3d8bff;
  --sc-accent-ink:  #06101f;
  --sc-hairline:    rgba(255, 255, 255, 0.08);
  --sc-hairline-strong: rgba(255, 255, 255, 0.16);
  /* The edge of a form control (radio ring, check box, text field). A
     hairline is too faint to find a control by; this grey holds 3:1 on the
     canvas, the surface and the hover row. */
  --sc-control:     #6c7380;
  --gold:           #f2b705;
  --navy:           #050608;

  /* One family. Display, text and figures are all Bricolage Grotesque; its
     optical size axis tunes each size, so one file does every job. */
  --sc-font-display: "Bricolage Grotesque", system-ui, sans-serif;
  --sc-font-text:    var(--sc-font-display);
  --sc-font-mono:    var(--sc-font-display);

  /* One spacing scale on an 8px base. */
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 40px; --s5: 64px; --s6: 96px; --s7: 144px;
  --wrap: 1200px;
  --gutter: 24px;
  --bar-h: 64px;
  /* The inner edge of the centred column, for anything placed against a
     full width box instead of inside .sc-wrap. The percent resolves where
     the value is used, against that box. */
  --edge: max(var(--gutter), calc((100% - var(--wrap)) / 2 + var(--gutter)));

  --sc-gutter: var(--gutter);
  --sc-maxw: var(--wrap);
  --sc-r-sm: 10px; --sc-r-md: 14px; --sc-r-lg: 14px;
  color-scheme: dark;
}
@media (max-width: 479px) { :root { --gutter: 16px; } }

html { overflow-x: clip; font-optical-sizing: auto; scroll-padding-top: calc(var(--bar-h) + var(--s2)); }
body { font-size: 1.0625rem; line-height: 1.6; letter-spacing: 0; }
[data-sc-progress] { background: var(--gold); }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ----------------------------------------------------------- the type -- */
.sc-display { font-weight: 700; line-height: 1.05; letter-spacing: -0.02em; }
h1.sc-display { font-size: clamp(2.75rem, 6.4vw, 5.5rem); line-height: 1; letter-spacing: -0.025em; max-width: 12ch; }
h2.sc-display { font-size: clamp(2rem, 3.6vw, 3.25rem); line-height: 1.05; letter-spacing: -0.02em; max-width: 18ch; }
.sc-lede { font-size: 1.25rem; line-height: 1.5; letter-spacing: 0; max-width: 44ch; }
.sc-body { font-size: 1.0625rem; line-height: 1.6; max-width: 62ch; color: var(--sc-ink-soft); }
h3, .why-list strong, .steps strong, .option strong, .choice > legend {
  font-size: 1.1875rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em;
}

/* Inside a section: heading to lede 16, paragraph to paragraph 24, lede
   to a control 40, heading block to content 64. */
.sc-stack > * { margin-block: 0; }
.sc-stack > * + * { margin-top: var(--s2); }
.sc-stack > :is(h1, h2, h3) { margin-top: 0; }
.sc-stack > .sc-body + .sc-body { margin-top: var(--s3); }
.sc-stack > .lead-rule { margin-bottom: var(--s3); }
.lead-rule { width: 56px; height: 2px; background: var(--gold); }

/* ------------------------------------------------------------ the bar -- */
.bar {
  position: fixed; inset: 0 0 auto 0; z-index: var(--sc-z-chrome);
  height: var(--bar-h);
  display: flex; align-items: center; gap: var(--s2);
  padding-inline: var(--edge);
  background: color-mix(in oklab, var(--sc-canvas) 82%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--sc-hairline);
}
.bar-brand { flex: none; display: inline-flex; align-items: center; gap: 10px; font-size: 1rem; font-weight: 600; letter-spacing: -0.005em; color: var(--sc-ink); text-decoration: none; }
.bar-brand img { border-radius: 50%; }
.bar nav { margin-left: auto; min-width: 0; }
.bar-links { display: flex; list-style: none; margin: 0; padding: 0; }
.bar-links a { display: inline-flex; align-items: center; height: 40px; padding: 0 12px; font-size: 1rem; font-weight: 500; line-height: 1; color: var(--sc-ink-soft); text-decoration: none; transition: color var(--sc-d-fast); }
.bar-links a:hover { color: var(--sc-ink); }
.bar-links a[aria-current="page"] { color: var(--sc-ink); text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 2px; text-underline-offset: 6px; }

/* ------------------------------------------------------------ buttons -- */
.btn, .bar-cta, .ticket-go {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 20px;
  border-radius: var(--sc-r-sm);
  background: var(--sc-accent); color: var(--sc-accent-ink);
  font-size: 1rem; font-weight: 600; line-height: 1.2; text-align: center;
  text-decoration: none;
  transition: background-color var(--sc-d-fast);
}
.bar-cta { min-height: 40px; white-space: nowrap; }
:is(.btn, .bar-cta, .ticket-go):hover { background: color-mix(in oklab, var(--sc-accent) 84%, white); }
:is(.btn, .bar-cta, .ticket-go):focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; }
.tel {
  display: inline-block; padding-block: 12px;
  font-weight: 500; color: var(--sc-ink);
  text-decoration: underline; text-decoration-color: var(--sc-hairline-strong);
  text-decoration-thickness: 1px; text-underline-offset: 0.3em;
  font-variant-numeric: tabular-nums;
}
.tel:hover { text-decoration-color: currentColor; }
.cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); margin: 0; }

@media (max-width: 560px) {
  .bar { gap: var(--s1); }
  .bar-brand span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .bar-links a { padding: 0 8px; font-size: 0.9375rem; }
  .bar-cta { padding: 0 14px; font-size: 0.9375rem; }
}
/* Measured: the mark, three links and the button need 350px at 14px. Below
   that the mark goes; the Websites link is the same way home. */
@media (max-width: 389px) {
  .bar { gap: 6px; }
  .bar-links a { padding: 0 6px; font-size: 0.875rem; }
  .bar-cta { padding: 0 12px; font-size: 0.875rem; }
}
@media (max-width: 349px) {
  .bar-brand { display: none; }
}

/* ----------------------------------------------------------- the hero -- */
.stage-hero { background: var(--sc-canvas); }
.plane { position: absolute; inset: 0; pointer-events: none; }
.plane svg { width: 100%; height: 100%; }
.plane-far { background: radial-gradient(60% 60% at 72% 55%, rgba(61, 139, 255, 0.14), transparent 70%); }
.plane-mid { opacity: 0.9; }
.hero-copy {
  position: absolute; z-index: var(--sc-z-copy);
  left: var(--edge); right: var(--edge);
  top: calc(50% + var(--bar-h) / 2); translate: 0 -50%;
  max-width: 40rem;
}
.hero-copy .sc-lede { margin-top: var(--s2); color: var(--sc-ink-soft); }
.hero-copy .namefield { margin-top: var(--s4); }
.hero-copy .cta-row { margin-top: var(--s3); }
.namefield { display: grid; gap: var(--s1); max-width: 29rem; }
.namefield label { font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft); }
.namefield input {
  width: 100%; height: 48px; padding: 0 var(--s2);
  border: 1px solid var(--sc-control); border-radius: var(--sc-r-sm);
  background: var(--sc-surface); color: var(--sc-ink);
  font-size: 1.0625rem;
}
.namefield input::placeholder { color: var(--sc-ink-soft); opacity: 1; }
.namefield input:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; border-color: var(--sc-accent); }
.phone-dock { display: contents; }
.phone-slot { position: absolute; z-index: 2; right: calc(var(--edge) + 4vw); top: 50%; translate: 0 -50%; width: clamp(220px, 20vw, 300px); aspect-ratio: 9 / 19; pointer-events: none; }
/* Phones and tablets stack the hero: the copy on top, then a dock that takes
   whatever height is left, with the phone slot sized to it. The slot can
   never reach up into the copy, whatever the heading wraps to; when the
   space left is too short for a phone worth showing, there is no phone. */
@media (max-width: 860px) {
  .stage-hero { display: grid; grid-template-rows: auto minmax(0, 1fr); }
  .plane-far { background: radial-gradient(70% 45% at 72% 82%, rgba(61, 139, 255, 0.14), transparent 70%); }
  .plane-mid .beacon { display: none; }
  .hero-copy { position: relative; top: auto; left: auto; right: auto; translate: none; max-width: none; margin: var(--s4) var(--gutter) 0; }
  .hero-copy .namefield { margin-top: var(--s3); }
  .phone-dock { display: block; position: relative; min-height: 0; margin: var(--s2) 0; container-type: size; }
  .phone-slot { right: 8%; top: auto; bottom: 0; translate: none; width: auto; height: min(100%, 72vw, 359px); }
}
@container (max-height: 180px) {
  .phone-slot { display: none; }
}
@media (max-width: 860px) and (max-height: 760px) {
  .phone-slot { display: none; }
}

/* ------------------------------------------------------ the 3D phone -- */
.phone {
  position: fixed; left: 0; top: 0; z-index: 10;
  width: 260px; aspect-ratio: 9 / 19;
  pointer-events: none; opacity: 0;
  transform-origin: 50% 50%;
  perspective: 1400px;
  will-change: transform, opacity;
}
.phone-body {
  position: absolute; inset: 0;
  border-radius: 13% / 6.2%;
  background: linear-gradient(160deg, #2a3140 0%, #0f1420 55%, #1c2230 100%);
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, 0.08),
    inset 0 2px 1px rgba(255, 255, 255, 0.14),
    0 0 0 1px rgba(255, 255, 255, 0.14),
    0 28px 56px -18px rgba(0, 0, 0, 0.7);
  transform-style: preserve-3d;
}
.phone-body::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, rgba(0,0,0,0.5), transparent 12%, transparent 88%, rgba(0,0,0,0.5));
  transform: translateZ(-10px) scale(1.012);
}
.phone-side { position: absolute; width: 3px; background: #2b3447; border-radius: 2px; }
.phone-side-l1 { left: -3px; top: 18%; height: 6%; }
.phone-side-l2 { left: -3px; top: 27%; height: 10%; }
.phone-side-r { right: -3px; top: 22%; height: 14%; }
.phone-screen {
  position: absolute; inset: 3.2% 4.6%;
  border-radius: 10% / 4.8%;
  background: radial-gradient(120% 80% at 50% 0%, #1a2a52 0%, #0b1630 60%, #070d1e 100%);
  color: #f2f5fa; overflow: hidden;
  display: flex; flex-direction: column;
  font-family: var(--sc-font-text);
}
.phone-screen::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.03) 32%, transparent 48%);
}
.notch { position: absolute; top: 3%; left: 50%; translate: -50% 0; width: 34%; height: 4.2%; border-radius: 999px; background: #05080f; }
.screen-top { display: flex; justify-content: space-between; padding: 5% 9% 0; font-size: 0.72em; opacity: 0.85; font-variant-numeric: tabular-nums; }
.screen-main { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 0 8%; gap: 0.35em; }
.screen-kicker { margin: 0; font-size: 0.72em; letter-spacing: 0.02em; opacity: 0.7; }
.screen-name { margin: 0; font-family: var(--sc-font-display); font-weight: 700; font-size: 1.22em; line-height: 1.15; text-wrap: balance; }
.screen-sub { margin: 0; font-size: 0.8em; opacity: 0.86; }
.screen-time { margin: 0; font-family: var(--sc-font-display); font-weight: 700; font-size: 2.6em; line-height: 1; letter-spacing: -0.02em; }
.screen-actions { display: flex; justify-content: space-between; padding: 0 16% 11%; }
.screen-actions span { width: 2.9em; height: 2.9em; border-radius: 50%; display: grid; place-items: center; }
.screen-actions svg { width: 1.3em; height: 1.3em; fill: #fff; }
.decline { background: #e5484d; }
.accept { background: #30a46c; }
.phone[data-mode="idle"] .call-only { display: none; }
.phone[data-mode="ring"] .idle-only { display: none; }
.rings { position: absolute; inset: -30%; pointer-events: none; z-index: -1; }
.rings i { position: absolute; inset: 0; border-radius: 50%; border: 2px solid rgba(61, 139, 255, 0.55); opacity: 0; transform: scale(0.5); }
.phone[data-mode="ring"] .rings i { animation: ring-out 2.2s var(--sc-ease-out) infinite; }
.phone[data-mode="ring"] .rings i:nth-child(2) { animation-delay: 0.7s; }
.phone[data-mode="ring"] .rings i:nth-child(3) { animation-delay: 1.4s; }
@keyframes ring-out { 0% { opacity: 0.9; transform: scale(0.55); } 100% { opacity: 0; transform: scale(1.15); } }
.phone[data-mode="ring"] .phone-body { animation: buzz 0.5s linear infinite; }
@keyframes buzz { 0%, 100% { translate: 0 0; } 20% { translate: -1.5px 0.5px; } 40% { translate: 1.5px -0.5px; } 60% { translate: -1px 0; } 80% { translate: 1px 0; } }
.phone-shadow { position: absolute; left: 6%; right: 6%; bottom: -10%; height: 12%; border-radius: 50%; background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.18) 45%, transparent 72%); }
@media (prefers-reduced-motion: reduce) {
  .phone[data-mode="ring"] .phone-body { animation: none; }
  .phone[data-mode="ring"] .rings i { animation: none; opacity: 0.35; transform: scale(0.9); }
}

/* ----------------------------------------------------------- sections -- */
.sect { padding-block: var(--s7); background: var(--sc-canvas); position: relative; }
.sect-tight { padding-top: var(--s5); }
@media (max-width: 899px) {
  .sect { padding-block: var(--s5); }
  .sect-tight { padding-top: var(--s4); }
}
.split { display: grid; gap: var(--s5); align-items: center; }
@media (min-width: 900px) { .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--s6); } }
.map-fig { margin: 0; overflow: hidden; background: var(--sc-surface); border: 1px solid var(--sc-hairline); aspect-ratio: 4 / 3; }
.map-fig svg { width: 100%; height: 100%; display: block; }

/* A heading block beside a list of rows. On wide screens the heading
   holds still while its rows pass. */
.rows-split { display: grid; gap: var(--s5); }
@media (min-width: 900px) {
  .rows-split { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--s6); align-items: start; }
  .rows-head { position: sticky; top: 96px; }
}
.rows { list-style: none; margin: 0; padding: 0; border-bottom: 1px solid var(--sc-hairline); }
.rows > li { border-top: 1px solid var(--sc-hairline); padding-block: var(--s3); }
.rows p { margin: 0; color: var(--sc-ink-soft); max-width: 62ch; text-wrap: pretty; }

/* ----------------------------------------------------------- the ring -- */
.act-ring { background: var(--navy); --sc-canvas: var(--navy); }
.stage-ring { background: radial-gradient(90% 70% at 50% 60%, #15275a 0%, #0a1430 45%, var(--navy) 100%); }
.stage-ring::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.05;
  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>");
}
.ring-slot { position: absolute; z-index: 2; left: 50%; top: 52%; translate: -50% -50%; width: clamp(200px, 22vw, 320px); aspect-ratio: 9 / 19; pointer-events: none; }
.ring-copy { position: absolute; z-index: var(--sc-z-copy); left: var(--edge); right: var(--edge); bottom: clamp(2.5rem, 9vh, 7rem); max-width: 30rem; height: 9rem; }
.ring-copy p { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; }
.ring-copy .sc-display { font-size: clamp(1.7rem, 3.6vw, 2.8rem); }
.ring-copy .sc-lede { color: var(--sc-ink-soft); }
.ring-caption { position: absolute; z-index: var(--sc-z-copy); right: var(--edge); bottom: clamp(2.5rem, 9vh, 7rem); margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft); max-width: 22ch; text-align: right; }
@media (max-width: 860px) {
  .ring-slot { top: 42%; width: clamp(170px, 46vw, 220px); }
  .ring-copy { left: var(--gutter); right: var(--gutter); bottom: 6vh; max-width: none; }
  .ring-copy .sc-display { font-size: clamp(1.5rem, 7vw, 2.2rem); }
  .ring-caption { display: none; }
}

/* ------------------------------------------------------- what you get -- */
.get-list > li { display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: var(--s3); row-gap: var(--s1); }
.get-list > li > :not(svg) { grid-column: 2; }
.get-list svg { grid-row: 1 / span 2; width: 28px; height: 28px; margin-top: 1px; fill: none; stroke: var(--sc-accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.get-list h3 { margin: 0; }
.get-list > li.get-note p { color: var(--sc-ink-soft); }

/* --------------------------------------------------------- what we do --
   Rows that are links to a service page. The whole row is the target; a
   chevron at its right edge says it goes somewhere, since a phone has no
   hover to tell it. */
.sc-stack > .do-list { margin-top: var(--s4); }
.do-list > li { padding-block: 0; }
.do-list > li > a {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s3); align-items: center;
  padding-block: var(--s3); color: inherit; text-decoration: none;
}
.do-list > li > a > * { grid-column: 1; }
.do-list > li > a::after { content: ""; grid-column: 2; grid-row: 1 / span 2; width: 8px; height: 8px; margin-right: 4px; border-right: 2px solid var(--sc-accent); border-bottom: 2px solid var(--sc-accent); transform: rotate(-45deg); }
.do-list strong { display: block; font-size: 1.1875rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em; color: var(--sc-ink); transition: color var(--sc-d-fast); }
.do-list p { margin-top: var(--s1); }
.do-list > li > a:hover strong, .do-list > li > a:focus-visible strong { color: var(--sc-accent); }
.do-list > li > a:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 4px; border-radius: var(--sc-r-sm); }
.why-list { list-style: none; margin: 0; padding: 0; }
.why-list li { border-top: 1px solid var(--sc-hairline); padding-block: var(--s3); }
.why-list li:last-child { padding-bottom: 0; }
.why-list strong { display: block; color: var(--sc-ink); }
.why-list p { margin: var(--s1) 0 0; color: var(--sc-ink-soft); max-width: 46ch; }

/* --------------------------------------------------- the estimate builder --
   Three columns from 1280px: the two groups and the ticket, which holds
   still beside them and so can never sit over a price. Below that the
   ticket follows the groups in the page, and a one line sheet carries the
   total while the groups are on screen. */
.builder { display: grid; gap: var(--s3); margin-top: var(--s5); }
@media (min-width: 900px) {
  .builder { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .builder > #addons, .builder > .ticket { grid-column: 1 / -1; }
}
@media (min-width: 1280px) {
  .builder { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 320px; }
  .builder > #addons { grid-column: 1 / 3; }
  .builder > .ticket { grid-column: 3; grid-row: 1; position: sticky; top: 96px; align-self: start; }
  .builder:has(> #addons) > .ticket { grid-row: 1 / span 2; }
}

.choice {
  margin: 0; padding: 0; min-width: 0;
  background: var(--sc-surface);
  border: 1px solid var(--sc-hairline); border-radius: var(--sc-r-md);
  overflow: clip;
}
/* A floated legend is laid out as ordinary content, so the group's name
   sits inside the box as its header instead of notched into the border. */
.choice > legend { float: left; width: 100%; margin: 0; padding: var(--s3) var(--s3) var(--s2); }
.choice > legend:has(+ .choice-note) { padding-bottom: 4px; }
.choice > legend + * { clear: both; }
.choice-note { margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft); }
.choice > legend + .choice-note { padding: 0 var(--s3) var(--s2); }
.choice > .option ~ .choice-note { padding: var(--s2) var(--s3); border-top: 1px solid var(--sc-hairline); }
.choice-note a { color: var(--sc-accent); font-weight: 600; }

/* No transition on the row's background: rows slide under a resting pointer
   while the page scrolls, and an eased background repaints the row on every
   frame of the ease. Measured: seven dropped frames across the pricing
   builder with a 160ms ease, none without. */
.option { border-top: 1px solid var(--sc-hairline); }
.option > label {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) auto;
  column-gap: var(--s2); align-items: start;
  padding: var(--s2) var(--s3);
  cursor: pointer;
}
.option:has(:checked) { background: var(--sc-surface-2); box-shadow: inset 3px 0 0 var(--sc-accent); }
@media (hover: hover) and (pointer: fine) {
  .option:hover { background: var(--sc-surface-2); }
}
.option:has(input:focus-visible) { outline: 2px solid var(--sc-accent); outline-offset: -2px; }
.option input {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; margin: 3px 0 0;
  display: grid; place-content: center;
  border: 1.5px solid var(--sc-control); border-radius: 50%;
  background: transparent; cursor: pointer;
}
.option input::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--sc-canvas); transform: scale(0); }
.option input:checked { border-color: var(--sc-accent); background: var(--sc-accent); }
.option input:checked::before { transform: none; }
.option input[type="checkbox"] { border-radius: 4px; }
.option input[type="checkbox"]::before { width: 5px; height: 9px; margin-top: -2px; border-radius: 0; background: none; border: solid var(--sc-canvas); border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0); }
.option input[type="checkbox"]:checked::before { transform: rotate(45deg); }
.option input:focus-visible { outline: none; }
/* Three columns: control, name, price. The name and the price share the
   first line; the description runs from the name column to the right edge
   underneath, so it is not squeezed into the space beside the price. The
   name wrapper span steps aside (display: contents) so its two children
   are placed on the label's grid directly. */
.option > label > span:not(.price) { display: contents; }
.option > label > input { grid-column: 1; grid-row: 1; }
.option strong { grid-column: 2; grid-row: 1; display: block; color: var(--sc-ink); }
.option .meta { grid-column: 2 / -1; grid-row: 2; display: block; margin-top: 4px; font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft); }
.option .price { grid-column: 3; grid-row: 1; font-size: 1.1875rem; font-weight: 600; line-height: 1.3; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.option .was, .prices .was { margin-right: var(--s1); font-size: 0.9375rem; font-weight: 400; color: var(--sc-ink-soft); text-decoration: line-through; }
@media (max-width: 359px) {
  .option .was, .prices .was { display: block; margin-right: 0; }
}
.option:has(> details) > label { padding-bottom: var(--s1); }
.option > details { padding: 0 var(--s3) var(--s2) calc(var(--s3) + 18px + var(--s2)); font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft); }
.option > details > summary { display: inline-flex; align-items: center; gap: var(--s1); color: var(--sc-accent); font-weight: 600; cursor: pointer; list-style: none; }
.option > details > summary::-webkit-details-marker { display: none; }
.option > details > summary::after { content: ""; width: 6px; height: 6px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform var(--sc-d-fast); }
.option > details[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
.option > details ul { margin: 12px 0 0; padding-left: 24px; display: grid; gap: 12px; }
.option > details a { color: var(--sc-accent); font-weight: 600; }

/* the ticket */
.ticket {
  --ticket-pad: var(--s3);
  position: relative; min-width: 0; padding: var(--ticket-pad);
  background: var(--sc-surface);
  border: 1px solid var(--sc-hairline); border-radius: var(--sc-r-md);
}
.ticket h3 { margin: 0; overflow-wrap: anywhere; }
.ticket dl { margin: var(--s2) 0 0; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s1) var(--s2); font-size: 0.9375rem; line-height: 1.5; }
.ticket dt { color: var(--sc-ink-soft); }
.ticket dd { margin: 0; text-align: right; color: var(--sc-ink); font-variant-numeric: tabular-nums; }
.ticket .total { margin: var(--s2) 0 0; padding-top: var(--s2); border-top: 1px solid var(--sc-hairline); font-size: 1.75rem; font-weight: 700; line-height: 1.1; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.ticket .total small, .sheet-total small { display: block; margin-top: 4px; font-size: 0.9375rem; font-weight: 400; line-height: 1.5; letter-spacing: 0; color: var(--sc-ink-soft); }
.ticket #tNote { margin-top: var(--s1); }
.ticket #tNote:empty { display: none; }
.ticket .ticket-go { width: 100%; margin-top: var(--s3); }
@media (min-width: 900px) and (max-width: 1279px) {
  .ticket { display: grid; grid-template-columns: minmax(0, 26rem) minmax(0, 20rem); justify-content: space-between; column-gap: var(--s5); align-items: start; }
  .ticket > h3 { grid-column: 1; grid-row: 1; }
  .ticket > dl { grid-column: 1; grid-row: 2 / span 2; }
  .ticket > .total { grid-column: 2; grid-row: 1 / span 2; margin: 0; padding: 0; border: 0; }
  .ticket > .ticket-go { grid-column: 2; grid-row: 3; align-self: end; }
  .ticket > #tNote { grid-column: 2; grid-row: 4; }
}
@media (max-width: 359px) {
  .ticket { --ticket-pad: var(--s2); }
  .ticket .ticket-go { padding-inline: 12px; }
}

/* the sheet: the total and the button at the foot of a narrow screen */
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--sc-surface); border-top: 1px solid var(--sc-hairline);
  transform: translateY(100%); visibility: hidden;
}
/* It slides up when it arrives and is simply gone when it leaves, so it is
   never still on screen while the full ticket scrolls into its place. */
.sheet.is-on { transform: none; visibility: visible; transition: transform var(--sc-d-base) var(--sc-ease-out); }
.sheet-total { margin: 0; min-width: 0; font-size: 1.1875rem; font-weight: 600; line-height: 1.2; font-variant-numeric: tabular-nums; }
.sheet-total small { margin-top: 2px; }
.sheet .ticket-go { flex: none; }
@media (min-width: 1280px) { .sheet { display: none; } }
@media (max-width: 1279px) { html { scroll-padding-bottom: 96px; } }
@media (prefers-reduced-motion: reduce) { .sheet, .sheet.is-on { transition: none; } }

/* --------------------------------------------------------- the steps -- */
.steps { counter-reset: step; }
.steps > li { display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: var(--s2); row-gap: 4px; }
.steps > li::before { counter-increment: step; content: counter(step); grid-row: 1 / span 2; font-size: 1.1875rem; font-weight: 600; line-height: 1.3; color: var(--sc-accent); font-variant-numeric: tabular-nums; }
.steps > li > * { grid-column: 2; }
.steps strong { display: block; color: var(--sc-ink); }

/* ---------------------------------------------------------- the close -- */
.act-close { background: var(--sc-canvas); }
.stage-close { position: relative; display: flex; flex-direction: column; justify-content: center; min-height: 100vh; min-height: 100svh; background: var(--sc-canvas); }
/* The footer is in the flow at the foot of the stage, and the copy takes
   the auto margins: centred in the space above the footer, never under it,
   whatever the footer wraps to on a short phone. */
.close-inner { position: relative; z-index: var(--sc-z-copy); width: 100%; max-width: var(--wrap); margin: auto; padding-inline: var(--gutter); }
.close-inner .sc-lede { margin-top: var(--s3); color: var(--sc-ink-soft); }
.close-inner .cta-row { margin-top: var(--s4); }
.close-foot {
  margin-top: var(--s4);
  padding: var(--s3) var(--edge);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s3);
  font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft);
  border-top: 1px solid var(--sc-hairline);
}
.close-foot img { border-radius: 50%; }
.close-foot a { color: var(--sc-ink-soft); text-decoration: none; }
.close-foot a:hover { color: var(--sc-ink); text-decoration: underline; }
.close-foot a[aria-current="page"] { color: var(--sc-ink); }
.close-foot .fine { margin: 0 0 0 auto; }

/* ------------------------------------------------------ pricing page -- */
.page-head { padding-top: calc(var(--bar-h) + var(--s6)); padding-bottom: 0; }
.page-head .sc-lede { color: var(--sc-ink-soft); }
.sc-stack > .namefield { margin-top: var(--s4); }
.know > li { position: relative; padding-left: var(--s3); }
.know > li::before { content: ""; position: absolute; left: 0; top: calc(var(--s3) + 0.8em - 3px); width: 6px; height: 6px; border-radius: 50%; background: var(--sc-accent); }
@media (max-width: 899px) { .page-head { padding-top: calc(var(--bar-h) + var(--s5)); } }
.page-head .cta-row { margin-top: var(--s4); }

/* ------------------------------------------------------ service pages --
   Flow sections only: the H1 is the hero, the rest is rows and hairlines.
   A service H1 is a sentence, not a word, so it gets a wider measure than
   the home hero's and a size that keeps it to four lines on a laptop. */
.service-head h1.sc-display { max-width: 17ch; font-size: clamp(2.5rem, 5.6vw, 4.75rem); line-height: 1.02; }
.entries > li > :is(h3, h4) { margin: 0; }
.entries h4 { font-size: 1.1875rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em; }
.entries > li > :is(h3, h4) + p { margin-top: var(--s1); }
/* A plan's name over its list of inclusions: one step up from a row title. */
.rows-body > h3 { margin: 0 0 var(--s3); font-size: 1.625rem; font-weight: 700; line-height: 1.15; letter-spacing: -0.015em; }
.rows-body > .entries + h3 { margin-top: var(--s5); }
.rows-body > .rows + .price-note { margin-top: var(--s3); }
.rows-body > * + .text-link-row { margin-top: var(--s2); }
.price-note, .text-link-row { margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft); }
/* Row titles and questions are short lines: balanced, so no word is left alone on a phone. */
.rows > li > :is(h3, h4, strong), .rows > li > a > strong, .faq summary { text-wrap: balance; }
.price-note { text-wrap: pretty; }
.text-link-row a { display: inline-block; padding-block: 12px; color: var(--sc-accent); font-weight: 600; font-size: 1.0625rem; }

/* A price row: the name and the figure share the first line, the plan's own
   words from the pricing page run underneath at full width. */
.prices > li { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s3); row-gap: 4px; align-items: baseline; }
.prices strong { font-size: 1.1875rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em; color: var(--sc-ink); }
.prices .price { grid-column: 2; grid-row: 1; font-size: 1.1875rem; font-weight: 600; line-height: 1.3; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.prices .price small { font-size: 0.9375rem; font-weight: 400; color: var(--sc-ink-soft); }
.prices p { grid-column: 1 / -1; }

/* Questions: the summary is the whole row, so the tap target is the full
   width and the full padding, and the chevron sits at the right edge. */
.faq > li { padding-block: 0; }
.faq summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3);
  padding-block: var(--s3); cursor: pointer; list-style: none;
  font-size: 1.1875rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em; color: var(--sc-ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; flex: none; width: 8px; height: 8px; margin-right: 4px; border-right: 2px solid var(--sc-ink-soft); border-bottom: 2px solid var(--sc-ink-soft); transform: translateY(-3px) rotate(45deg); transition: transform var(--sc-d-fast); }
.faq details[open] summary::after { transform: translateY(2px) rotate(225deg); }
.faq summary:hover { color: var(--sc-accent); }
.faq summary:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 4px; border-radius: var(--sc-r-sm); }
.faq details > p { padding-bottom: var(--s3); }
@media (prefers-reduced-motion: reduce) { .faq summary::after { transition: none; } }

/* Cities: short names, so two to a line. */
.cities { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s3); }
.cities > li { padding-block: var(--s2); font-weight: 500; color: var(--sc-ink); }

/* ------------------------------------- no script, and the act sizes -- */
html.nojs [data-sc-cue], html.nojs [data-sc-in], html.nojs [data-sc-stagger] > * { opacity: 1; transform: none; }
/* The ticket stays in the page without script: the checked inputs are its
   defaults, so it is already right, and hiding it would reflow the builder
   the moment the script runs. Only the sheet, which needs the script, goes. */
html.nojs .phone, html.nojs .sheet { display: none; }
/* Without script the ticket cannot total, and the radios still change. Its
   figures are hidden in place (visibility keeps their boxes, so nothing
   moves when the script arrives) and a note sits over them, positioned so
   it adds no height. The booking link still works, without the notes. */
.ticket-nojs { display: none; }
html.nojs .ticket-nojs {
  display: block; position: absolute;
  top: calc(var(--ticket-pad) + 1.1875rem * 1.3 + var(--s2));
  left: var(--ticket-pad); right: var(--ticket-pad);
  max-width: 34ch; margin: 0;
  font-size: 0.9375rem; line-height: 1.5; color: var(--sc-ink-soft);
}
html.nojs .ticket dl, html.nojs .ticket .total, html.nojs .ticket .choice-note { visibility: hidden; }
.stage-hero, .stage-ring, .stage-close { padding-top: var(--bar-h); box-sizing: border-box; }
/* Size the pinned acts and their stages up front so the engine's mount writes the
   same numbers it finds, and nothing below the hero shifts on first paint. */
html:not(.nojs) #hero { height: 150vh; }
html:not(.nojs) #ring { height: 240vh; }
html:not(.nojs) [data-sc-stage] { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: clip; z-index: var(--sc-z-stage); }
html.nojs [data-sc-stage] { position: relative; min-height: 100vh; }
html.nojs .ring-copy p { position: static; margin-top: var(--s2); }
html.nojs .ring-copy { height: auto; }
