/* ==========================================================================
   BASE.CSS — Shared mobile-first foundation
   Implements MOBILE-UI-SPEC.md. Copied into each site; brand values are
   overridden in that site's site.css. Do not put brand colors here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
  /* --- Spacing: 4px base, 8px-preferred scale --- */
  --sp-1: 0.25rem;   /*  4 */
  --sp-2: 0.5rem;    /*  8 */
  --sp-3: 0.75rem;   /* 12 */
  --sp-4: 1rem;      /* 16 */
  --sp-5: 1.25rem;   /* 20 — default mobile gutter */
  --sp-6: 1.5rem;    /* 24 */
  --sp-8: 2rem;      /* 32 — intra-section block gap */
  --sp-10: 2.5rem;   /* 40 */
  --sp-12: 3rem;     /* 48 — cluster separation */
  --sp-16: 4rem;     /* 64 */
  --sp-20: 5rem;     /* 80 */
  --sp-24: 6rem;     /* 96 */

  /* Fluid gutter: 20px @360 → 32px @1440 */
  --gutter: clamp(1.25rem, 1rem + 1.111vw, 2rem);
  /* Section block padding: 56px @360 → 112px @1440 */
  --section-y: clamp(3.5rem, 2.333rem + 5.185vw, 7rem);

  /* --- Containers --- */
  --w-prose: 42rem;    /* 672 */
  --w-content: 72rem;  /* 1152 */
  --w-wide: 85rem;     /* 1360 */

  /* --- Type scale: clamp between 360px and 1440px viewport --- */
  --t-eyebrow: 0.75rem;                                        /* 12 */
  --t-sm:      clamp(0.875rem, 0.854rem + 0.093vw, 0.9375rem); /* 14 → 15 */
  --t-body:    clamp(1.0625rem, 1rem + 0.278vw, 1.125rem);     /* 17 → 18 */
  --t-lead:    clamp(1.125rem, 1.021rem + 0.463vw, 1.375rem);  /* 18 → 22 */
  --t-h3:      clamp(1.25rem, 1.083rem + 0.741vw, 1.75rem);    /* 20 → 28 */
  --t-h2:      clamp(1.625rem, 1.333rem + 1.296vw, 2.5rem);    /* 26 → 40 */
  --t-h1:      clamp(2.125rem, 1.5rem + 2.778vw, 4rem);        /* 34 → 64 */
  --t-display: clamp(2.5rem, 1.667rem + 3.704vw, 5rem);        /* 40 → 80 */

  --lh-body: 1.6;
  --lh-lead: 1.45;
  --lh-h3: 1.25;
  --lh-h2: 1.18;
  --lh-h1: 1.08;

  /* Negative tracking on display sizes — highest-ROI premium detail */
  --tr-h1: -0.03em;
  --tr-h2: -0.02em;
  --tr-h3: -0.01em;
  --tr-eyebrow: 0.08em;

  /* --- Radius: inner = outer − padding --- */
  --r-xs: 0.25rem;
  --r-sm: 0.5rem;
  --r-md: 0.75rem;
  --r-lg: 1rem;
  --r-xl: 1.5rem;
  --r-2xl: 1.75rem;
  --r-full: 9999px;

  /* --- Chrome heights (spec §2.3, §2.4) --- */
  --header-h: 3.5rem;   /* 56px */
  --header-h-sm: 3rem;  /* 48px after shrink */
  --cta-h: 4.5rem;      /* 72px bottom action bar */

  /* --- Motion: authored positive; see §5.3 --- */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-out-soft: cubic-bezier(0.05, 0.7, 0.1, 1);
  --ease-in-sharp: cubic-bezier(0.3, 0, 0.8, 0.15);
  --ease-spring: linear(0, .006, .025 2.8%, .101 6.1%, .539 18.9%, .721 25.3%,
    .849 31.5%, .937 38.1%, .968 41.8%, .991 45.7%, 1.006 50.1%, 1.015 60%, 1.004 78.2%, 1);
  --dur-1: 100ms;
  --dur-2: 160ms;
  --dur-3: 220ms;
  --dur-4: 300ms;
  --dur-5: 360ms;

  /* --- Elevation: hairline borders, minimal shadow (§4.3) --- */
  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.04);
  --shadow-pop: 0 8px 24px -8px rgb(0 0 0 / 0.14);
}

/* --------------------------------------------------------------------------
   2. RESET
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* WCAG 2.4.11 — focused elements come to rest ABOVE the sticky bottom bar */
  scroll-padding-top: calc(var(--header-h) + var(--sp-4));
  scroll-padding-bottom: calc(var(--cta-h) + env(safe-area-inset-bottom) + var(--sp-4));
}

body {
  min-height: 100svh;
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Stops the sticky bottom bar covering the footer */
  padding-bottom: calc(var(--cta-h) + env(safe-area-inset-bottom));
}

@media (min-width: 768px) {
  body { padding-bottom: 0; }
  html { scroll-padding-bottom: var(--sp-8); }
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
  height: auto;
}

/* 16px minimum on all controls — blocks iOS focus zoom. Non-negotiable. */
input, button, textarea, select {
  font: inherit;
  font-size: max(1rem, 1em);
  color: inherit;
}

button { background: none; border: none; cursor: pointer; }

p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
p { text-wrap: pretty; }
h1, h2, h3, h4 { text-wrap: balance; }

h1 { font-size: var(--t-h1); line-height: var(--lh-h1); letter-spacing: var(--tr-h1); font-weight: 700; }
h2 { font-size: var(--t-h2); line-height: var(--lh-h2); letter-spacing: var(--tr-h2); font-weight: 700; }
h3 { font-size: var(--t-h3); line-height: var(--lh-h3); letter-spacing: var(--tr-h3); font-weight: 650; }

a { color: inherit; }

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

/* Visible focus on everything focusable */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--accent); color: var(--accent-fg); }

/* --------------------------------------------------------------------------
   3. LAYOUT UTILITIES
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--prose { max-width: var(--w-prose); }
.wrap--wide { max-width: var(--w-wide); }

.section { padding-block: var(--section-y); }

/* Full-bleed: escape the gutter (§4.5 — inset hero images are a cheapness tell) */
.bleed { margin-inline: calc(var(--gutter) * -1); }
@media (min-width: 1152px) { .bleed { margin-inline: 0; } }

/* Prose measure applies at md+ only — on mobile 40ch happens naturally (§4.1) */
.measure { max-width: none; }
@media (min-width: 768px) { .measure { max-width: 65ch; } }

.eyebrow {
  font-size: var(--t-eyebrow);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted);
}

.stack > * + * { margin-block-start: var(--sp-4); }
.stack-lg > * + * { margin-block-start: var(--sp-8); }

/* --------------------------------------------------------------------------
   TOUCH FEEDBACK
   Chrome on Android paints a translucent blue flash behind every tap target by
   default. On a dark, cyan-accented ground that reads as someone else's UI, and
   it was only switched off for .btn. Off everywhere a tap can land, with a real
   :active state supplied in its place so the tap still confirms itself.
   -------------------------------------------------------------------------- */
a, button, summary, label, input, select, textarea,
[role="button"], [role="tab"], [tabindex] {
  -webkit-tap-highlight-color: transparent;
}
@media (hover: none) and (pointer: coarse) {
  a:not(.btn):active,
  summary:active { opacity: 0.6; transition: opacity 60ms linear; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* A <table> will not shrink below its min-content width. It ignores the width
   above and keeps its full size in the SCROLLABLE OVERFLOW area even though
   clip-path has hidden it, so pages carrying an accessible chart table scrolled
   sideways at 320px for a reason invisible on screen. Measured: table-layout
   fixed, max-width, contain:size and contain:strict all left it at 413px; only
   display:block collapsed it, and that costs the table semantics the chart
   depends on. So the tables are WRAPPED in an sr-only div instead and left as
   real tables. This rule is the belt to that braces. */
.sr-only > table { table-layout: fixed; }

/* Long below-fold sections: 232ms → 30ms rendering (web.dev) */
/* content-visibility: auto is off by default now. Measured on the homepage it
   made the document height fall from 10,328px to 9,278px as you scrolled and
   never recover, because each section that collapsed invalidated the
   measurements ScrollTrigger had cached for its pinned story. Consequences:
   every anchor jump landed short, and scrollTo(0, 0) came to rest at 2,128px,
   so a visitor could not get back to the top. GSAP's own docs call out that
   content-visibility breaks position: fixed on ancestors, which is what pinning
   uses. Opt in per page with .defer-render only where there is no pin on the
   page and the content below the fold is genuinely heavy. */
.defer-render {
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}

/* --------------------------------------------------------------------------
   4. SKIP LINK
   -------------------------------------------------------------------------- */
.skip {
  position: absolute;
  top: var(--sp-2); left: var(--sp-2);
  z-index: 100;
  padding: var(--sp-3) var(--sp-4);
  background: var(--accent);
  color: var(--accent-fg);
  border-radius: var(--r-sm);
  font-weight: 600;
  transform: translateY(-200%);
}
.skip:focus { transform: translateY(0); }

/* --------------------------------------------------------------------------
   5. BUTTONS  (§3.3 — 48px targets, CSS-only press feedback, scoped hover)
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 3rem;          /* 48px */
  padding: var(--sp-3) var(--sp-6);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border-radius: var(--r-md);
  font-weight: 650;
  font-size: 1rem;
  line-height: 1.2;
  text-decoration: none;
  text-align: center;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-1) var(--ease-standard),
              background-color var(--dur-1) var(--ease-standard);
}
.btn:active { transform: scale(0.97); }

.btn--outline {
  --btn-bg: transparent;
  --btn-fg: var(--fg);
  border: 1.5px solid var(--border-strong);
}
.btn--ghost { --btn-bg: transparent; --btn-fg: var(--fg); }
.btn--lg { min-height: 3.5rem; font-size: 1.0625rem; padding-inline: var(--sp-8); }
.btn--block { display: flex; width: 100%; }

@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--btn-bg-hover, color-mix(in oklch, var(--btn-bg) 88%, black)); }
  .btn--outline:hover { background: var(--surface-2); }
}

/* Busy state paints in the same frame as the tap (INP budget) */
.btn[aria-busy="true"] { pointer-events: none; opacity: 0.75; }
.btn[aria-busy="true"]::before {
  content: "";
  inline-size: 1em; block-size: 1em;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* Invisible hit expander — visual size decoupled from tap size (§3.1) */
.tap-safe { position: relative; }
.tap-safe::after {
  content: "";
  position: absolute;
  inset: 50% 50%;
  min-width: 48px; min-height: 48px;
  width: 100%; height: 100%;
  transform: translate(-50%, -50%);
}

/* --------------------------------------------------------------------------
   6. HEADER  (§2.3 — 56px, opaque when scrolled, hide-on-scroll-down)
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--header-h);
  padding-top: env(safe-area-inset-top);
  background: var(--bg);
  border-bottom: 1px solid transparent;
  /* transform and colour only. Height is deliberately NOT animated: the header
     is sticky and therefore in normal flow, so shrinking it moved every pixel
     of the page up by 8px on each scroll threshold crossing. Scroll gets no
     CLS grace window, so that shift counted in full, and MOBILE-UI-SPEC 13
     bans animating height outright. */
  transition: transform var(--dur-4) var(--ease-standard),
              border-color var(--dur-2) linear;
  view-transition-name: site-header;   /* stays pinned across navigation */
}
.site-header[data-scrolled] {
  border-bottom-color: var(--border);
}
.site-header[data-hidden] { transform: translateY(-100%); }

.header-inner {
  height: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  max-width: var(--w-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.logo {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  margin-inline-end: auto;
  min-height: 48px;
}

/* Combo nav: ONE Primary landmark, sized by CSS. Two <nav aria-label="Primary">
   elements — one per breakpoint — is a duplicate-landmark defect, so the third
   item hides instead. 57% → 86% usage (§2.1) */
.nav-primary {
  display: flex;
  gap: var(--sp-1);
}
.nav-primary a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--sp-3);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: var(--r-sm);
  color: var(--muted);
}
.nav-primary a[aria-current="page"] {
  color: var(--fg);
  box-shadow: inset 0 -2px 0 var(--accent);   /* non-color indicator too */
}
@media (hover: hover) and (pointer: fine) {
  .nav-primary a:hover { color: var(--fg); background: var(--surface-2); }
}
/* Third item appears only once the header has room for it.
   Selector must out-specify `.nav-primary a` above, hence the `a`. */
.nav-primary a.nav-primary__wide { display: none; }
@media (min-width: 1024px) { .nav-primary a.nav-primary__wide { display: inline-flex; } }
@media (max-width: 359px) { .nav-primary { display: none; } }

/* Menu trigger — 48px, three bars PLUS the word "Menu" (§2.2) */
.menu-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 48px;
  min-width: 48px;
  padding-inline: var(--sp-3);
  border-radius: var(--r-sm);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  border: 1px solid var(--border);
  touch-action: manipulation;
}
.menu-btn__bars { display: grid; gap: 4px; width: 18px; }
.menu-btn__bars span {
  display: block; height: 2px; width: 100%;
  background: currentColor; border-radius: 2px;
}
@media (min-width: 1024px) { .menu-btn { display: none; } }

/* --------------------------------------------------------------------------
   7. DRAWER  (§2.6 — native <dialog>, full-height, focus + scroll contract)
   -------------------------------------------------------------------------- */
.drawer {
  width: min(22rem, 88vw);
  max-width: none;
  height: 100dvh;            /* the one legitimate dvh use */
  max-height: 100dvh;
  margin: 0 0 0 auto;
  padding: 0;
  border: none;
  background: var(--bg);
  color: var(--fg);
  overflow-y: auto;
  overscroll-behavior: contain;
  translate: 0 0;
  transition: translate var(--dur-4) var(--ease-spring),
              overlay var(--dur-4) allow-discrete,
              display var(--dur-4) allow-discrete;
}
.drawer:not([open]) { translate: 100% 0; }
@starting-style { .drawer[open] { translate: 100% 0; } }
.drawer::backdrop {
  background: rgb(0 0 0 / 0.5);
  opacity: 1;
  transition: opacity var(--dur-4) var(--ease-standard),
              overlay var(--dur-4) allow-discrete,
              display var(--dur-4) allow-discrete;
}
.drawer:not([open])::backdrop { opacity: 0; }
@starting-style { .drawer[open]::backdrop { opacity: 0; } }

.drawer__head {
  position: sticky; top: 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  padding-top: calc(var(--sp-4) + env(safe-area-inset-top));
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.drawer__close {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sp-2);
  min-height: 48px; min-width: 48px;
  padding-inline: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-size: 0.8125rem; font-weight: 700;
}
.drawer__body { padding: var(--sp-4) var(--sp-5) var(--sp-12); }
.drawer__foot {
  padding: 0 var(--sp-5) calc(var(--sp-8) + env(safe-area-inset-bottom));
  display: grid; gap: var(--sp-3);
}

.drawer-nav a {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 56px;
  padding-block: var(--sp-2);
  font-size: 1.125rem; font-weight: 650;
  text-decoration: none;
  border-bottom: 1px solid var(--border);
}
.drawer-nav a[aria-current="page"] { color: var(--accent-text); }

/* Accordion inside the drawer — never drill-down (§2.7) */
.acc { border-bottom: 1px solid var(--border); }
.acc__btn {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  min-height: 56px;
  font-size: 1.125rem; font-weight: 650;
  text-align: left;
  touch-action: manipulation;
}
.acc__btn svg { transition: transform var(--dur-4) var(--ease-standard); flex: none; }
.acc__btn[aria-expanded="true"] svg { transform: rotate(180deg); }
.acc__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-4) var(--ease-standard);
}
.acc__btn[aria-expanded="true"] + .acc__panel { grid-template-rows: 1fr; }
.acc__panel > div { overflow: hidden; }
.acc__panel a {
  display: flex; align-items: center;
  min-height: 48px;
  padding-left: var(--sp-3);
  font-size: 1rem; font-weight: 500;
  color: var(--muted);
  text-decoration: none;
}
.acc__panel > div > :last-child { margin-bottom: var(--sp-3); }

/* --------------------------------------------------------------------------
   8. BOTTOM ACTION BAR  (§2.4 — actions, not tabs)
   -------------------------------------------------------------------------- */
.cta-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 40;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--sp-2);
  min-height: var(--cta-h);
  align-items: center;
  padding: var(--sp-3) max(var(--sp-4), env(safe-area-inset-left))
           calc(var(--sp-3) + env(safe-area-inset-bottom))
           max(var(--sp-4), env(safe-area-inset-right));
  background: var(--surface);
  border-top: 1px solid var(--border);
  transition: translate var(--dur-3) var(--ease-standard);
}
/* Hidden until ~1 viewport of scroll, and near the form/footer */
.cta-bar[data-hidden] { translate: 0 110%; }
.cta-bar .btn { min-height: 3rem; }
@media (min-width: 768px) { .cta-bar { display: none; } }

/* --------------------------------------------------------------------------
   9. HERO  (§10 — 78svh, eased multi-stop scrim §6)
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  min-height: 78svh;
  display: flex;
  align-items: flex-end;
  overflow: clip;
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }

.hero::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    hsl(0 0% 0% / .82) 0%,
    hsl(0 0% 0% / .62) 22%,
    hsl(0 0% 4% / .34) 48%,
    hsl(0 0% 8% / .10) 72%,
    hsl(0 0% 10% / 0) 100%);
}
@media (max-width: 640px) {
  .hero::after { background-size: 100% 140%; background-position: bottom; }
}

.hero__content {
  position: relative; z-index: 2;
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding: var(--sp-12) var(--gutter) var(--sp-16);
  color: #fff;
}
.hero__content h1 { text-shadow: 0 1px 2px hsl(0 0% 0% / .35); }

/* --------------------------------------------------------------------------
   10. CARDS & RAILS  (§4.3, §3.5)
   -------------------------------------------------------------------------- */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  transition: transform var(--dur-1) var(--ease-standard);
}
.card:active { transform: scale(0.985); }
/* Shadow lives on a pseudo-element so we animate opacity, never box-shadow */
.card::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: var(--shadow-pop);
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease-standard);
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .card:hover::before { opacity: 1; }
}
/* Nested radius: inner = outer − padding */
.card img { border-radius: calc(var(--r-lg) - var(--sp-5)); }

/* Full-bleed rows beat inset cards for one-per-row mobile lists (§4.3) */
.rows { border-top: 1px solid var(--border); }
.rows > * {
  display: block;
  padding-block: var(--sp-5);
  border-bottom: 1px solid var(--border);
  text-decoration: none;
}

.rail {
  display: flex;
  gap: var(--sp-3);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--gutter);
  padding-inline: var(--gutter);
  margin-inline: calc(var(--gutter) * -1);
  scrollbar-width: none;
  padding-block-end: var(--sp-2);
}
.rail::-webkit-scrollbar { display: none; }
/* 82% so the next card visibly peeks — the affordance, not arrows */
.rail > * { flex: 0 0 82%; scroll-snap-align: start; }
@media (min-width: 640px) { .rail > * { flex-basis: 46%; } }
@media (min-width: 1024px) { .rail > * { flex-basis: 31%; } }

/* WCAG 2.5.7 — every rail ships real prev/next buttons */
.rail-nav { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); }
.rail-nav button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
  touch-action: manipulation;
}
.rail-nav button:active { transform: scale(0.94); }

/* --------------------------------------------------------------------------
   11. FORMS  (§7)
   -------------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 0.375rem; margin-block-end: var(--sp-5); }
.field label { font-size: 0.9375rem; font-weight: 650; line-height: 1.3; }
.field .hint { font-size: 0.875rem; color: var(--muted); }

.field input,
.field select,
.field textarea {
  min-height: 3.25rem;      /* 52px */
  font-size: 1rem;          /* 16px — blocks iOS auto-zoom */
  padding: 0.875rem 1rem;
  width: 100%;
  background: var(--surface);
  color: var(--fg);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-md);
  transition: border-color var(--dur-2) linear;
}
.field textarea { min-height: 7rem; resize: vertical; line-height: 1.5; }
.field select { appearance: none; background-image: var(--select-chevron); background-repeat: no-repeat;
  background-position: right var(--sp-4) center; padding-right: var(--sp-10); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); }

/* Autofill: recolor, never suppress — the tint is a useful signal */
input:-webkit-autofill, input:autofill {
  box-shadow: 0 0 0 100px var(--surface) inset;
  -webkit-text-fill-color: var(--fg);
  caret-color: var(--fg);
}

/* Errors below the field, text + icon, never color alone */
.field .err {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-size: 0.875rem; font-weight: 600;
  color: var(--danger);
}
.field .err[hidden] { display: none; }
.field[data-invalid] input,
.field[data-invalid] select,
.field[data-invalid] textarea { border-color: var(--danger); }

.req { color: var(--danger); }

/* Multi-step progress (§7.8) */
.steps { display: flex; align-items: center; gap: var(--sp-3); margin-block-end: var(--sp-6); }
.steps__track { flex: 1; height: 4px; background: var(--border); border-radius: var(--r-full); overflow: hidden; }
.steps__fill { height: 100%; background: var(--accent); transition: width var(--dur-4) var(--ease-standard); }
.steps__label { font-size: 0.8125rem; font-weight: 700; color: var(--muted); white-space: nowrap; }

/* --------------------------------------------------------------------------
   12. CLICK-TO-CALL  (§7.5)
   -------------------------------------------------------------------------- */
.tel {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 48px;
  text-decoration: none;
  font-weight: 700;
}
.tel__num { font-size: 1.125rem; letter-spacing: -0.01em; }
.tel__sub { display: block; font-size: 0.75rem; font-weight: 600; color: var(--muted); letter-spacing: 0.02em; }
@media (hover: hover) and (pointer: fine) {
  /* Selectable text on desktop instead of a dead link */
  .tel { pointer-events: none; }
}

/* --------------------------------------------------------------------------
   13. SCROLL-DRIVEN REVEALS  (§5.5 — off-main-thread, max 1 per viewport)
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .reveal {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 35%;
    }
  }
}
@keyframes reveal-up {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   14. VIEW TRANSITIONS  (§5.6 — progressive enhancement, zero cost)
   -------------------------------------------------------------------------- */
/* Opt in unconditionally. Gating the whole feature behind no-preference means a
   reduce user gets a hard cut; a cross-fade is an opacity change, which WCAG's
   own definition of motion animation explicitly excludes, so the right reduced
   variant is a fast fade rather than none. Both documents must opt in
   independently for a cross-document transition to run. */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: var(--dur-3); }
.site-footer { view-transition-name: site-footer; }

/* Snapshots default to object-fit: fill, which stretches any image group. */
::view-transition-old(site-header),
::view-transition-new(site-header),
::view-transition-old(site-footer),
::view-transition-new(site-footer) { object-fit: cover; }

/* --------------------------------------------------------------------------
   15. REDUCED MOTION — reduce, do not delete (§5.9)
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Keep functional feedback */
  .btn, .card { transition: opacity 120ms linear !important; }
  .btn:active, .card:active { transform: none; }
  .drawer, .drawer::backdrop { transition: opacity 120ms linear !important; }
  /* 1ms, never none: `none` can leave a snapshot on screen and skips the
     lifecycle events the page relies on. The universal selector above does not
     reach view-transition pseudo-elements, so they need their own rule. */
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation-duration: 1ms !important; }
}

/* --------------------------------------------------------------------------
   16. FOOTER
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--surface-2);
  border-top: 1px solid var(--border);
  padding-block: var(--sp-12) var(--sp-8);
  font-size: var(--t-sm);
}
.footer-grid {
  display: grid;
  gap: var(--sp-8);
}
@media (min-width: 768px) {
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: var(--sp-12); }
}
.footer-grid h3 { font-size: 0.8125rem; letter-spacing: var(--tr-eyebrow); text-transform: uppercase; color: var(--muted); margin-bottom: var(--sp-4); }
.footer-grid li a { display: flex; align-items: center; min-height: 44px; text-decoration: none; color: var(--muted); }
.legal {
  margin-top: var(--sp-10);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.8125rem;
  display: grid; gap: var(--sp-3);
}

/* Concept chip + disclosure — required on every demo (PRD §8.3) */
.concept-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 0.375rem var(--sp-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
  font-size: 0.6875rem; font-weight: 800;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.disclosure {
  font-size: 0.8125rem;
  color: var(--muted);
  font-style: italic;
  max-width: 60ch;
}
