/* ==========================================================================
   simcoach-rs.app — design system
   --------------------------------------------------------------------------
   Ported from the design handoff at
   `RaceStint/Desgins/design_handoff_simcoach_rs_site/site/sc-site.css`
   (+ `sc-atoms.jsx` for the atoms), rewritten from React inline styles into
   plain CSS. Values are the handoff's; the structure is not.

   The palette is the SimCoach app theme. Where the app's Flutter tokens and
   the handoff disagree the handoff wins for this site (it is the design of
   record here) — the one place that bites is red-light: the app ships
   `#FF4954`, the site is specified `#FF5560`.

   Section order: fonts · tokens · reset · utilities · layout · type ·
   buttons · cards · nav · hero · sections · footer · responsive · motion.
   ========================================================================== */

/* ── Fonts ───────────────────────────────────────────────────────────────
   Self-hosted; see fonts/README.md for why (short version: a cross-origin
   font fetch is a visible flash on the headline of a landing page). Variable
   files, one per family, preloaded from the document head.               */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('fonts/archivo-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;
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/archivo-italic-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;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/geist-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;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/geist-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500 800;
  font-display: swap;
  src: url('fonts/jetbrains-mono-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;
}

/* The heading face. One static weight, and ONE subset: unlike the three
   families above, Squada One has no `latin-ext` upstream — Google publishes a
   single `latin` file for it, so there is no second face to declare here. Any
   glyph outside this range falls through to Archivo, which is why
   `--font-heading` names Archivo before the generics rather than after them. */
@font-face {
  font-family: 'Squada One';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/squada-one-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;
}

/* ── Tokens ──────────────────────────────────────────────────────────── */

:root {
  /* Red — the brand. `--sc-red-light` and `--sc-red-deep` exist only here:
     neither has an equivalent in the app's Flutter tokens. */
  --sc-red: #E11D27;
  --sc-red-light: #FF5560;
  --sc-red-soft: #FF8A92;
  --sc-red-deep: #8B0E14;

  /* Green is status/live/data ONLY. Never a CTA. Never a price. */
  --sc-green: #5CE1A8;
  --sc-green-dim: #2FA17C;

  --sc-purple: #B57FFF;
  --sc-cyan: #7DD3FC;
  --sc-amber: #F0A830;

  /* Ink ramp: page · app content · telemetry page. */
  --sc-ink: #06080C;
  --sc-ink2: #0A0E15;
  --sc-ink3: #03060A;

  /* Text ramp. */
  --sc-text: #F1F3F6;
  --sc-text2: #C7CCD4;
  --sc-muted: #8A929E;
  --sc-dim: #565E6B;
  --sc-faint: #2A323D;

  /* The handoff sets its quietest site labels in `dim` and the footer's legal
     line in `faint`. Measured against the page ground those are 3.06:1 and
     1.55:1 — both below the 4.5:1 WCAG AA floor for text this size, and the
     footer one is barely legible. `dim` and `faint` are kept as tokens
     because the app mocks genuinely need the full ramp (they are a picture of
     an app, which the handoff's own a11y note exempts), but no SITE copy is
     set in them. This is the quiet tier the site uses instead: 4.88:1 on the
     ground, 4.97:1 on the footer wash, and still a clear step below `muted`
     (6.38:1) so the hierarchy the handoff draws survives. */
  --sc-label: #757E8B;

  --sc-focus: #FFD34D;

  /* HEADINGS ONLY. Kept separate from `--font-display` rather than replacing
     it, because `--font-display` is not a headings token: it also carries
     `.sc-figure` (numerals), `.sc-em` (the one italic in the ramp) and the
     booking mock's app chrome, none of which Squada One can express — it is a
     single static 400 with no italic. Swapping the one token would have taken
     all of those with it.
     Archivo sits second so that anything Squada One's latin-only file does not
     cover — the `’` in the setups headline is the one on this page — falls
     through to the display face rather than to system-ui. */
  --font-heading: 'Squada One', 'Archivo', system-ui, sans-serif;
  --font-display: 'Archivo', system-ui, sans-serif;
  --font-ui: 'Geist', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  /* Surfaces. */
  --sc-glass: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.045),
    rgba(255, 255, 255, 0.008)
  );
  --sc-glass-border: 1px solid rgba(255, 255, 255, 0.08);
  --sc-glass-inset: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  --sc-radius: 18px;

  /* CTA. The gradient end (#B01018) is site-only, like the reds above. */
  --sc-cta: linear-gradient(180deg, #E11D27, #B01018);
  --sc-cta-border: rgba(255, 120, 128, 0.5);
  --sc-cta-shadow: 0 8px 22px rgba(225, 29, 39, 0.28),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
  --sc-cta-shadow-hover: 0 12px 28px rgba(225, 29, 39, 0.36),
    inset 0 1px 0 rgba(255, 255, 255, 0.24);

  /* Rhythm. Both step down at breakpoints, so everything laid out against
     them follows without a second rule. */
  --nav-h: 66px;
  --wrap: 1280px;
  --gutter: 40px;
  --sec-y: 104px;

  /* Micro-label floor. The handoff runs mono labels at 7.5–10.5px; that is
     correct INSIDE the app mocks (they are a picture of an app) but not for
     site chrome, which the a11y notes hold to >= 13px. */
  --fs-micro: 13px;

  /* The tick used by `.sc-ticks`, drawn as a mask so it takes currentColor
     rather than needing a second file per colour. */
  --tick-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M2 7.4l3.2 3.2L12 3.6' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* ── Reset + base ────────────────────────────────────────────────────── */

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

/* `hidden` is a UA-origin `display: none`, so ANY author `display` beats it —
   and the hero facade's control carries `.sc-btn`, which sets
   `display: inline-flex`. Without this line a `hidden` button paints, and
   paints as a working control that boot.js has not wired. Stated once here
   rather than as a `:not([hidden])` guard on each rule that could collide. */
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 12px);
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}

body {
  margin: 0;
  background: var(--sc-ink);
  color: var(--sc-text);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.5;
  font-variant-numeric: lining-nums tabular-nums;
  overflow-x: hidden;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-heading);
  /* Squada One ships ONE weight. The ramp below still asks for 800/800/700,
     and unanswered that becomes SYNTHETIC bold — the browser smearing the 400
     outlines, which on a face this condensed closes the counters and reads as
     a rendering fault rather than as emphasis.
     Disabling the synthesis is the whole fix, and it is why those weights are
     deliberately left alone rather than rewritten to 400: they are not dead.
     They are what the FALLBACK renders at. Archivo is a 300-800 variable file,
     so if the woff2 above ever fails to arrive the headings still come up at
     the weight this page was designed around instead of dropping to a limp
     400. Squada One simply cannot answer them, and now says so honestly
     instead of faking it.
     Weight only, and scoped to headings: `.sc-em` is Archivo 500 ITALIC and
     needs style synthesis left alone, and the mono labels want the real
     instances of their own variable file. */
  font-synthesis-weight: none;
  letter-spacing: -0.028em;
  line-height: 1.04;
  text-wrap: balance;
  color: #fff;
}

p,
ul,
ol,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: var(--sc-red-soft);
  text-decoration: none;
  transition: color 0.15s;
}

a:hover {
  color: #FFB3B9;
}

button {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

::selection {
  background: rgba(225, 29, 39, 0.35);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 8px;
}

::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.18);
}

/* One focus treatment, everywhere. 3px so it clears the CTA's own 1px
   border, offset 2 so it never sits on the glyph. No border-radius here —
   the outline already follows each element's own corner radius, and forcing
   one would square off the 12px buttons while they are focused. */
:focus-visible {
  outline: 3px solid var(--sc-focus);
  outline-offset: 2px;
}

/* ── Utilities ───────────────────────────────────────────────────────── */

.mono {
  font-family: var(--font-mono);
  text-transform: uppercase;
  font-variant-ligatures: none;
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.24em;
  color: var(--sc-muted);
  line-height: 1.4;
}

.sc-hr {
  height: 1px;
  border: 0;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.11),
    rgba(255, 255, 255, 0)
  );
}

.sc-nowrap {
  white-space: nowrap;
}

/* Text equivalents for anything carried visually. Not `display:none` —
   screen readers must still reach it. */
.sc-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 12px 20px;
  border-radius: 0 0 12px 0;
  background: var(--sc-cta);
  border: 1px solid var(--sc-cta-border);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
}

.skip-link:focus {
  left: 0;
  color: #fff;
}

/* `#main` carries `tabindex="-1"` so the skip link moves focus and not merely
   the scroll position. It is a LANDMARK, not a user-interface component, so
   WCAG 2.4.7 does not ask for an indicator on it — and the default treatment
   would ring the entire page in amber for as long as focus rested there. The
   skip link's own ring has already told the user where they were, and the next
   Tab lands on a real control that draws its own. */
#main:focus,
#main:focus-visible {
  outline: none;
}

/* ── Layout primitives ───────────────────────────────────────────────── */

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

.sc-sec {
  position: relative;
  padding: var(--sec-y) 0;
}

.sc-stack {
  display: flex;
  flex-direction: column;
  gap: 44px;
}

.sc-grid3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.sc-grid2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.sc-sechead {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 760px;
}

/* ── Type ────────────────────────────────────────────────────────────── */

.sc-h1 {
  font-size: clamp(38px, 5.4vw, 72px);
  font-weight: 800;
  line-height: 0.98;
}

.sc-h2 {
  font-size: clamp(30px, 3.6vw, 46px);
  font-weight: 800;
}

.sc-h3 {
  font-size: 18.5px;
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -0.02em;
}

.sc-lede {
  max-width: 60ch;
  font-size: clamp(15px, 1.35vw, 19px);
  line-height: 1.5;
  color: var(--sc-text2);
}

.sc-body {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--sc-muted);
}

.sc-eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
}

.sc-eyebrow::before {
  content: '';
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 99px;
  background: var(--sc-red);
  box-shadow: 0 0 10px var(--sc-red);
}

.sc-eyebrow .mono {
  letter-spacing: 0.28em;
  color: var(--sc-red-soft);
}

/* Any standalone figure. Tabular so a column of them cannot jitter. */
.sc-figure {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: #fff;
}

/* The one italic the type ramp carries: Archivo 500 italic. Used inside a
   display heading, where the drop from 800 to 500 is the emphasis. */
.sc-em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.02em;
}

/* ── Buttons ─────────────────────────────────────────────────────────── */

.sc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 12px 20px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  text-decoration: none;
}

.sc-btn--sm {
  padding: 8px 14px;
  font-size: 13px;
}

.sc-btn--lg {
  padding: 15px 26px;
  font-size: 15.5px;
}

.sc-btn--block {
  width: 100%;
}

.sc-btn svg {
  flex: none;
  opacity: 0.9;
}

.sc-cta {
  background: var(--sc-cta);
  border: 1px solid var(--sc-cta-border);
  box-shadow: var(--sc-cta-shadow);
  color: #fff;
  transition: transform 0.16s cubic-bezier(0.2, 0.7, 0.3, 1),
    box-shadow 0.16s, filter 0.16s;
}

.sc-cta:hover {
  transform: translateY(-1px);
  filter: brightness(1.08);
  box-shadow: var(--sc-cta-shadow-hover);
  color: #fff;
}

.sc-ghost {
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid rgba(255, 255, 255, 0.13);
  color: var(--sc-text);
  transition: background 0.16s, border-color 0.16s, transform 0.16s;
}

.sc-ghost:hover {
  background: rgba(255, 255, 255, 0.075);
  border-color: rgba(255, 255, 255, 0.24);
  transform: translateY(-1px);
  color: var(--sc-text);
}

.sc-btnrow {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* ── Cards ───────────────────────────────────────────────────────────── */

.sc-card {
  position: relative;
  background: var(--sc-glass);
  border: var(--sc-glass-border);
  border-radius: var(--sc-radius);
  box-shadow: var(--sc-glass-inset);
  transition: transform 0.18s cubic-bezier(0.2, 0.7, 0.3, 1),
    border-color 0.18s, box-shadow 0.18s;
}

.sc-card-h:hover {
  transform: translateY(-4px);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: 0 22px 46px rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* Bulleted proof lists — a red tick rather than a disc. */
.sc-ticks {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.sc-ticks li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--sc-text2);
}

.sc-ticks li::before {
  content: '';
  flex: none;
  width: 13px;
  height: 13px;
  margin-top: 4px;
  background-color: var(--sc-red-soft);
  -webkit-mask: var(--tick-mask) no-repeat center / contain;
  mask: var(--tick-mask) no-repeat center / contain;
}

/* "Soon" — the amber pill the shipped app's nav rail uses for a feature
   that is not live yet. Same treatment here so the two agree. */
.sc-soon {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 99px;
  background: rgba(240, 168, 48, 0.1);
  border: 1px solid rgba(240, 168, 48, 0.35);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sc-amber);
  line-height: 1.3;
}

/* ── Nav ─────────────────────────────────────────────────────────────── */

.sc-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  display: flex;
  align-items: center;
  height: var(--nav-h);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.25s, border-color 0.25s, backdrop-filter 0.25s;
}

.sc-nav.is-solid {
  background: rgba(6, 8, 12, 0.86);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border-bottom-color: rgba(255, 255, 255, 0.07);
}

.sc-nav__inner {
  display: flex;
  align-items: center;
  gap: 26px;
}

.sc-nav__brand {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-right: auto;
}

.sc-nav__brand:hover {
  color: inherit;
}

.sc-wordmark {
  height: 19px;
  width: auto;
  flex: none;
}

.sc-nav__rule {
  width: 1px;
  height: 18px;
  flex: none;
  background: rgba(255, 255, 255, 0.12);
}

.sc-powered {
  display: flex;
  align-items: center;
  gap: 7px;
}

.sc-powered svg {
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 3px;
}

.sc-powered .mono {
  letter-spacing: 0.16em;
  font-weight: 500;
  color: var(--sc-muted);
  white-space: nowrap;
}

.sc-powered b {
  color: var(--sc-green);
  font-weight: 700;
}

.sc-nav__links {
  display: flex;
  gap: 2px;
}

.sc-navlink {
  display: block;
  padding: 7px 11px;
  border-radius: 9px;
  font-size: 13.5px;
  color: var(--sc-muted);
  white-space: nowrap;
  transition: color 0.15s, background 0.15s;
}

.sc-navlink:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.06);
}

.sc-nav__actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* The sheet trigger. Absent above 1060px, where the anchors are visible — and
   absent below it too until site.js has confirmed `<dialog>.showModal` and set
   `has-sheet` on the root. Nothing but script can open the sheet, so a
   no-script visitor must never be shown the button (see site.js). */
.sc-nav__toggle {
  position: relative;
  display: none;
  align-items: center;
  gap: 9px;
  padding: 8px 13px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid rgba(255, 255, 255, 0.13);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sc-text2);
}

.sc-nav__toggle:hover {
  background: rgba(255, 255, 255, 0.075);
  border-color: rgba(255, 255, 255, 0.24);
}

/* ── Nav touch targets ───────────────────────────────────────────────────
   The nav's controls are painted small on purpose. Measured, the burger is
   39x29 below 430px and 91.5x35 above it, and the Download button is 37.5
   tall at every width — all under the 44px floor a finger needs, and the
   burger is the one control a phone visitor MUST hit to reach the sections.

   The obvious fix is padding, and it is the wrong one here. The block at the
   bottom of this file that shrinks the burger below 430px exists because the
   header's three intrinsically-sized items stop fitting the row and flexbox
   pays for the shortfall by squashing the wordmark to an illegible smear.
   Padding the controls back up would spend exactly the horizontal room that
   block bought.

   So the HIT AREA grows and the PAINTED BOX does not. An empty, transparent
   `::after` is centred over each control and floored at 44px in both axes; it
   is inside the button, so a press on it is a press on the button, and it is
   out of flow, so the row's layout is untouched.

   The overhang stays inside the gaps, so nothing here overlaps its neighbour.
   The burger grows 2.5px each side at its narrowest — 44 against a painted 39
   — into an 8px gap; the buttons grow on the Y axis only, both being wider
   than 44px already. Those two numbers are rendered geometry and no VM test
   can see them, so `site_hero_facade_test.dart` pins the RULE (a centred
   `::after` floored at 44, on a control that is not itself padded up) and the
   measurement is the browser pass on the PR. */
.sc-nav__toggle::after,
.sc-nav__actions .sc-btn--sm::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

.sc-nav__actions .sc-btn--sm {
  position: relative;
}

.sc-burger {
  width: 15px;
  height: 11px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
}

/* ── Mobile sheet ────────────────────────────────────────────────────────
   A native <dialog> opened with showModal(), so Escape, the focus trap and
   inert-ing the page behind it are the platform's job rather than ours. */

/* Without <dialog> support the UA stylesheet's own
   `dialog:not([open]){display:none}` is absent too, and the sheet would sit
   in the flow permanently visible. Stated here so the closed state does not
   depend on the element being implemented. */
dialog:not([open]) {
  display: none;
}

/* Set while the sheet is open — showModal() does not reliably stop the page
   behind it scrolling. */
.is-menu-open,
.is-menu-open body {
  overflow: hidden;
}

.sc-sheet {
  position: fixed;
  margin: 0 0 0 auto;
  inset: 0 0 0 auto;
  width: min(360px, 90vw);
  max-width: none;
  max-height: none;
  height: 100%;
  padding: 0;
  border: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.08);
  background: var(--sc-ink2);
  color: var(--sc-text);
  overflow-y: auto;
}

.sc-sheet::backdrop {
  background: rgba(3, 5, 9, 0.72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.sc-sheet[open] {
  animation: scSheetIn 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);
}

@keyframes scSheetIn {
  from {
    transform: translateX(100%);
  }
  to {
    transform: none;
  }
}

.sc-sheet__inner {
  display: flex;
  flex-direction: column;
  gap: 26px;
  padding: 20px 24px 32px;
  min-height: 100%;
}

.sc-sheet__head {
  display: flex;
  align-items: center;
  gap: 14px;
  height: calc(var(--nav-h) - 20px);
}

.sc-sheet__close {
  margin-left: auto;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.13);
  background: rgba(255, 255, 255, 0.035);
  color: var(--sc-text2);
}

.sc-sheet__close:hover {
  background: rgba(255, 255, 255, 0.075);
}

.sc-sheet__close svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.sc-sheet__links {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sc-sheet__links a {
  padding: 13px 12px;
  border-radius: 10px;
  font-size: 16px;
  font-weight: 500;
  color: var(--sc-text);
}

.sc-sheet__links a:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}

.sc-sheet__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: auto;
}

/* ── Hero ────────────────────────────────────────────────────────────── */

.sc-hero {
  position: relative;
  padding: calc(var(--nav-h) + 84px) 0 0;
  overflow: hidden;
}

.sc-hero__glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}

.sc-hero__glow::before,
.sc-hero__glow::after {
  content: '';
  position: absolute;
}

.sc-hero__glow::before {
  top: -320px;
  left: 50%;
  width: 1500px;
  height: 760px;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse at center,
    rgba(225, 29, 39, 0.16),
    transparent 66%
  );
}

.sc-hero__glow::after {
  top: 200px;
  right: -200px;
  width: 820px;
  height: 620px;
  background: radial-gradient(
    ellipse at center,
    rgba(181, 127, 255, 0.07),
    transparent 68%
  );
}

/* The vertical rule field behind the hero. Decorative only. */
.sc-hero__rules {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.35;
  background: repeating-linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.028) 0 1px,
    transparent 1px 128px
  );
}

.sc-hero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 44px;
}

.sc-hero__copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  max-width: 880px;
  text-align: center;
}

.sc-hero__copy .sc-lede {
  max-width: 580px;
}

.sc-hero__note {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sc-hero__note .mono {
  letter-spacing: 0.2em;
  color: var(--sc-label);
}

/* Green = live/status. This is the one place on the page it appears as a
   standalone accent, and it is a status dot. */
.sc-dot {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 99px;
  background: var(--sc-green);
  box-shadow: 0 0 9px var(--sc-green);
  animation: scPulse 1.8s ease-in-out infinite;
}

@keyframes scPulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.sc-pillars {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 0;
  align-items: center;
  justify-content: center;
}

.sc-pillars li {
  display: flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--sc-muted);
}

.sc-pillars li + li::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.16);
  margin: 0 clamp(8px, 1.2vw, 16px);
}

/* ── Embedded app mocks ──────────────────────────────────────────────────
   Real DOM at the app's own geometry, never a raster screenshot. The frame
   carries the app window's chrome (14px radius, hairline, deep shadow) and
   a red wash behind it.

   `:has(:empty)` hides the whole embed — glow, frame and caption — while
   its slot has no content, so a mock that lands in a later PR leaves no
   hole in this one. */
.sc-embed {
  position: relative;
  margin-top: 52px;
}

.sc-embed:has(> .sc-embed__frame:empty) {
  display: none;
}

.sc-embed__glow {
  position: absolute;
  inset: -24px -14px 30px;
  pointer-events: none;
  background: radial-gradient(
    ellipse at 50% 20%,
    rgba(225, 29, 39, 0.11),
    transparent 70%
  );
}

.sc-embed__frame,
.sc-mockframe {
  position: relative;
  width: 100%;
  border-radius: 14px;
  overflow: hidden;
  background: var(--sc-ink2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.7),
    inset 0 0 0 1px rgba(255, 255, 255, 0.03);
}

.sc-caption {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 14px;
}

.sc-caption::before,
.sc-caption::after {
  content: '';
  width: 22px;
  height: 1px;
  background: rgba(255, 255, 255, 0.14);
}

.sc-caption .mono {
  letter-spacing: 0.22em;
  color: var(--sc-label);
}

/* ── The hero's sim-media band ────────────────────────────────────────────
   A strip of in-game media directly above the telemetry window, per the
   `design_handoff_hero_media` bundle on the NAS. It is decoration and carries
   `aria-hidden` in the markup, so nothing here holds meaning a reader loses.

   BOTH MASKS ARE THE EFFECT, not a polish pass on it. Horizontally the band
   dissolves into the page at 14% and 86% so it has no rectangle edges to give
   itself away as a pasted-in photograph; vertically it fades up into the
   headline area and out at the bottom, where `.sc-heroshell`'s lift tucks the
   window over what is left. Drop either one and the hero gains a hard-edged
   picture instead of atmosphere.

   `brightness(.78)` is the same argument in a third axis: at full brightness
   the media competes with the red CTA sitting directly above it, which is the
   one thing on this page that has to win. */
.sc-heroband {
  position: relative;
  width: 100%;
  height: clamp(180px, 20vw, 268px);
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 14%,
    #000 86%,
    transparent 100%
  );
  mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 14%,
    #000 86%,
    transparent 100%
  );
}

/* WebP, not the PNG the handoff bundles. The source render is 1,398,591 bytes
   and this band sits at the top of the fold on every visit, so shipping it
   would have made the decoration the largest thing on the page and almost
   certainly the LCP element — on the same phones the facade two rules down
   exists to keep light. Re-encoded at q80 it is 97,324 bytes, and what would
   show the difference is masked on two axes and darkened to 78% anyway.
   The handoff's own check list asks for exactly this to be confirmed. */
.sc-heroband-img {
  position: absolute;
  inset: 0;
  background: url('simcoach-lmp2.webp?v=4370205c') no-repeat center 30% / cover;
  filter: saturate(0.84) contrast(1.05) brightness(0.78);
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 26%,
    #000 58%,
    transparent 97%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 26%,
    #000 58%,
    transparent 97%
  );
}

/* Inside the horizontal mask's solid region (14%–86%), not over its fade. */
.sc-heroband-credit {
  position: absolute;
  left: 15%;
  top: 34px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 12px 5px 10px;
  border-radius: 99px;
  background: rgba(6, 8, 12, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.sc-heroband-credit .dot {
  width: 5px;
  height: 5px;
  border-radius: 99px;
  background: var(--sc-red);
  box-shadow: 0 0 8px rgba(225, 29, 39, 0.7);
}

.sc-heroband-credit .txt {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: lowercase;
  color: rgba(255, 255, 255, 0.82);
  white-space: nowrap;
}

/* Below 900px the band comes OFF, where the handoff shrinks it to 150px.
   Measured on a 390x844 phone: a 150px band leaves 4px of the telemetry
   window above the fold, where 100px stood before it. That trades the one
   thing on this page worth showing a phone visitor first — the product,
   running — for a photograph of a car, and charges them 97,324 bytes for the
   swap, on exactly the viewports the facade further down exists to keep
   light. Desktop and large tablet get the band exactly as designed.

   `display: none` is also what stops the fetch: a background image inside a
   `display: none` subtree is never requested. Measured in Chromium at 390px —
   zero bytes of `simcoach-lmp2.webp` on the wire, against 97,324 at 901px —
   which is the whole reason this is `display: none` and not `height: 0`, and
   why `site_hero_band_test` pins the declaration to that exact word. A VM
   test cannot run a browser, so it holds the shape the measurement proved,
   not the measurement.

   The credit chip needs no rule of its own any more: it lives inside the
   band, so it goes when the band goes. */
@media (max-width: 900px) {
  .sc-heroband {
    display: none;
  }
}

/* The hero's Flutter host. It must carry its own size — a Flutter view
   mounted via `hostElement` fills its host, so an auto-height container
   collapses to zero and the hero never paints. 3:2 is the app window's own
   1200x800 geometry. */
.sc-hero__mock {
  position: relative;
  width: 100%;
  max-width: 1200px;
  margin-top: 8px;
}

.sc-hero__mock::before {
  content: '';
  position: absolute;
  inset: -40px -30px 40px;
  pointer-events: none;
  background: radial-gradient(
    ellipse at 50% 30%,
    rgba(225, 29, 39, 0.18),
    transparent 70%
  );
}

#hero-mock {
  position: relative;
  aspect-ratio: 3 / 2;
  min-height: 320px;
}

/* THE PHONE BAND GETS THE POSTER'S OWN SHAPE, and the live hero gets it too.
   3/2 with a 320px floor is not a designed proportion — the floor exists only
   so a Flutter view mounted via `hostElement` cannot collapse to zero height.
   Left alone across the facade band it makes the host's aspect swing from
   0.86 at a 320px viewport to 1.50 from 524px up, and one still image cannot
   fill a moving shape: measured against the local bundle, `object-fit:
   contain` left 21.4% of the frame empty at 320px, 21.6% at 480 and 28.6% at
   700 — bars up to 185px wide inside a bordered frame, not the "few pixels of
   ground" the note below this once claimed (Codex, PR #332).

   Pinning the band to the poster's own 346:320 removes the variance rather
   than papering over it: the still fills the frame exactly at every width, so
   there are no bars to hide. It is applied to the host itself, NOT to a
   facade-only class, so the box does not change size when the visitor taps —
   the live hero mounts into the same rectangle the still occupied, and the
   page does not jump underneath the thing they just pressed.

   That does move the live board's geometry, which the first cut of this PR
   deliberately avoided. It is a real trade and it goes both ways: a 700px host
   gains height (437 -> 607), a 320px one loses it (320 -> 255). The small end
   is the one that needed checking, and it lands inside the tier the board
   already supports — `site_telemetry_hero.dart` documents measured board
   heights of "98 / 178 / 282 ...", and there are widget tests at Size(276,320)
   and Size(276,240) either side of it. `site_hero_facade_test.dart` pins both
   new extremes so this cannot regress unseen. */
@media (max-width: 700px) {
  #hero-mock {
    aspect-ratio: 346 / 320;
    min-height: 0;
  }
}

.hero-fallback {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 32px;
  text-align: center;
  color: var(--sc-muted);
  font-size: 14.5px;
}

/* ── The hero's phone facade ─────────────────────────────────────────────
   A still of the hero, plus the control that replaces it with the real thing.
   Both are `hidden` in the markup and revealed by boot.js, which also owns the
   width they appear at — there is no breakpoint here, deliberately, so the
   number lives in exactly one file.

   `#hero-mock` KEEPS ITS BOX ACROSS THE SWAP. The facade changes what fills
   the host, never its geometry — the phone band's `346 / 320` above is what
   the still occupies AND what the live hero mounts into, so tapping the
   control cannot move the page or land the Flutter board in a layout tier no
   widget test has ever seen. */

/* The positioning context for the two overlays. `#hero-mock` is its only
   in-flow child and carries all the sizing, so this box IS the host's box —
   which is what lets `inset` below mean "the host's rectangle" without either
   overlay living inside the element Flutter clears. */
.sc-heroshell {
  position: relative;
  /* Tucks the window over the bottom of the media band above it, so the two
     read as one object rather than a picture with a screenshot under it. The
     band's vertical mask is already fading out across this overlap.

     `z-index` is required, not decorative: the band is a positioned sibling
     that comes first in the DOM, so at `auto` the two paint in source order
     and the band's lower fade lands ON TOP of the window's frame. */
  margin-top: -54px;
  z-index: 2;
}

/* PLACEMENT IS LOAD-BEARING: this has to sit AFTER the rule above, not with
   the band's own 900px block further up the file. A media query adds no
   specificity, so both rules are one class selector and the later one wins —
   put this where the band rules are and `-54px` simply overrides it, lifting
   the window 54px into the pillars above it with no band there to tuck under.
   Which is why `site_hero_band_test` asserts the two rules' ORDER in the file
   rather than merely that both exist: existence is what the broken version
   has too. Confirmed against a browser at 390px — computed margin-top 0px. */
@media (max-width: 900px) {
  .sc-heroshell {
    margin-top: 0;
  }
}

.sc-heroposter {
  position: absolute;
  /* 1px, not 0: `.sc-mockframe`'s hairline border is now OUTSIDE the poster
     rather than around it, and insetting by its width puts the still exactly
     where it sat when it was a child of the frame — measured at 274x318 inside
     a 276x320 host. The radius follows it in, one pixel tighter than the
     frame's 14px, because the frame's `overflow: hidden` no longer clips it. */
  inset: 1px;
  border-radius: 13px;
  /* Sized explicitly, NOT left to `auto`. An `<img>` is a replaced element, so
     `width: auto` on an absolutely positioned one takes the INTRINSIC width
     (1038px here) and ignores the `right` offset entirely — the reset's
     `max-width: 100%` then clamped it back to the full 346px and the still
     hung 1px past the shell on two sides. Measured, not reasoned about: the
     computed box read 346x320 inside a 346x320 shell. Subtracting the two
     insets by hand is what actually fits it. */
  width: calc(100% - 2px);
  height: calc(100% - 2px);
  /* `contain`, not `cover`, and now it is a belt-and-braces choice rather than
     a load-bearing one: the host carries the poster's own 346:320 across the
     whole facade band, so the fitted box IS the host box and there is nothing
     to letterbox. `contain` is kept so that if the two ever drift — a new
     capture geometry, an edited breakpoint — the instrument shrinks intact
     instead of being silently cropped, and the sizing test catches the drift.
     The ground behind it matches the poster's own (`--sc-ink`) either way. */
  object-fit: contain;
  background: var(--sc-ink);
}

/* Bottom-centred rather than over the middle: the track map is the half of
   the picture worth seeing, and a control on top of it would sell the hero
   short in the state most phone visitors will only ever see. */
.sc-heroplay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 16px;
  /* Centred with auto margins rather than a translate. Two later rules write
     `transform` on this element — `.sc-cta:hover` lifts it 1px, and the
     reduced-motion block sets `transform: none` — and either one would drop a
     centring translate and slide the button off by half its width. Auto
     margins are not `transform`, so neither can reach them. */
  width: max-content;
  margin: 0 auto;
  /* The touch-target floor, on the one control this page adds. `.sc-btn--sm`
     alone measures 37.5px tall. */
  min-height: 44px;
  padding: 11px 18px;
  z-index: 1;
}

.sc-heroplay__glyph {
  width: 11px;
  height: 13px;
}

/* ── Booking mock ────────────────────────────────────────────────────────
   Step 4 of the in-app coaching wizard, drawn at the app's own geometry:
   a 1320x752 window, chrome 46/90/30 (the hero's `SiteAppWindow` constants),
   a 190 steps rail, a 288 summary panel, 40/28 page padding and 28 between
   panes (`BookingWizardScaffold`).

   SCALED WHOLE, not reflowed. Every length below is `N * --u`, where `--u` is
   one design pixel: the frame's own width over 1320. At the widest the page
   ever gives it (1200px) that is 0.909, so the mock is never enlarged past the
   geometry it was drawn at, and at every narrower width the picture shrinks
   intact — type, gaps, radii and grid together — instead of rewrapping into a
   layout the app does not have. Hairlines stay literal `1px`: a border is a
   hairline in the app too, and scaling it produces a grey blur rather than a
   line.

   The quiet end of the ink ramp (`--sc-dim`, `--sc-faint`) is used freely in
   here and NOWHERE in site copy — see the note on those tokens. This is a
   picture of an app, which is the exemption the handoff's a11y note draws, and
   the whole subtree is `aria-hidden` with the section's own copy carrying the
   meaning.

   Nothing in here animates or transitions, at any preference. */

.bk {
  /* Container-query fallback, for engines without `container-type` (pre-2023).
     The scale then tracks the VIEWPORT instead of the frame, which overshoots
     by the width of a vertical scrollbar; the frame's `overflow: hidden`
     absorbs that. `--gutter` is the same token the wrap is inset by, so this
     follows the 900px breakpoint without a second rule. */
  --u: calc((min(100vw, var(--wrap)) - 2 * var(--gutter)) / 1320);

  --bk-line: #1A2029;

  width: calc(1320 * var(--u));
  height: calc(752 * var(--u));
  display: flex;
  flex-direction: column;
  background: var(--sc-ink);
  color: var(--sc-text);
  font-family: var(--font-ui);
  line-height: 1.3;
}

@supports (container-type: inline-size) {
  #booking-mock {
    container-type: inline-size;
  }

  .bk {
    --u: calc(100cqw / 1320);
  }
}

/* Window chrome — title bar and status footer. */

.bk__title,
.bk__status {
  flex: none;
  display: flex;
  align-items: center;
  padding: 0 calc(14 * var(--u));
  background: var(--sc-ink2);
}

.bk__title {
  gap: calc(10 * var(--u));
  height: calc(46 * var(--u));
  border-bottom: 1px solid var(--bk-line);
}

.bk__dot {
  width: calc(10 * var(--u));
  height: calc(10 * var(--u));
  flex: none;
  border-radius: 99px;
  background: var(--sc-red);
}

.bk__name {
  font-family: var(--font-mono);
  font-size: calc(11.5 * var(--u));
  font-weight: 700;
  letter-spacing: calc(1.4 * var(--u));
  color: var(--sc-text);
}

.bk__winctl {
  margin-left: auto;
  width: calc(44 * var(--u));
  height: calc(8 * var(--u));
  fill: none;
  stroke: var(--sc-dim);
  stroke-width: 1;
}

.bk__status {
  height: calc(30 * var(--u));
  border-top: 1px solid var(--bk-line);
  font-family: var(--font-mono);
  font-size: calc(9 * var(--u));
  letter-spacing: calc(0.9 * var(--u));
  text-transform: uppercase;
  color: var(--sc-dim);
}

/* Nav rail. */

.bk__main {
  flex: 1;
  display: flex;
  min-height: 0;
}

.bk__nav {
  width: calc(90 * var(--u));
  flex: none;
  display: flex;
  flex-direction: column;
  padding: calc(10 * var(--u)) 0;
  background: #080B10;
  border-right: 1px solid var(--bk-line);
}

.bk__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: calc(3 * var(--u)) calc(8 * var(--u));
  padding: calc(7 * var(--u)) 0;
  border-radius: calc(7 * var(--u));
  color: var(--sc-dim);
}

.bk__tile.is-on {
  background: #14181F;
  color: var(--sc-red);
}

.bk__tile svg {
  width: calc(17 * var(--u));
  height: calc(17 * var(--u));
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.bk__tile-l {
  margin-top: calc(4 * var(--u));
  font-family: var(--font-mono);
  font-size: calc(6.5 * var(--u));
  font-weight: 700;
  letter-spacing: calc(0.6 * var(--u));
  color: inherit;
}

.bk__tile.is-on .bk__tile-l {
  color: var(--sc-text);
}

.bk__badge {
  margin-top: calc(3 * var(--u));
  padding: calc(1 * var(--u)) calc(4 * var(--u));
  border-radius: calc(3 * var(--u));
  background: var(--bk-line);
  font-family: var(--font-mono);
  font-size: calc(6 * var(--u));
  font-weight: 700;
  letter-spacing: calc(0.4 * var(--u));
  color: #8B96A4;
}

/* The wizard's three panes. */

.bk__page {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: calc(28 * var(--u));
  padding: calc(28 * var(--u)) calc(40 * var(--u)) calc(40 * var(--u));
  /* The app's own backdrop, not decoration invented for the page: a step-4
     screen genuinely leaves the lower half of the content area empty, and in
     the app that area carries `backdropWash` / `backdropGlow` rather than flat
     ground. Sized in percentages so it scales with everything else. */
  background:
    radial-gradient(
      ellipse 70% 55% at 78% 86%,
      rgba(94, 10, 16, 0.22),
      transparent 70%
    ),
    radial-gradient(
      ellipse 62% 50% at 10% 16%,
      rgba(255, 73, 84, 0.045),
      transparent 70%
    ),
    var(--sc-ink2);
}

.bk__eyebrow {
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
  font-family: var(--font-mono);
  font-size: calc(10 * var(--u));
  font-weight: 700;
  letter-spacing: calc(1.6 * var(--u));
  text-transform: uppercase;
  color: var(--sc-red-soft);
}

.bk__eyebrow::before {
  content: '';
  width: calc(6 * var(--u));
  height: calc(6 * var(--u));
  flex: none;
  border-radius: 99px;
  background: var(--sc-red);
}

/* Steps rail (190). */

.bk__steps {
  width: calc(190 * var(--u));
  flex: none;
}

.bk__steps .bk__eyebrow {
  margin-bottom: calc(20 * var(--u));
}

.bk__step {
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
  padding: calc(8 * var(--u));
  margin-bottom: calc(4 * var(--u));
  border: 1px solid transparent;
  border-radius: calc(8 * var(--u));
}

.bk__bar {
  width: calc(3 * var(--u));
  height: calc(18 * var(--u));
  flex: none;
  border-radius: calc(2 * var(--u));
}

.bk__disc {
  width: calc(20 * var(--u));
  height: calc(20 * var(--u));
  flex: none;
  display: grid;
  place-items: center;
  margin-right: calc(2 * var(--u));
  border: 1px solid var(--sc-faint);
  border-radius: 99px;
  font-family: var(--font-mono);
  font-size: calc(11 * var(--u));
  font-weight: 600;
  color: var(--sc-dim);
}

.bk__disc svg {
  width: calc(12 * var(--u));
  height: calc(12 * var(--u));
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.bk__step-l {
  font-size: calc(13 * var(--u));
  color: var(--sc-dim);
}

.bk__step.is-done .bk__disc {
  background: rgba(225, 29, 39, 0.14);
  border-color: rgba(225, 29, 39, 0.45);
  color: var(--sc-red);
}

.bk__step.is-done .bk__step-l {
  color: var(--sc-text2);
}

.bk__step.is-now {
  background: rgba(225, 29, 39, 0.08);
  border-color: rgba(225, 29, 39, 0.25);
}

.bk__step.is-now .bk__bar {
  background: var(--sc-red);
}

.bk__step.is-now .bk__disc {
  background: rgba(225, 29, 39, 0.12);
  border-color: rgba(225, 29, 39, 0.6);
  color: var(--sc-red);
}

.bk__step.is-now .bk__step-l {
  font-weight: 600;
  color: var(--sc-text);
}

/* Centre pane. */

.bk__centre {
  flex: 1;
  min-width: 0;
}

.bk__centre .bk__eyebrow {
  margin-bottom: calc(12 * var(--u));
}

/* Deliberately a <p>: it is drawn as the step headline but is not one. The
   display face and tight leading the `h1..h4` reset would have given it are
   therefore set here instead. */
.bk__h {
  font-family: var(--font-display);
  font-size: calc(26 * var(--u));
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: calc(-0.5 * var(--u));
  color: var(--sc-text);
}

.bk__sub {
  margin-top: calc(9 * var(--u));
  font-size: calc(13.5 * var(--u));
  color: var(--sc-muted);
}

.bk__slots {
  display: flex;
  gap: calc(24 * var(--u));
  margin-top: calc(22 * var(--u));
}

/* Calendar (288). */

.bk__cal {
  width: calc(288 * var(--u));
  flex: none;
}

.bk__cal-top {
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
}

.bk__cal-m {
  flex: 1;
  font-family: var(--font-display);
  font-size: calc(17 * var(--u));
  font-weight: 700;
  color: var(--sc-text);
}

.bk__cal-nav {
  width: calc(28 * var(--u));
  height: calc(28 * var(--u));
  flex: none;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: calc(8 * var(--u));
  color: var(--sc-text2);
}

.bk__cal-nav.is-off {
  border-color: rgba(255, 255, 255, 0.04);
  color: var(--sc-faint);
}

.bk__cal-nav svg {
  width: calc(6 * var(--u));
  height: calc(9 * var(--u));
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.bk__cal-nav.is-off svg {
  transform: scaleX(-1);
}

.bk__cal-w,
.bk__cal-g {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.bk__cal-w {
  margin-top: calc(14 * var(--u));
}

.bk__cal-w span {
  text-align: center;
  font-family: var(--font-mono);
  font-size: calc(10 * var(--u));
  line-height: calc(20 * var(--u));
  color: var(--sc-dim);
}

.bk__cal-g {
  gap: calc(2 * var(--u));
  margin-top: calc(4 * var(--u));
}

.bk__d {
  height: calc(38 * var(--u));
  display: grid;
  place-items: center;
  border-radius: calc(9 * var(--u));
  font-size: calc(13 * var(--u));
  color: var(--sc-faint);
}

.bk__d.is-sel {
  background: var(--sc-cta);
  font-weight: 700;
  color: #fff;
}

.bk__legend {
  display: flex;
  align-items: center;
  gap: calc(8 * var(--u));
  margin-top: calc(14 * var(--u));
  font-family: var(--font-mono);
  font-size: calc(10 * var(--u));
  letter-spacing: calc(0.4 * var(--u));
  color: var(--sc-muted);
}

.bk__legend-dot {
  width: calc(8 * var(--u));
  height: calc(8 * var(--u));
  flex: none;
  border-radius: 99px;
  background: var(--sc-red);
}

/* Day list. */

.bk__day {
  flex: 1;
  min-width: 0;
  padding-left: calc(24 * var(--u));
  border-left: 1px solid rgba(255, 255, 255, 0.06);
}

.bk__day-h {
  display: flex;
  align-items: baseline;
  gap: calc(10 * var(--u));
}

.bk__day-h > span:first-child {
  font-family: var(--font-display);
  font-size: calc(17 * var(--u));
  font-weight: 700;
  color: var(--sc-text);
}

.bk__day-c {
  font-family: var(--font-mono);
  font-size: calc(11 * var(--u));
  letter-spacing: calc(0.4 * var(--u));
  color: var(--sc-dim);
}

.bk__times {
  display: flex;
  gap: calc(10 * var(--u));
  margin-top: calc(14 * var(--u));
}

.bk__time {
  flex: 1;
  padding: calc(13 * var(--u)) calc(16 * var(--u));
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: calc(11 * var(--u));
  background: rgba(255, 255, 255, 0.04);
  font-family: var(--font-mono);
  font-size: calc(14 * var(--u));
  font-weight: 500;
  letter-spacing: calc(0.2 * var(--u));
  color: var(--sc-text2);
}

.bk__tz {
  margin-top: calc(16 * var(--u));
  font-size: calc(11.5 * var(--u));
  color: var(--sc-dim);
}

/* Summary panel (288). */

.bk__sum {
  width: calc(288 * var(--u));
  flex: none;
  padding: calc(18 * var(--u));
  background: var(--sc-glass);
  border: var(--sc-glass-border);
  border-radius: calc(14 * var(--u));
  box-shadow: var(--sc-glass-inset);
}

.bk__sum .bk__eyebrow {
  margin-bottom: calc(18 * var(--u));
}

.bk__row {
  display: flex;
  align-items: flex-start;
  gap: calc(10 * var(--u));
  margin-bottom: calc(12 * var(--u));
}

.bk__row-k {
  width: calc(78 * var(--u));
  flex: none;
  font-family: var(--font-mono);
  font-size: calc(10 * var(--u));
  letter-spacing: calc(1.2 * var(--u));
  color: var(--sc-dim);
}

.bk__row-v {
  flex: 1;
  text-align: right;
  font-size: calc(13 * var(--u));
  font-weight: 500;
  color: var(--sc-text);
}

.bk__row-v.is-unset {
  font-weight: 400;
  color: var(--sc-faint);
}

.bk__rule {
  display: block;
  height: 1px;
  margin: calc(6 * var(--u)) 0;
  background: rgba(255, 255, 255, 0.08);
}

.bk__total {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
  margin-top: calc(6 * var(--u));
}

.bk__total > span:first-child {
  font-size: calc(13 * var(--u));
  font-weight: 600;
  color: var(--sc-text2);
}

.bk__total-v {
  flex: 1;
  text-align: right;
  font-size: calc(15 * var(--u));
  font-weight: 600;
  color: var(--sc-text);
}

.bk__cta {
  display: block;
  width: max-content;
  margin: calc(16 * var(--u)) 0 0 auto;
  padding: calc(11 * var(--u)) calc(18 * var(--u));
  border: 1px solid var(--sc-cta-border);
  border-radius: calc(10 * var(--u));
  background: var(--sc-cta);
  font-size: calc(13 * var(--u));
  font-weight: 600;
  color: #fff;
}

.bk__foot {
  margin-top: calc(10 * var(--u));
  text-align: right;
  font-size: calc(11 * var(--u));
  color: var(--sc-dim);
}

/* ── #app — the feature grid ─────────────────────────────────────────── */

.sc-feature {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 22px 22px 24px;
}

.sc-feature__icon {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  background: linear-gradient(
    180deg,
    rgba(225, 29, 39, 0.18),
    rgba(139, 14, 20, 0.05)
  );
  border: 1px solid rgba(225, 29, 39, 0.3);
}

.sc-feature__icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--sc-red-light);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sc-feature__head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.sc-strip {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding: 20px 24px;
  border-radius: 16px;
}

.sc-strip__glyph {
  width: 20px;
  height: 20px;
  flex: none;
  fill: var(--sc-text2);
  opacity: 0.9;
}

.sc-strip__text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 220px;
}

.sc-strip__text strong {
  font-size: 14.5px;
  font-weight: 600;
  color: #fff;
}

.sc-strip__text .mono {
  letter-spacing: 0.18em;
  color: var(--sc-label);
}

/* ── #coaching ───────────────────────────────────────────────────────── */

#coaching {
  background: linear-gradient(
    180deg,
    transparent,
    rgba(225, 29, 39, 0.035),
    transparent
  );
}

/* ── #group ──────────────────────────────────────────────────────────── */

.sc-step {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px 22px;
}

.sc-step__n {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: rgba(255, 255, 255, 0.14);
  font-variant-numeric: tabular-nums;
}

/* Amber is the group-session accent (and SOON) — never a CTA colour. */
.sc-panel--amber {
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
  padding: 26px 28px;
  background: linear-gradient(
    100deg,
    rgba(240, 168, 48, 0.08),
    rgba(255, 255, 255, 0.008)
  );
  border: 1px solid rgba(240, 168, 48, 0.26);
}

.sc-panel__body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
  min-width: 260px;
}

.sc-panel__body .mono {
  letter-spacing: 0.24em;
  font-weight: 700;
  color: var(--sc-amber);
}

.sc-panel__body h3 {
  font-size: 24px;
  font-weight: 700;
}

.sc-panel__body p {
  font-size: 14.5px;
  color: var(--sc-text2);
  max-width: 520px;
}

.sc-panel__cta {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.sc-panel__cta .mono {
  letter-spacing: 0.16em;
  color: var(--sc-label);
  text-align: center;
}

/* ── #setups ─────────────────────────────────────────────────────────── */

#setups {
  background: linear-gradient(
    180deg,
    transparent,
    rgba(255, 255, 255, 0.014),
    transparent
  );
}

.sc-plans {
  max-width: 840px;
}

.sc-plan {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px 24px 26px;
}

.sc-plan--featured {
  border-color: rgba(225, 29, 39, 0.34);
  background: linear-gradient(
    180deg,
    rgba(225, 29, 39, 0.09),
    rgba(255, 255, 255, 0.006)
  );
}

.sc-plan__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 30px;
}

.sc-plan__meta .mono {
  letter-spacing: 0.24em;
  color: var(--sc-label);
}

.sc-plan--featured .sc-plan__meta .mono {
  color: var(--sc-red-soft);
}

.sc-plan__badge {
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 99px;
  background: rgba(225, 29, 39, 0.16);
  border: 1px solid rgba(225, 29, 39, 0.4);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sc-red-soft);
  line-height: 1.3;
}

/* The plan cards' titles. These are `<h3 class="sc-figure sc-plan__name">` —
   real headings, so they take the heading face like the other ten h3s on the
   page, but `.sc-figure` is a class and the `h1..h4` reset is an element
   selector, so without this line the cascade hands these two back to Archivo
   and the setups section is the one place where a card title does not match
   the rest of the page. Invisible before this change: both tokens resolved to
   Archivo, so the override existed and had nothing to do.
   `.sc-figure`'s other declarations are still wanted here — the tight leading,
   the white, the tracking — so it stays on the elements rather than being
   unpicked into this rule. */
.sc-plan__name {
  font-family: var(--font-heading);
  font-size: clamp(28px, 3vw, 36px);
}

.sc-plan .sc-body {
  flex: 1;
}

/* ── #download ───────────────────────────────────────────────────────── */

.sc-close {
  position: relative;
  padding: 110px 0 120px;
  overflow: hidden;
}

.sc-close__glow {
  position: absolute;
  bottom: -360px;
  left: 50%;
  width: 1400px;
  height: 700px;
  transform: translateX(-50%);
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    rgba(225, 29, 39, 0.2),
    transparent 66%
  );
}

.sc-close__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  text-align: center;
}

.sc-close__inner h2 {
  max-width: 780px;
}

.sc-close__inner .sc-lede {
  max-width: 560px;
}

.sc-close__inner .mono {
  letter-spacing: 0.2em;
  color: var(--sc-label);
}

/* ── Footer ──────────────────────────────────────────────────────────── */

.sc-footer {
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(3, 5, 9, 0.7);
  padding: 54px 0 34px;
}

.sc-footer__inner {
  display: flex;
  flex-direction: column;
  gap: 40px;
}

.sc-footer__cols {
  display: flex;
  gap: 56px;
  flex-wrap: wrap;
}

/* `align-items` must be pinned: a column flex container stretches its items
   across the cross axis by default, which blows the fixed-height wordmark out
   to the full column width. */
.sc-footer__brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  min-width: 250px;
  flex: 1;
}

.sc-footer__brand p {
  max-width: 300px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--sc-label);
}

.sc-footer__col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 140px;
}

.sc-footer__col h2 {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sc-label);
  line-height: 1.4;
}

.sc-footer__col a {
  font-size: 14px;
  color: var(--sc-text2);
}

.sc-footer__col a:hover {
  color: #fff;
}

.sc-footer__legal {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.sc-footer__legal .mono {
  letter-spacing: 0.16em;
  color: var(--sc-label);
}

.sc-footer__legal .mono:last-child {
  margin-left: auto;
}

/* ── Responsive ──────────────────────────────────────────────────────────
   The handoff's breakpoints, minus 1150 (that one governed hero direction B,
   which was explored and not chosen). */

@media (max-width: 1100px) {
  :root {
    --sec-y: 80px;
  }

  .sc-grid3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sc-navlink {
    font-size: 12.5px;
    padding: 6px 8px;
  }
}

@media (max-width: 1060px) {
  .sc-nav__links {
    display: none;
  }

  /* `has-sheet` is set by site.js only once showModal is known to exist. */
  .has-sheet .sc-nav__toggle {
    display: inline-flex;
  }
}

@media (max-width: 900px) {
  :root {
    --gutter: 22px;
  }

  .sc-nav__rule,
  .sc-nav__brand .sc-powered {
    display: none;
  }

  .sc-hero {
    padding-top: calc(var(--nav-h) + 56px);
  }

  .sc-footer__cols {
    gap: 34px;
  }
}

@media (max-width: 760px) {
  /* Log in lives in the sheet at this width; Download stays — it is the
     page's one conversion and it is only an in-page anchor. */
  .sc-nav__actions .sc-ghost {
    display: none;
  }
}

@media (max-width: 680px) {
  :root {
    --sec-y: 64px;
  }

  .sc-grid3,
  .sc-grid2 {
    grid-template-columns: minmax(0, 1fr);
  }

  .sc-stack {
    gap: 32px;
  }

  .sc-embed {
    margin-top: 34px;
  }

  .sc-close {
    padding: 72px 0 84px;
  }

  /* The flanking rules assume a single-line caption; once it wraps they
     strand themselves at opposite ends of two different lines. */
  .sc-caption::before,
  .sc-caption::after {
    display: none;
  }

  /* Same problem for the pillar separators — a wrapped list leaves an
     orphan dot at the head of the second line. Gap carries the rhythm
     instead. */
  .sc-pillars {
    gap: 8px 18px;
  }

  .sc-pillars li + li::before {
    display: none;
  }

  .sc-footer__legal .mono:last-child {
    margin-left: 0;
  }

  /* ── Booking mock, cropped to the pane that carries the step ───────────
     Above this width the mock is scaled WHOLE from `--u` and never reflows —
     see the section it is styled in. That property is what makes it a
     truthful picture of the app, and it is also what makes it unreadable on a
     phone: `--u` is the frame width over the app's own 1320px, so at a 390px
     viewport the whole 1320x752 window is drawn into 346px and its type runs
     1.56px to 6.78px. Nothing is wrong with the picture; there is simply no
     scale at which all three panes of a desktop wizard fit a phone.

     So below this width the mock stops being the whole window and becomes ONE
     PANE OF IT AT FULL SIZE. `--u` is pinned to 1px — the app's own design
     unit — and the panes a phone has no room for are dropped: the icon rail,
     the steps rail and the summary panel. What is left is the step's own
     content, rendered at exactly the size the app draws it: "Pick a time" at
     26px, the day cells at 13px, against 5.45px for the smallest type in the
     DESKTOP rendering of the same mock.

     NOTHING IS LOST BY DROPPING THEM. The whole subtree is `aria-hidden` and
     carries no copy of its own — the section's prose above it states what the
     picture shows, including the four-selection flow the steps rail draws —
     so this is a crop of a decoration, not a cut to the page's content.

     The rules live here, in the responsive section, rather than in the mock's
     own: the assertion that every length in that section is one design pixel
     times `--u` is the guard that keeps the DESKTOP picture from coming apart
     a rule at a time, and it is worth more intact than extended with
     exceptions. `site_booking_mock_test.dart` reads this block on its own. */
  .bk {
    /* The app's design unit, 1:1. Beats the `@supports` container-query rule
       above on source order — same specificity, later in the file. */
    --u: 1px;
    /* The window's fixed 1320x752 cannot survive into a cropped view: it is
       the geometry of the thing that is no longer being drawn. */
    width: auto;
    height: auto;
  }

  .bk__nav,
  .bk__steps,
  .bk__sum {
    display: none;
  }

  /* The window-control glyph is the one piece of chrome that means nothing
     once the window is cropped, and it is also the piece that does not fit:
     the title bar needs 307px at `--u: 1px` and a 320px viewport leaves 276.
     Without it, 253. The title itself stays — it is what says "this is the
     app", which is the whole reason the mock is on the page. */
  .bk__winctl {
    display: none;
  }

  .bk__page {
    padding: calc(18 * var(--u)) calc(14 * var(--u)) calc(22 * var(--u));
  }

  /* Calendar over day list, and both fluid. The calendar's fixed 288 design
     px is 12px wider than a 320px viewport leaves, and its seven columns are
     `minmax(0, 1fr)` already, so it fits by giving up the fixed width rather
     than by scaling the type back down. */
  .bk__slots {
    flex-direction: column;
    gap: calc(20 * var(--u));
  }

  .bk__cal {
    width: auto;
  }

  .bk__day {
    padding-left: 0;
    padding-top: calc(18 * var(--u));
    border-left: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
  }

  /* Stacked, the day heading has the pane's full width but not the desktop
     pane's: "Tuesday 28 July · 2 slots open" is a nowrap flex row that would
     otherwise be clipped by the frame's `overflow: hidden` on the narrowest
     phones. */
  .bk__day-h {
    flex-wrap: wrap;
  }

  /* ── Footer links, thumb-sized ─────────────────────────────────────────
     Measured, each link is 140x21 with a 12px gap — a 33px pitch, so a 44px
     target could only be reached by overlapping its neighbour, and a link
     whose hit area covers the one above it is worse than one that is small.
     The pitch has to grow, so it grows to exactly 44: `gap` goes to zero and
     each link becomes a 44px row. Adjacent targets then meet edge to edge and
     never overlap.

     Phone-scoped on purpose. This is a fix for fingers, and it costs the
     desktop footer's tighter rhythm nothing at a width where the columns sit
     side by side. */
  .sc-footer__col {
    gap: 0;
  }

  .sc-footer__col h2 {
    margin-bottom: 8px;
  }

  .sc-footer__col a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Hero eyebrow and status note, once their text wraps.
   Both are a decorative dot in a centred flex row. On one line the dot reads
   as a marker at the head of the label; once the label wraps, the row is
   still centred as a whole but the dot sits alone against the left edge of a
   two-line block, and reads as a stray. There is no way to ask CSS whether a
   line has wrapped, so this is a width — measured rather than guessed, on the
   shipped faces: the eyebrow wraps below 450px, the note below 480px, and 500
   is the first round width clear of both.

   The same fix, for the same reason, as the `.sc-caption` flanking rules at
   680px above — and, like those, pitched at the width where THIS element
   wraps rather than at a shared number. The section eyebrows keep their dots:
   they are left-aligned, so the dot stays at the head of the first line
   whatever the text does. So does #download's, which is centred but short
   enough that it never wraps at any width this page renders at. */
@media (max-width: 500px) {
  .sc-hero__copy .sc-eyebrow::before,
  .sc-hero__note .sc-dot {
    display: none;
  }
}

/* Header, narrow phones. Below ~385px the header's three intrinsically-sized
   items — wordmark, Download, Menu — stop fitting the gutter-inset row, and
   flexbox pays for the shortfall out of the only item that can give: the
   brand. Measured at a 320px viewport before this block, the wordmark
   rendered 36.3px wide against its intrinsic 101.3px — a 36% horizontal
   squash, i.e. an illegible smear where the logo should be. (Nothing was
   clipped or unreachable; the row absorbed it by distortion instead.)

   The fix takes the brand out of the shrink pool outright and buys the space
   back from the two controls: tighter gaps, and a Menu button reduced to its
   burger glyph. The label is clipped rather than `display: none` so the
   button keeps its accessible name. 320px is an iPhone SE, so this is a real
   device width and not a synthetic one. */
@media (max-width: 430px) {
  .sc-nav__inner {
    gap: 12px;
  }

  .sc-nav__brand {
    flex: none;
  }

  .sc-nav__actions {
    gap: 8px;
  }

  .sc-nav__toggle {
    padding: 8px 11px;
  }

  .sc-nav__toggle-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .sc-nav__actions .sc-btn--sm {
    padding: 8px 12px;
  }
}

/* ── Motion ──────────────────────────────────────────────────────────────
   Everything that moves is decorative. Under a reduced-motion preference it
   all stops — including the smooth scroll, which is motion the user did not
   ask for either. */

@keyframes scRise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.sc-rise {
  animation: scRise 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

.sc-rise--late {
  animation-delay: 0.12s;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .sc-cta:hover,
  .sc-ghost:hover,
  .sc-card-h:hover {
    transform: none;
  }
}
