/* ==========================================================================================
   site.css — one stylesheet, no build step, no framework.

   Structure:
     1.  Tokens and themes
     2.  Reset and base
     3.  Utilities
     4.  Buttons, badges, marks
     5.  Header and navigation
     6.  Hero and numbers strip
     7.  The problem, and its diagram
     8.  Steps
     9.  Comparison table
     10. Build / buy / subscribe
     11. Compatibility checker
     12. Kit
     13. Ecosystem
     14. Pricing
     15. Open source
     16. FAQ, final CTA, footer
     16b. Sign-in page
     16c. Shop, checkout and order status
     17. Print
     18. Reduced motion

   The palette is dark-first: the default token block is the dark theme, a light block is
   applied under `prefers-color-scheme: light`, and `[data-theme]` on <html> overrides both.
   Every colour that is not neutral derives from --accent, which is set at runtime from
   shared/brand.js via js/main.js. The literal below is only the pre-script fallback.
   ========================================================================================== */

/* ── 1. Tokens ──────────────────────────────────────────────────────────────────────── */

:root {
  /* --accent-brand is set at runtime from shared/brand.js by js/main.js. The literal here is
     only the value used before the module runs, and the light theme derives a darker shade
     from it rather than hardcoding a second colour — so a brand change is still one edit. */
  --accent: var(--accent-brand, #3B82F6);

  --surface-0: #0B0F19;
  --surface-1: #111726;
  --surface-2: #172032;
  --surface-3: #1E2941;
  --border: #26314A;

  --text: #E8ECF5;
  --text-dim: #9BA7BF;
  --text-faint: #6E7B95;

  --accent-ink: #06090F;
  --accent-soft: color-mix(in oklab, var(--accent) 16%, var(--surface-0));
  --accent-line: color-mix(in oklab, var(--accent) 42%, var(--surface-0));
  --accent-text: color-mix(in oklab, var(--accent) 82%, white);

  --good: #34D399;
  --warn: #FBBF24;
  --bad: #F87171;
  --good-soft: color-mix(in oklab, var(--good) 14%, var(--surface-0));
  --warn-soft: color-mix(in oklab, var(--warn) 14%, var(--surface-0));
  --bad-soft: color-mix(in oklab, var(--bad) 14%, var(--surface-0));

  --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 8px 24px -12px rgb(0 0 0 / 0.6);
  --radius: 14px;
  --radius-sm: 9px;

  --wrap: 74rem;
  --wrap-narrow: 46rem;
  --gutter: clamp(1.1rem, 4vw, 2.5rem);
  --section-y: clamp(3.5rem, 8vw, 7rem);

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  color-scheme: dark;
}

/* The light palette appears twice: once for visitors whose OS asks for it and who have not
   overridden the theme here, and once for the explicit `data-theme="light"` override. CSS has
   no way to share a declaration block between a media query and an attribute selector without
   a preprocessor, and a preprocessor is a build step.

   Both are scoped to `screen`. Screen themes are not a printing concern, and without the
   scope their attribute selectors out-specify the plain `:root` palette in the print block
   below — which is how a "print in black on white" rule silently loses to a screen theme. */
@media screen and (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --surface-0: #FFFFFF;
    --surface-1: #F6F8FC;
    --surface-2: #EDF1F8;
    --surface-3: #E3E9F4;
    --border: #D7DEEC;

    --text: #0D1220;
    --text-dim: #4C586F;
    --text-faint: #6D7891;

    --accent: color-mix(in oklab, var(--accent-brand, #3B82F6) 76%, black);
    --accent-ink: #FFFFFF;
    --accent-soft: color-mix(in oklab, var(--accent) 9%, white);
    --accent-line: color-mix(in oklab, var(--accent) 34%, white);
    --accent-text: color-mix(in oklab, var(--accent) 88%, black);

    --good: #0F9D6B;
    --warn: #B45309;
    --bad: #DC2626;
    --good-soft: color-mix(in oklab, var(--good) 10%, white);
    --warn-soft: color-mix(in oklab, var(--warn) 10%, white);
    --bad-soft: color-mix(in oklab, var(--bad) 10%, white);

    --shadow: 0 1px 2px rgb(16 24 40 / 0.06), 0 10px 28px -14px rgb(16 24 40 / 0.28);
    color-scheme: light;
  }
}

@media screen {
:root[data-theme="light"] {
  --surface-0: #FFFFFF;
  --surface-1: #F6F8FC;
  --surface-2: #EDF1F8;
  --surface-3: #E3E9F4;
  --border: #D7DEEC;

  --text: #0D1220;
  --text-dim: #4C586F;
  --text-faint: #6D7891;

  --accent: color-mix(in oklab, var(--accent-brand, #3B82F6) 76%, black);
  --accent-ink: #FFFFFF;
  --accent-soft: color-mix(in oklab, var(--accent) 9%, white);
  --accent-line: color-mix(in oklab, var(--accent) 34%, white);
  --accent-text: color-mix(in oklab, var(--accent) 88%, black);

  --good: #0F9D6B;
  --warn: #B45309;
  --bad: #DC2626;
  --good-soft: color-mix(in oklab, var(--good) 10%, white);
  --warn-soft: color-mix(in oklab, var(--warn) 10%, white);
  --bad-soft: color-mix(in oklab, var(--bad) 10%, white);

  --shadow: 0 1px 2px rgb(16 24 40 / 0.06), 0 10px 28px -14px rgb(16 24 40 / 0.28);
  color-scheme: light;
}
}

/* ── 2. Reset and base ──────────────────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;
}

body {
  margin: 0;
  background: var(--surface-0);
  color: var(--text);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5 { margin: 0; line-height: 1.18; font-weight: 640; letter-spacing: -0.017em; }
p, ul, ol, dl, figure, pre { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { max-width: 100%; }

a { color: var(--accent-text); text-decoration-color: color-mix(in oklab, currentColor 42%, transparent); text-underline-offset: 0.18em; }
a:hover { text-decoration-color: currentColor; }

code {
  font-family: var(--mono);
  font-size: 0.895em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.08em 0.34em;
  word-break: break-word;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: color-mix(in oklab, var(--accent) 34%, transparent); }

/* ── 3. Utilities ───────────────────────────────────────────────────────────────────── */

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

/* The `hidden` attribute is only `display: none` in the UA stylesheet, so any author rule
   setting `display` silently beats it — which is why the two component-level `[hidden]`
   overrides further down this file exist. This makes the guarantee global so the next
   component that needs a display mode does not have to remember. */
[hidden] { display: none !important; }

.section { padding-block: var(--section-y); border-top: 1px solid var(--border); }
.section__title { font-size: clamp(1.7rem, 4.4vw, 2.5rem); max-width: 22ch; margin-bottom: 0.7rem; }
.section__lead { color: var(--text-dim); font-size: clamp(1rem, 1.9vw, 1.13rem); max-width: 62ch; }

.eyebrow {
  font-size: 0.78rem;
  font-weight: 660;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.7rem;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: 0.5rem; left: 0.5rem;
  z-index: 100;
  transform: translateY(-200%);
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius-sm);
  font-weight: 620;
  text-decoration: none;
}
.skip-link:focus-visible { transform: translateY(0); }

.noscript {
  max-width: var(--wrap-narrow);
  margin: 4rem auto;
  padding: 1.2rem var(--gutter);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-dim);
}

/* Below-the-fold sections are skipped by layout and paint until they are near the viewport.
   `auto` in contain-intrinsic-size means the browser remembers the real size once measured,
   so the scrollbar does not jump around on the way back up. */
.defer { content-visibility: auto; contain-intrinsic-size: auto 1000px; }

.punchline {
  margin-top: 2.4rem;
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
  font-weight: 560;
  line-height: 1.42;
  max-width: 44ch;
  border-left: 3px solid var(--accent);
  padding-left: 1.1rem;
}
.punchline--sm { font-size: clamp(1rem, 1.8vw, 1.1rem); font-weight: 460; color: var(--text-dim); max-width: 68ch; }

.footnote { margin-top: 1.2rem; color: var(--text-faint); font-size: 0.9rem; max-width: 72ch; }

.aside {
  margin-top: 2.5rem;
  padding: 1.3rem 1.5rem;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  max-width: 68ch;
  color: var(--text-dim);
}
.aside__title { font-size: 1.02rem; margin-bottom: 0.4rem; color: var(--text); }
.aside--warn { border-left-color: var(--warn); background: var(--warn-soft); }

/* ── 4. Buttons, badges, marks ──────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.72rem 1.15rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.btn:active { transform: translateY(1px); }

/* A disabled button must not look like a live one. Until the shop existed nothing on this site
   rendered a disabled button, so this had no reason to exist — and its absence made every
   "Out of stock" card look like a working "Add to basket" in full accent blue. */
.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(0.6);
}
.btn:disabled:active { transform: none; }
.btn--lg { padding: 0.95rem 1.5rem; font-size: 1.03rem; }
.btn--sm { padding: 0.5rem 0.85rem; font-size: 0.87rem; }
.btn__icon { width: 1.05em; height: 1.05em; flex: none; }

.btn--primary { background: var(--accent); color: var(--accent-ink); }
.btn--primary:hover { background: color-mix(in oklab, var(--accent) 84%, white); }

.btn--secondary {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border);
}
.btn--secondary:hover { background: var(--surface-3); border-color: var(--accent-line); }

.btn--ghost { background: transparent; color: var(--text-dim); border-color: var(--border); }
.btn--ghost:hover { color: var(--text); border-color: var(--accent-line); }

.badge {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.075em;
  text-transform: uppercase;
  padding: 0.24rem 0.55rem;
  border-radius: 999px;
  border: 1px solid;
  margin-bottom: 0.85rem;
}
.badge--now { color: var(--good); border-color: color-mix(in oklab, var(--good) 45%, transparent); background: var(--good-soft); }
.badge--launch { color: var(--accent-text); border-color: var(--accent-line); background: var(--accent-soft); }
.badge--dev { color: var(--warn); border-color: color-mix(in oklab, var(--warn) 45%, transparent); background: var(--warn-soft); }
.badge--api { color: var(--text-dim); border-color: var(--border); background: var(--surface-2); }

.mark-wrap { display: inline-flex; flex: none; }
.mark { width: 1.05rem; height: 1.05rem; flex: none; }
.mark--yes { color: var(--good); }
.mark--no { color: var(--bad); }
.mark--partial { color: var(--warn); }

/* ── 5. Header and navigation ───────────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in oklab, var(--surface-0) 86%, transparent);
  backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--border);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 4rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--text);
  text-decoration: none;
  font-weight: 680;
  letter-spacing: -0.02em;
  font-size: 1.06rem;
  flex: none;
}
.wordmark__mark { width: 1.35rem; height: 1.35rem; color: var(--accent); }

.site-nav { margin-inline: auto; }
.site-nav__list { display: flex; gap: 0.35rem; }
.site-nav__list a {
  display: block;
  padding: 0.45rem 0.7rem;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.925rem;
  font-weight: 520;
}
.site-nav__list a:hover { color: var(--text); background: var(--surface-2); }

.site-header__actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }

.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 2.3rem; height: 2.3rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-dim);
  cursor: pointer;
}
.theme-toggle:hover { color: var(--text); border-color: var(--accent-line); }
.theme-toggle__icon { width: 1.05rem; height: 1.05rem; grid-area: 1 / 1; }
.theme-toggle[data-theme-state="dark"] .theme-toggle__icon--sun,
.theme-toggle[data-theme-state="light"] .theme-toggle__icon--moon { display: none; }

.nav-toggle {
  display: none;
  width: 2.3rem; height: 2.3rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text);
  cursor: pointer;
  padding: 0;
}
.nav-toggle__bars { display: grid; gap: 4px; justify-items: center; }
.nav-toggle__bars span { display: block; width: 1rem; height: 2px; background: currentColor; border-radius: 2px; }

.site-nav__panel { display: none; }

@media (max-width: 59.99rem) {
  .site-nav { display: none; }
  .nav-toggle { display: inline-grid; place-items: center; }
  .site-header__cta { display: none; }
  .site-nav__panel {
    display: block;
    border-top: 1px solid var(--border);
    background: var(--surface-1);
    padding: 0.6rem var(--gutter) 1rem;
  }
  .site-nav__panel[hidden] { display: none; }
  .site-nav__panel ul { display: grid; gap: 0.15rem; }
  .site-nav__panel a {
    display: block;
    padding: 0.7rem 0.6rem;
    border-radius: var(--radius-sm);
    color: var(--text);
    text-decoration: none;
    font-weight: 560;
  }
  .site-nav__panel a:hover { background: var(--surface-2); }
  /* The header CTA is hidden at this width to keep the bar uncluttered, so it is reinstated
     inside the panel — otherwise the primary action is unreachable from the mobile menu. */
  .site-nav__panel .btn--primary { display: flex; margin-top: 0.7rem; width: 100%; }
}

/* ── 6. Hero and numbers ────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  padding-block: clamp(3rem, 9vw, 6.5rem) clamp(2.5rem, 6vw, 4.5rem);
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  inset: -40% 20% auto -10%;
  height: 42rem;
  background: radial-gradient(50% 50% at 40% 50%, var(--accent-soft), transparent 72%);
  pointer-events: none;
  z-index: -1;
}
.hero__title {
  font-size: clamp(2.1rem, 6.2vw, 4rem);
  /* Wide enough that the headline reaches across a desktop viewport rather than stacking into
     a narrow four-line column with half the hero empty beside it. */
  max-width: 21ch;
  letter-spacing: -0.032em;
  margin-bottom: 1.1rem;
}
.hero__sub {
  font-size: clamp(1.03rem, 2.2vw, 1.24rem);
  color: var(--text-dim);
  max-width: 58ch;
  margin-bottom: 1.9rem;
}
.hero__ctas { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.hero__ctanote { margin-top: 0.7rem; font-size: 0.85rem; color: var(--text-faint); }

.trust {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.35rem;
  margin-top: 2.4rem;
  font-size: 0.885rem;
  color: var(--text-dim);
}
.trust__item { display: inline-flex; align-items: center; gap: 0.5rem; }
.trust__dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex: none; }

.stats { border-top: 1px solid var(--border); background: var(--surface-1); padding-block: clamp(2rem, 5vw, 3rem); }
/* auto-fit would leave a lone fourth stat stranded on its own row at tablet widths, so the
   column count is pinned rather than derived. */
.stats__list { display: grid; gap: 1.4rem; grid-template-columns: repeat(4, 1fr); }
@media (max-width: 62rem) { .stats__list { grid-template-columns: repeat(2, 1fr); gap: 1.6rem 1.4rem; } }
@media (max-width: 26rem) { .stats__list { grid-template-columns: 1fr; } }
.stat__value {
  font-size: clamp(1.85rem, 4.4vw, 2.5rem);
  font-weight: 680;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}
.stat__label { font-weight: 620; margin-top: 0.15rem; }
.stat__detail { color: var(--text-faint); font-size: 0.85rem; line-height: 1.5; margin-top: 0.3rem; }
.stats__note { margin-top: 1.6rem; color: var(--text-faint); font-size: 0.83rem; max-width: 74ch; }

/* ── 7. The problem, and its diagram ────────────────────────────────────────────────── */

.problem__points {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  margin-top: 2.4rem;
}
.point, .step {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.35rem;
}
.point__n, .step__n {
  display: inline-grid;
  place-items: center;
  width: 1.9rem; height: 1.9rem;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent-text);
  font-size: 0.85rem;
  font-weight: 700;
  margin-bottom: 0.9rem;
}
.point__title, .step__title { font-size: 1.08rem; margin-bottom: 0.45rem; }
.point__body, .step__body { color: var(--text-dim); font-size: 0.955rem; }

.diagram { margin-top: 2.8rem; }
.diagram__svg {
  display: block;
  width: 100%;
  height: auto;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.5rem;
}
.diagram__caption { margin-top: 0.9rem; color: var(--text-faint); font-size: 0.88rem; max-width: 74ch; }

.diagram__boundary { fill: none; stroke: var(--border); stroke-width: 1.5; stroke-dasharray: 7 6; }
.diagram__boundary-label { fill: var(--text-faint); font-size: 13px; font-family: var(--font); }

.diagram__node > rect,
.diagram__node > path { fill: var(--surface-2); stroke: var(--accent-line); stroke-width: 1.6; }
.diagram__screen { fill: var(--surface-0) !important; stroke: none !important; }
.diagram__label { fill: var(--text); font-size: 14px; font-weight: 600; font-family: var(--font); }
.diagram__led { fill: var(--good); stroke: none; }
.diagram__wave { stroke: var(--accent); stroke-width: 2; stroke-linecap: round; fill: none; }
.diagram__zzz { stroke: var(--text-faint); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; fill: none; }

.diagram__edge { fill: none; stroke: var(--accent-line); stroke-width: 2; }
.diagram__edge--blocked { stroke: var(--bad); stroke-dasharray: 6 7; opacity: 0.65; }
.diagram__edge-label { fill: var(--text-dim); font-size: 12.5px; font-family: var(--font); }
.diagram__edge-label--lan { fill: var(--accent-text); }
.diagram__edge-label--blocked { fill: var(--bad); }
.diagram__cross circle { fill: var(--surface-1); stroke: var(--bad); stroke-width: 2; }
.diagram__cross path { stroke: var(--bad); stroke-width: 2.4; stroke-linecap: round; }

.diagram__packet { fill: var(--accent); }
.diagram__packet--lan { fill: var(--good); }

/* ── 8. Steps ───────────────────────────────────────────────────────────────────────── */

.steps {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  margin-top: 2.4rem;
  counter-reset: step;
}

/* ── 9. Comparison table ────────────────────────────────────────────────────────────── */

.table-hint { display: none; color: var(--text-faint); font-size: 0.85rem; margin-top: 1.6rem; }
.table-scroll {
  margin-top: 1.6rem;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-1);
}
.compare { width: 100%; border-collapse: collapse; min-width: 56rem; font-size: 0.9rem; }
.compare th, .compare td { text-align: left; vertical-align: top; padding: 0.85rem 0.95rem; border-bottom: 1px solid var(--border); }
.compare thead th { border-bottom: 1px solid var(--border); background: var(--surface-2); position: sticky; top: 0; }
.compare__col-label { display: block; font-weight: 680; }
.compare__col-sub { display: block; font-weight: 420; color: var(--text-faint); font-size: 0.8rem; margin-top: 0.15rem; }
.compare__col.is-us, .compare td.is-us { background: var(--accent-soft); }
.compare__col.is-us .compare__col-label { color: var(--accent-text); }

.compare__row-label {
  position: sticky;
  left: 0;
  background: var(--surface-1);
  min-width: 15rem;
  max-width: 19rem;
  border-right: 1px solid var(--border);
}
.compare__row-title { display: block; font-weight: 620; }
.compare__row-detail { display: block; color: var(--text-faint); font-weight: 400; font-size: 0.815rem; margin-top: 0.25rem; line-height: 1.45; }

.compare td { min-width: 9.5rem; }
.compare td .mark-wrap { display: block; margin-bottom: 0.3rem; }
.compare__cell-text { color: var(--text-dim); font-size: 0.855rem; line-height: 1.45; }

.compare tr.is-loss th, .compare tr.is-loss td { background: var(--warn-soft); }
.compare tr.is-loss .compare__row-label { box-shadow: inset 3px 0 0 var(--warn); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }

@media (max-width: 60rem) { .table-hint { display: block; } }

/* ── 10. Build / buy / subscribe ────────────────────────────────────────────────────── */

.paths {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  margin-top: 2.4rem;
}
.path-card {
  display: flex;
  flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
}
.path-card__kicker {
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--accent-text); margin-bottom: 0.6rem;
}
.path-card__title { font-size: 1.22rem; margin-bottom: 0.6rem; }
.path-card__body { color: var(--text-dim); font-size: 0.95rem; flex: 1; }
.path-card__cta { margin-top: 1.2rem; font-weight: 600; font-size: 0.93rem; }

/* ── 11. Compatibility checker ──────────────────────────────────────────────────────── */

.section--checker { background: var(--surface-1); }
.checker-shell { margin-top: 2rem; }

.cc {
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(1.2rem, 3.5vw, 2rem);
  max-width: 54rem;
  box-shadow: var(--shadow);
}
.cc__head { margin-bottom: 1.4rem; }
.cc__progress { font-size: 0.8rem; color: var(--text-faint); letter-spacing: 0.04em; text-transform: uppercase; font-weight: 620; margin-bottom: 0.5rem; }
.cc__bar { width: 100%; height: 4px; appearance: none; border: 0; background: var(--surface-3); border-radius: 999px; overflow: hidden; display: block; }
.cc__bar::-webkit-progress-bar { background: var(--surface-3); }
.cc__bar::-webkit-progress-value { background: var(--accent); transition: width 0.25s ease; }
.cc__bar::-moz-progress-bar { background: var(--accent); }

/* The card and the result panel are focus landing points, not controls. They are announced
   because focus moves into a labelled group; drawing a focus ring around a whole panel would
   read to sighted users as an editable field. Every actual control keeps its indicator. */
.cc__card:focus, .cc__result:focus { outline: none; }

.cc__q { font-size: clamp(1.15rem, 2.8vw, 1.5rem); margin-bottom: 0.5rem; }
.cc__help { color: var(--text-dim); font-size: 0.93rem; margin-bottom: 1.3rem; max-width: 58ch; }

.cc__options { display: grid; gap: 0.6rem; }
.cc__option {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1.05rem;
  font: inherit;
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.14s ease, background-color 0.14s ease;
}
.cc__option:hover { border-color: var(--accent); background: var(--accent-soft); }
.cc__option.is-chosen { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.cc__option-label { display: block; font-weight: 580; }
.cc__option-note { display: block; color: var(--text-faint); font-size: 0.855rem; margin-top: 0.22rem; line-height: 1.45; }

.cc__controls { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 1.5rem; }
.cc__controls button[hidden] { display: none; }
.cc__footnote { margin-top: 1.1rem; color: var(--text-faint); font-size: 0.82rem; }

.cc__result { --tone: var(--good); }
.cc__result[data-tone="warn"] { --tone: var(--warn); }
.cc__result[data-tone="blocked"] { --tone: var(--bad); }
.cc__badge {
  display: inline-block;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--tone);
  border: 1px solid color-mix(in oklab, var(--tone) 45%, transparent);
  background: color-mix(in oklab, var(--tone) 12%, var(--surface-0));
  padding: 0.3rem 0.65rem;
  border-radius: 999px;
  margin-bottom: 0.9rem;
}
.cc__verdict-title { font-size: clamp(1.25rem, 3vw, 1.7rem); margin-bottom: 0.55rem; }
.cc__verdict-body { color: var(--text-dim); max-width: 62ch; }

.cc__summary { margin-top: 1.8rem; padding: 1.1rem 1.25rem; background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.cc__summary-title { font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 0.7rem; }
.cc__answers { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 1.2rem; font-size: 0.9rem; }
.cc__answers dt { color: var(--text-faint); }
.cc__answers dd { margin: 0; font-weight: 560; }

.cc__checklist { margin-top: 2rem; }
.cc__checklist-title { font-size: 1.15rem; margin-bottom: 0.35rem; }
.cc__checklist-lead { color: var(--text-dim); font-size: 0.93rem; margin-bottom: 1.3rem; max-width: 60ch; }

.cc__tasks { display: grid; gap: 1rem; }
.cc__task { background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1.1rem 1.25rem; break-inside: avoid; }
.cc__task-head { display: flex; align-items: flex-start; gap: 0.7rem; }
.cc__tick {
  display: inline-grid; place-items: center;
  width: 1.6rem; height: 1.6rem; flex: none;
  border-radius: 50%;
  border: 1px solid var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: 0.78rem; font-weight: 700;
}
.cc__task-title { font-size: 1.02rem; padding-top: 0.12rem; }
.cc__task-why { color: var(--text-faint); font-size: 0.875rem; margin: 0.6rem 0 0 2.3rem; max-width: 62ch; }
.cc__steps { margin: 0.85rem 0 0 2.3rem; padding-left: 1.1rem; list-style: decimal; display: grid; gap: 0.45rem; }
.cc__steps li { color: var(--text-dim); font-size: 0.92rem; padding-left: 0.2rem; }
.cc__steps li::marker { color: var(--text-faint); font-variant-numeric: tabular-nums; }

.cc__printonly { display: none; }

@media (max-width: 34rem) {
  .cc__task-why, .cc__steps { margin-left: 0; }
}
/* Two columns squeeze the answer values into three-word-per-line ribbons on a phone. */
@media (max-width: 30rem) {
  .cc__answers { grid-template-columns: 1fr; gap: 0; }
  .cc__answers dt { margin-top: 0.55rem; }
  .cc__answers dt:first-child { margin-top: 0; }
}

/* ── 12. Kit ────────────────────────────────────────────────────────────────────────── */

.kit { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); margin-top: 2.4rem; align-items: start; }
@media (max-width: 52rem) { .kit { grid-template-columns: 1fr; } }

.kit-card { background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.6rem; box-shadow: var(--shadow); }
.kit-card__name { font-size: 1.3rem; }
.kit-card__price { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.45rem; }
.kit-card__amount { font-size: 2.1rem; font-weight: 700; letter-spacing: -0.03em; color: var(--accent-text); }
.kit-card__pricenote { color: var(--text-faint); font-size: 0.85rem; }
.kit-card__includes { display: grid; gap: 0.55rem; margin-top: 1.4rem; }
.kit-card__includes li { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.94rem; }
.kit-card__includes .mark { margin-top: 0.22rem; }
.kit-card__notincluded { margin-top: 1.1rem; color: var(--text-faint); font-size: 0.87rem; }
.kit-card__action { margin-top: 1.5rem; }
.kit-card__soon { border: 1px dashed var(--border); border-radius: var(--radius-sm); padding: 1.1rem 1.2rem; background: var(--surface-2); }
.kit-card__soon-title { font-weight: 660; margin-bottom: 0.3rem; }
.kit-card__soon-body { color: var(--text-dim); font-size: 0.9rem; margin-bottom: 1.1rem; }

/* ── "Tell me when it is on sale" ─────────────────────────────────────────────────────────
 *
 * Replaces a mailto: button, so it has to feel like as small an ask as that button looked. Two
 * fields stacked, full-width submit, and the whole thing swapped for one line of confirmation on
 * success. */
.notify { display: grid; gap: 0.85rem; }

.notify__field { display: grid; gap: 0.3rem; }

.notify__label { font-size: 0.82rem; font-weight: 600; color: var(--text-dim); }

.notify__input {
  width: 100%;
  padding: 0.6rem 0.7rem;
  font: inherit;
  /* 16px floor: iOS Safari zooms the viewport on focus for anything smaller and never zooms back
     out when the field blurs. */
  font-size: max(0.95rem, 16px);
  color: var(--text);
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.notify__help { margin: 0.15rem 0 0; font-size: 0.78rem; color: var(--text-faint); }

.notify__submit { width: 100%; justify-content: center; }

.notify__status {
  margin: 0;
  font-size: 0.85rem;
  color: var(--bad);
  font-weight: 600;
}

.notify__done {
  margin: 0;
  padding: 0.7rem 0.85rem;
  border-radius: var(--radius-sm);
  background: var(--good-soft);
  color: var(--good);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.5;
}
.kit-card__build { display: inline-block; margin-top: 1.1rem; font-size: 0.9rem; }

.kit-specs { background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.4rem 1.6rem; }
.kit-specs__title { font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 0.9rem; }
.kit-specs__list { display: grid; grid-template-columns: auto 1fr; gap: 0.55rem 1.1rem; font-size: 0.89rem; }
.kit-specs__list dt { color: var(--text-faint); }
.kit-specs__list dd { margin: 0; }

/* ── 13. Ecosystem ──────────────────────────────────────────────────────────────────── */

.eco { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); margin-top: 2.4rem; }
.eco-card { background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.4rem; }
.eco-card__title { font-size: 1.1rem; margin-bottom: 0.5rem; }
.eco-card__body { color: var(--text-dim); font-size: 0.94rem; }
.eco-card__detail { color: var(--text-faint); font-size: 0.85rem; margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid var(--border); }

/* ── 14. Pricing ────────────────────────────────────────────────────────────────────── */

.tiers { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(16.5rem, 1fr)); margin-top: 2.6rem; align-items: start; }
.tier {
  position: relative;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.6rem;
}
.tier.is-featured { border-color: var(--accent); box-shadow: var(--shadow); }
.tier__ribbon {
  position: absolute;
  top: -0.75rem; right: 1.2rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  padding: 0.25rem 0.65rem;
  border-radius: 999px;
}
.tier__name { font-size: 1.15rem; }
.tier__price { display: flex; align-items: baseline; gap: 0.4rem; margin-top: 0.5rem; }
.tier__amount { font-size: 2.2rem; font-weight: 700; letter-spacing: -0.03em; }
.tier__period { color: var(--text-faint); font-size: 0.85rem; }
.tier__tagline { color: var(--text-dim); font-size: 0.92rem; margin-top: 0.5rem; }
.tier__launch {
  margin-top: 0.9rem; padding: 0.6rem 0.8rem;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--radius-sm); font-size: 0.85rem; color: var(--accent-text);
}
.tier__features { display: grid; gap: 0.5rem; margin-top: 1.3rem; padding-top: 1.3rem; border-top: 1px solid var(--border); }
.tier__features li { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.9rem; }
.tier__features .mark { margin-top: 0.2rem; }
.tier__features li.is-off { color: var(--text-faint); text-decoration: line-through; text-decoration-color: color-mix(in oklab, currentColor 35%, transparent); }
.tier__cta { margin-top: 1.4rem; font-size: 0.85rem; color: var(--text-faint); font-weight: 560; }

/* ── 15. Open source ────────────────────────────────────────────────────────────────── */

.section--oss { background: var(--surface-1); }
.oss__licence { margin-top: 1.4rem; font-size: 1.02rem; max-width: 62ch; }
.oss__actions { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 1.5rem; }
.stars {
  margin-left: 0.15rem; padding-left: 0.6rem;
  border-left: 1px solid var(--border);
  color: var(--text-faint); font-weight: 520; font-size: 0.87rem;
}
.oss__cards { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); margin-top: 2.2rem; }
.oss-card { background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.2rem; }
.oss-card__title { font-family: var(--mono); font-size: 0.95rem; color: var(--accent-text); margin-bottom: 0.45rem; }
.oss-card__body { color: var(--text-dim); font-size: 0.89rem; }
.oss-card__licence { display: inline-block; margin-top: 0.8rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; color: var(--text-faint); border: 1px solid var(--border); border-radius: 999px; padding: 0.15rem 0.5rem; }

.selfhost { margin-top: 2.6rem; max-width: 46rem; }
.selfhost__title { font-size: 1.2rem; margin-bottom: 0.5rem; }
.selfhost p { color: var(--text-dim); font-size: 0.95rem; }
.code-block { position: relative; margin-top: 1.1rem; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.code-block pre { margin: 0; padding: 1.05rem 1.2rem; overflow-x: auto; }
.code-block code { background: none; border: 0; padding: 0; font-size: 0.875rem; line-height: 1.75; color: var(--text); white-space: pre; }
.code-block__copy { position: absolute; top: 0.55rem; right: 0.55rem; background: var(--surface-2); }

/* ── 16. FAQ, final CTA, footer ─────────────────────────────────────────────────────── */

/* The section sits in a full-width wrap so its heading lines up with every other section;
   the measure is constrained here instead. */
.faq { margin-top: 2.2rem; border-top: 1px solid var(--border); max-width: var(--wrap-narrow); }
.faq__item { border-bottom: 1px solid var(--border); }
.faq__summary {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  padding: 1.05rem 0.2rem;
  cursor: pointer;
  list-style: none;
}
.faq__summary::-webkit-details-marker { display: none; }
.faq__q { font-size: 1.02rem; font-weight: 600; }
.faq__chevron { width: 1.1rem; height: 1.1rem; flex: none; color: var(--text-faint); margin-top: 0.25rem; transition: transform 0.18s ease; }
.faq__item[open] .faq__chevron { transform: rotate(180deg); }
.faq__item[open] .faq__q { color: var(--accent-text); }
.faq__a { padding: 0 0.2rem 1.3rem; color: var(--text-dim); max-width: 68ch; }

.final-cta { padding-block: var(--section-y); border-top: 1px solid var(--border); background: var(--surface-1); text-align: center; }
.final-cta__title { font-size: clamp(1.6rem, 4.2vw, 2.3rem); margin-bottom: 0.8rem; }
.final-cta p { color: var(--text-dim); max-width: 54ch; margin-inline: auto; }
.final-cta .hero__ctas { justify-content: center; margin-top: 1.8rem; }

.site-footer { border-top: 1px solid var(--border); padding-block: 3rem 2.2rem; font-size: 0.9rem; }
.site-footer__top { display: grid; gap: 2.4rem; grid-template-columns: minmax(0, 1.1fr) minmax(0, 2fr); }
@media (max-width: 52rem) { .site-footer__top { grid-template-columns: 1fr; gap: 2rem; } }
.wordmark--footer { font-size: 1rem; }
.site-footer__tagline { color: var(--text-faint); margin-top: 0.7rem; max-width: 34ch; }
.site-footer__nav { display: grid; gap: 1.6rem; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); }
.site-footer__grouptitle { font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 0.7rem; font-weight: 680; }
.site-footer__group ul { display: grid; gap: 0.4rem; }
.site-footer__group a { color: var(--text-dim); text-decoration: none; }
.site-footer__group a:hover { color: var(--text); text-decoration: underline; }
.site-footer__caveat {
  margin-top: 2.6rem; padding-top: 1.4rem;
  border-top: 1px solid var(--border);
  color: var(--text-faint); font-size: 0.82rem; line-height: 1.6; max-width: 82ch;
}
.site-footer__legal { margin-top: 0.9rem; color: var(--text-faint); font-size: 0.82rem; display: flex; flex-wrap: wrap; gap: 0.15rem 0.6rem; }

/* ── 16b. Sign-in page ──────────────────────────────────────────────────────────────── */

/* signin.html only. It shares the header, the tokens and the buttons with the landing page and
   adds one centred card, so it lives here rather than in a second stylesheet — a second file
   would double the theme block and the button rules for about forty lines of layout. */

.page-auth {
  /* The card is centred in the viewport, not in the document: on a phone in landscape the
     page is barely taller than the card, and centring in the document leaves it clinging to
     the top. min-height rather than height so a validation message can grow the page. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.auth {
  flex: 1;
  display: flex;
  align-items: center;
  padding: clamp(1.5rem, 6vw, 4rem) 0;
}

.auth__wrap {
  width: 100%;
  max-width: 27rem;
}

.auth__card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.4rem, 5vw, 2.2rem);
  text-align: center;
}

.auth__icon {
  width: 2.6rem;
  height: 2.6rem;
  color: var(--accent);
  margin-bottom: 0.6rem;
}

.auth__title {
  margin: 0 0 0.5rem;
  font-size: clamp(1.35rem, 4vw, 1.7rem);
  letter-spacing: -0.02em;
}

.auth__lead {
  margin: 0 0 1.4rem;
  color: var(--text-dim);
  line-height: 1.6;
}

.auth__form { text-align: left; }

.auth__label {
  display: block;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text-dim);
  margin-bottom: 0.35rem;
}

.auth__input {
  width: 100%;
  padding: 0.8rem 0.9rem;
  font: inherit;
  /* 16px minimum: iOS Safari zooms the viewport on focus for anything smaller, and the zoom
     is not undone when the field blurs. */
  font-size: max(1rem, 16px);
  color: var(--text);
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.auth__input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent-line);
}

.auth__input[aria-invalid='true'] { border-color: var(--bad); }

.auth__submit {
  width: 100%;
  margin-top: 1rem;
  justify-content: center;
}

.auth__field-error {
  margin: 0.5rem 0 0;
  font-size: 0.88rem;
  color: var(--bad);
}

.auth__note {
  margin: 1.2rem 0 0;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text-faint);
}

.auth__alert {
  margin: 0 0 1rem;
  padding: 0.75rem 0.9rem;
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in oklab, var(--warn) 45%, var(--border));
  background: var(--warn-soft);
  color: var(--text);
  font-size: 0.9rem;
  line-height: 1.55;
}

.auth__signout { margin-top: 0.9rem; }

.auth__back {
  margin: 1.2rem 0 0;
  text-align: center;
  font-size: 0.88rem;
}

.auth__back a { color: var(--text-faint); }
.auth__back a:hover { color: var(--text-dim); }

/* Before js/signin.js resolves the catalogue, every [data-copy] element is empty. Hiding the
   card until then avoids a frame of blank boxes; the `is-failed` case still shows the form,
   because the markup's static fallback text is better than nothing.

   Scoped to `body[data-hydrate]`, so a page opts IN to being hidden. An earlier version matched
   every `.auth__card` and would have blanked 404.html, which reuses this layout and has no
   script at all — an error page that renders nothing is the worst possible one. */
html:not(.is-ready) body[data-hydrate] .auth__card { visibility: hidden; }

/* ── 16c. Shop, checkout and order status ───────────────────────────────────────────── */

.shop, .checkout-page, .order-page { padding: clamp(1.8rem, 5vw, 3.5rem) 0; }

.shop__banner {
  margin: 0 0 1.5rem;
  padding: 0.85rem 1rem;
  border: 1px solid color-mix(in oklab, var(--warn) 45%, var(--border));
  background: var(--warn-soft);
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  line-height: 1.6;
}

/* Catalogue and basket side by side on a desktop, stacked on a phone with the basket LAST —
   on a narrow screen the thing you are choosing from should come before the thing you are
   choosing into, and a sticky basket on a 5-inch screen eats the content. */
.shop__layout {
  display: grid;
  gap: clamp(1.2rem, 4vw, 2.5rem);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 60rem) {
  .shop__layout { grid-template-columns: minmax(0, 1fr) 21rem; }
  .basket { position: sticky; top: 5rem; }
}

.shop__title { margin: 0 0 0.4rem; font-size: clamp(1.6rem, 5vw, 2.2rem); }
.shop__lead { margin: 0 0 1.8rem; color: var(--text-dim); }
.shop__note { margin: 1.5rem 0 0; font-size: 0.82rem; color: var(--text-faint); }

.shop__products {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.product {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.1rem;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.product__name { margin: 0; font-size: 1.05rem; }
.product__desc { margin: 0; font-size: 0.88rem; line-height: 1.55; color: var(--text-dim); flex: 1; }
.product__price { margin: 0.3rem 0 0; }
.product__amount { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.product__unit { font-size: 0.8rem; color: var(--text-faint); }
.product__add { width: 100%; justify-content: center; }

.basket {
  padding: 1.1rem;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.basket__title { margin: 0 0 0.8rem; font-size: 1.05rem; }
.basket__empty { margin: 0; color: var(--text-dim); font-size: 0.9rem; }

.basket__lines { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: 0.5rem; }

.basket__line {
  display: grid;
  grid-template-columns: 1fr 3.6rem auto auto;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.88rem;
}

.basket__line-name { overflow-wrap: anywhere; }
.basket__line-price { font-variant-numeric: tabular-nums; white-space: nowrap; }

.basket__qty {
  width: 100%;
  padding: 0.3rem 0.4rem;
  font: inherit;
  font-size: 0.88rem;
  color: var(--text);
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.basket__remove {
  padding: 0 0.35rem;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--text-faint);
  background: none;
  border: 0;
  cursor: pointer;
}
.basket__remove:hover { color: var(--bad); }

.basket__country { margin: 0 0 0.9rem; }
.basket__label { display: block; font-size: 0.82rem; font-weight: 600; color: var(--text-dim); margin-bottom: 0.3rem; }

.basket__select, .basket__input, .field__input, .field__select {
  width: 100%;
  padding: 0.6rem 0.7rem;
  font: inherit;
  /* 16px floor: iOS Safari zooms the viewport on focus for anything smaller and never zooms
     back out when the field blurs. */
  font-size: max(0.95rem, 16px);
  color: var(--text);
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.basket__help { margin: 0.3rem 0 0; font-size: 0.78rem; color: var(--text-faint); }

.basket__totals {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.3rem 0.8rem;
  margin: 0 0 0.9rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
}

.basket__key { margin: 0; color: var(--text-dim); }
.basket__value { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.basket__key--strong, .basket__value--strong { color: var(--text); font-weight: 700; font-size: 1rem; }

.basket__note { margin: 0 0 0.8rem; font-size: 0.78rem; line-height: 1.5; color: var(--text-faint); }
.basket__error { margin: 0 0 0.8rem; font-size: 0.85rem; color: var(--bad); }
.basket__checkout { width: 100%; justify-content: center; }

/* A disabled anchor cannot use :disabled, and removing the href would drop it out of the tab
   order silently. This keeps it focusable and announces the state. */
.btn.is-disabled { opacity: 0.5; pointer-events: none; }

/* ── Interest capture ─────────────────────────────────────────────────────────────────────
 *
 * Shown in place of the checkout button when the chosen destination has no shipping zone. Set
 * apart with a rule and a tint rather than styled as more of the basket, because it is a
 * different offer: the basket prices something you can have, this asks about something you
 * cannot have yet. */
.interest {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.interest__title { margin: 0 0 0.3rem; font-weight: 700; }
.interest__lead { margin: 0 0 0.9rem; font-size: 0.85rem; line-height: 1.55; color: var(--text-dim); }
.interest .basket__input { margin-bottom: 0.8rem; }

.interest__privacy {
  margin: 0 0 0.9rem;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--text-faint);
}

.interest__done {
  margin: 0.9rem 0 0;
  padding: 0.7rem 0.85rem;
  border-radius: var(--radius-sm);
  background: var(--good-soft);
  color: var(--good);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.5;
}

/* ── Checkout form ──────────────────────────────────────────────────────────────────── */

.checkout__layout {
  display: grid;
  gap: clamp(1.2rem, 4vw, 2.5rem);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 60rem) {
  .checkout__layout { grid-template-columns: minmax(0, 1fr) 21rem; }
}

/* Flex rather than inline-block. `display: inline-block` on two 50% children looks right until
   you count the whitespace: the newline between the two elements in the markup is a real space,
   so 50% + 50% + margin + that space exceeds 100% and the second field wraps onto its own line,
   indented by the margin. Flex has no such text node to trip over. */
.fieldset {
  border: 0;
  margin: 0 0 1.5rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.8rem;
}
.fieldset__legend { padding: 0; margin: 0 0 0.8rem; font-size: 1.05rem; font-weight: 700; width: 100%; }

.field { margin: 0 0 0.9rem; flex: 1 1 100%; min-width: 0; }
.field--half { flex: 1 1 calc(50% - 0.4rem); }

@media (max-width: 30rem) {
  .field--half { flex-basis: 100%; }
}

.field__label { display: block; font-size: 0.84rem; font-weight: 600; color: var(--text-dim); margin-bottom: 0.3rem; }
.field__help { margin: 0.3rem 0 0; font-size: 0.78rem; color: var(--text-faint); }
.field__input[aria-invalid='true'], .field__select[aria-invalid='true'] { border-color: var(--bad); }
.field__error { margin: 0.3rem 0 0; font-size: 0.8rem; color: var(--bad); }
.checkout__back { margin: 0.9rem 0 0; font-size: 0.88rem; }

.field__status { margin: 0.35rem 0 0; font-size: 0.82rem; line-height: 1.5; }
.field__status--ok { color: var(--good); }
.field__status--warn { color: var(--warn); }
.field__status--bad { color: var(--bad); }

/* ── Order status ───────────────────────────────────────────────────────────────────── */

.order-card {
  padding: clamp(1.2rem, 4vw, 1.8rem);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.order-card + .order-card { margin-top: 1.1rem; }

.order__status {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  border: 1px solid var(--accent-line);
  background: var(--accent-soft);
}

.claim {
  margin: 0.6rem 0;
  padding: 0.8rem 1rem;
  border: 1px dashed var(--accent-line);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  font-family: var(--mono);
  font-size: 1.3rem;
  letter-spacing: 0.1em;
  text-align: center;
  /* The one string on this page someone will select and copy by hand. */
  user-select: all;
}

.claim--redeemed { opacity: 0.55; text-decoration: line-through; }

/* ── 17. Print ──────────────────────────────────────────────────────────────────────── */

/* Printing is a real path here: the compatibility checklist is meant to be carried to the
   machine being fixed, which is by definition not the machine showing this page. Everything
   except the result panel is removed. */
@media print {
  :root {
    --surface-0: #fff; --surface-1: #fff; --surface-2: #fff; --surface-3: #fff;
    --border: #bbb; --text: #000; --text-dim: #222; --text-faint: #444;
    --accent: #1a4fb4; --accent-text: #1a4fb4; --accent-soft: #fff; --accent-line: #999;
  }
  body { background: #fff; color: #000; font-size: 11pt; }
  .site-header, .site-footer, .hero, .stats, .section, .final-cta, .noscript, .skip-link { display: none !important; }
  .section--checker { display: block !important; padding: 0; border: 0; background: #fff; }
  .section--checker .eyebrow, .section--checker .section__title, .section--checker .section__lead { display: none; }
  .cc { border: 0; box-shadow: none; padding: 0; max-width: none; }
  .cc__controls, .cc__footnote, .cc__head { display: none !important; }
  .cc__printonly { display: block; font-size: 9pt; color: #555; margin-bottom: 0.6rem; }
  .cc__badge { border-color: #666; color: #000; }
  .cc__task, .cc__summary { border: 1px solid #ccc; break-inside: avoid; page-break-inside: avoid; }
  .cc__task-title { font-size: 11pt; }
  a { color: #000; text-decoration: underline; }
}

/* ── 18. Reduced motion ─────────────────────────────────────────────────────────────── */

@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;
  }
  /* SVG SMIL is not covered by the rule above; the clock is also paused from js/main.js, and
     hiding the packets means a paused animation never shows a dot frozen mid-flight. */
  .diagram__packet { display: none; }
  .faq__chevron { transition: none; }
}
