/*
  Touch — public-web design system.
  ================================================================
  The single stylesheet behind every page on touchapp.app. Before this file
  the three public pages each carried their own inline <style> block built on
  a palette (#4f46e5 indigo, #1f2233 ink, pure white) and a type stack (system
  sans) that belong to NO version of Touch — the site read as a different
  company's boilerplate legal host sitting on the brand's domain.

  TOKENS ARE MIRRORED FROM THE APP, NOT INVENTED HERE.
  Every colour, radius and spacing step below traces to
  `mobile/lib/core/design/design_tokens.dart`, and every type role to
  `mobile/lib/core/design/typography.dart`. The Dart files are the source of
  truth; when they move, this file follows. Do not add a colour here that the
  app does not have.

  THE TWO DELIBERATE DIVERGENCES, both accessibility-forced. Measured against
  the three light surfaces (canvas #FAF7F2 / raised #FFFFFF / sunken #F1ECE3):

    - `TouchColors.bluePrimary` #6468C8 as LINK TEXT scores 4.51 / 4.82 / 4.10
      — it fails WCAG AA on the sunken surface and clears it by 0.01 on the
      canvas. `--c-link` is therefore #5458BC (5.62 / 6.00 / 5.10), the same
      hue darkened until it passes everywhere. #6468C8 itself is retained
      unchanged as a FILL (`--c-brand`), where white-on-it is 4.82 and passes.
    - `TouchColors.duskLavender` #8B80AB, the app's section-label colour,
      scores 3.40 and fails outright at label sizes. `--c-eyebrow` is #6F6490.

  Anything else that differs from the Dart tokens is a bug in this file.

  NO CDN, BY DESIGN. Fonts are self-hosted from `web/public/fonts/` (subset
  from the app's own TTFs). A privacy policy that makes the reader's browser
  announce itself to a third-party font host while it explains how carefully
  we handle their data is not a policy anyone should believe. The same reason
  rules out analytics, tag managers and embedded widgets on this surface: the
  public site makes ZERO third-party requests, and that is a property to
  preserve, not a coincidence.
*/

/* ============================================================
   1. Fonts — see web/public/fonts/README.md for the subset recipe
   ============================================================ */

/* Wordmark only. */
@font-face {
  font-family: 'Sora';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/sora-600.woff2') format('woff2');
}
/* Eyebrow / brand lead-in only. */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/nunito-500.woff2') format('woff2');
}
/* Editorial titles and headings. */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/montserrat-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/montserrat-700.woff2') format('woff2');
}
/* Body, UI and numerics. Variable, clamped to the weights we actually use. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('fonts/inter-var.woff2') format('woff2-variations');
}

/* ============================================================
   2. Tokens
   ============================================================ */

:root {
  color-scheme: light dark;

  /* -- Surfaces (TouchSemantic.surface*) -- */
  --c-canvas: #faf7f2; /* warmOffWhite */
  --c-raised: #ffffff; /* softWhite    */
  --c-sunken: #f1ece3; /* warmCloud    */
  --c-line: #e5dfd3; /* sand100      */
  --c-line-strong: #d8d0c0;

  /* -- Ink (TouchSemantic.text*) -- */
  --c-ink: #2c2a26; /* stone800 — 13.4:1 on canvas */
  --c-body: #5a5448; /* stone600 —  7.0:1          */
  --c-muted: #665e50; /* stone500, darkened — 6.0:1 */

  /* -- Brand -- */
  --c-brand: #6468c8; /* bluePrimary — FILLS ONLY   */
  --c-brand-warm: #686dcf; /* bluePrimaryWarm — gradient */
  --c-link: #5458bc; /* darkened for AA link text  */
  --c-eyebrow: #6f6490; /* darkened duskLavender      */
  --c-periwinkle: #afbbf2;
  --c-accent-mark: #6468c8; /* icon/graphic accent — flips in dark, see below */
  --c-wash: #eef1fb; /* periwinkleWash             */
  --c-on-brand: #ffffff;

  /* -- Warm accent (TouchSemantic.brandWarm*) -- */
  --c-peach-soft: #fbe6de;

  --c-focus: #5458bc;
  --c-selection: #e4e8fb; /* blueSoft */

  /* -- Type -- */
  --f-display: 'Montserrat', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --f-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --f-word: 'Sora', 'Montserrat', system-ui, sans-serif;
  --f-eyebrow: 'Nunito', 'Inter', system-ui, sans-serif;

  /* -- Space (TouchSpacing) -- */
  --s-xs: 4px;
  --s-sm: 8px;
  --s-md: 12px;
  --s-lg: 16px;
  --s-xl: 24px;
  --s-2xl: 32px;
  --s-3xl: 48px;
  --s-4xl: 64px;
  --s-band: clamp(64px, 11vw, 128px); /* vertical rhythm between page bands */
  --s-gutter: clamp(20px, 5vw, 40px);

  /* -- Radius (TouchRadius) -- */
  --r-sm: 8px;
  --r-md: 14px;
  --r-section: 16px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  /* -- Elevation (TouchElevation) -- */
  --e-1: 0 1px 2px rgba(44, 42, 38, 0.06);
  --e-2: 0 2px 8px rgba(44, 42, 38, 0.08), 0 1px 2px rgba(44, 42, 38, 0.04);

  /* -- Motion -- */
  --t-fast: 140ms;
  --t-base: 220ms;
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);

  --w-page: 1120px;
  --w-prose: 68ch;
}

/*
  Dark theme. The app itself is light-only, so these values are NOT inverted
  app tokens — inverting a warm cream palette produces a blue-grey corpse. The
  hues come from the one dark surface Touch already ships: the /confirm page's
  `prefers-color-scheme: dark` block in
  `backend/functions/src/auth/confirm_endpoint.ts`, kept in agreement here so
  the two surfaces cannot drift.
*/
@media (prefers-color-scheme: dark) {
  :root {
    --c-canvas: #17151a;
    --c-raised: #211e25;
    --c-sunken: #121016;
    --c-line: #322e38;
    --c-line-strong: #423d4a;

    --c-ink: #f2efea;
    --c-body: #b5aea4;
    --c-muted: #9e958a;

    --c-brand: #6468c8;
    --c-brand-warm: #7175d6;
    --c-link: #afbbf2; /* periwinkle — 9.7:1 on canvas */
    --c-eyebrow: #afbbf2;
    --c-accent-mark: #afbbf2; /* #6468C8 is only 2.9:1 on #17151A */
    --c-wash: #1e1c28;
    --c-on-brand: #ffffff;
    --c-peach-soft: #2a211f;

    --c-focus: #afbbf2;
    --c-selection: #2f3054;

    --e-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --e-2: 0 2px 10px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.3);
  }
}

/* ============================================================
   3. Reset + base
   ============================================================ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100svh;
  background: var(--c-canvas);
  color: var(--c-body);
  font-family: var(--f-body);
  font-size: 17px;
  line-height: 1.65;
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  flex-direction: column;
}

::selection {
  background: var(--c-selection);
  color: var(--c-ink);
}

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

h1,
h2,
h3,
h4 {
  font-family: var(--f-display);
  color: var(--c-ink);
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0;
}

p {
  margin: 0 0 1.1em;
  text-wrap: pretty;
}

p:last-child {
  margin-bottom: 0;
}

strong,
b {
  color: var(--c-ink);
  font-weight: 600;
}

a {
  color: var(--c-link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color var(--t-fast) var(--ease-out);
}

a:hover {
  color: var(--c-ink);
}

/* Never remove the ring — replace it with a better one. */
:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 3px;
  border-radius: 4px;
}

:focus:not(:focus-visible) {
  outline: none;
}

/* ============================================================
   4. Layout
   ============================================================ */

.shell {
  width: 100%;
  max-width: var(--w-page);
  margin-inline: auto;
  padding-inline: var(--s-gutter);
}

.shell--prose {
  max-width: calc(var(--w-prose) + 2 * 40px);
}

main {
  flex: 1 0 auto;
}

/* A full-bleed horizontal band. The modifier picks the surface. */
.band {
  padding-block: var(--s-band);
}

/* The first band on a page sits under the header, which already gives it air. */
.band--hero {
  padding-top: clamp(28px, 4.5vw, 56px);
}

.band--sunken {
  background: var(--c-sunken);
}

.band--raised {
  background: var(--c-raised);
}

.band--tight {
  padding-block: clamp(40px, 7vw, 72px);
}

.band + .band:not(.band--sunken):not(.band--raised) {
  padding-top: 0;
}

.rule {
  border: 0;
  border-top: 1px solid var(--c-line);
  margin: 0;
}

.stack > * + * {
  margin-top: var(--s-lg);
}

/* Skip link — first focusable element on every page. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--c-ink);
  color: var(--c-canvas);
  padding: 12px 18px;
  border-radius: 0 0 var(--r-md) 0;
  font-size: 15px;
  font-weight: 500;
}

.skip:focus {
  left: 0;
  color: var(--c-canvas);
}

/* ============================================================
   5. Brand lockup
   ============================================================ */

.lockup {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  color: var(--c-ink);
}

.lockup__mark {
  width: auto;
  height: 1.05em;
  color: currentColor;
  flex: none;
}

.lockup__word {
  font-family: var(--f-word);
  font-weight: 600;
  font-size: 1.28em;
  line-height: 1;
  letter-spacing: -0.02em;
  color: currentColor;
}

.lockup--nav {
  font-size: 18px;
}

.lockup--hero {
  font-size: 26px;
}

/*
  The lockup is only ~22px of ink. As a LINK that is a 22px tap target, half
  the 44px floor (`TouchA11y.minTapTarget`). The header has the room, so the
  hit area is grown around the artwork rather than the artwork being grown.
*/
a.lockup {
  min-height: 44px;
}

a.lockup:hover {
  color: var(--c-brand);
}

/* ============================================================
   6. Header / footer
   ============================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--c-canvas) 88%, transparent);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-base) var(--ease-out);
}

/* Only reveal the hairline once the page has actually scrolled under it. */
.site-header[data-scrolled='true'] {
  border-bottom-color: var(--c-line);
}

@supports not (backdrop-filter: blur(1px)) {
  .site-header {
    background: var(--c-canvas);
  }
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-lg);
  min-height: 68px;
  padding-block: 10px;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(4px, 2vw, 8px);
  flex-wrap: wrap;
  justify-content: flex-end;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: var(--r-sm);
  color: var(--c-body);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  transition:
    color var(--t-fast) var(--ease-out),
    background-color var(--t-fast) var(--ease-out);
}

.site-nav a:hover {
  color: var(--c-ink);
  background: var(--c-sunken);
}

.site-nav a[aria-current='page'] {
  color: var(--c-ink);
  font-weight: 600;
}

.site-footer {
  flex: none;
  background: var(--c-sunken);
  border-top: 1px solid var(--c-line);
  padding-block: var(--s-3xl) var(--s-2xl);
  margin-top: var(--s-band);
}

.site-footer__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2xl) var(--s-4xl);
  justify-content: space-between;
  align-items: flex-start;
}

.site-footer__brand {
  max-width: 30ch;
}

.site-footer__brand p {
  margin: var(--s-md) 0 0;
  font-size: 14.5px;
  color: var(--c-muted);
  line-height: 1.6;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2xl) var(--s-3xl);
}

.site-footer__col h2 {
  font-family: var(--f-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 var(--s-md);
}

.site-footer__col ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-footer__col li + li {
  margin-top: 2px;
}

.site-footer__col a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 15px;
  color: var(--c-body);
  text-decoration: none;
}

.site-footer__col a:hover {
  color: var(--c-ink);
  text-decoration: underline;
}

.site-footer__base {
  margin-top: var(--s-2xl);
  padding-top: var(--s-lg);
  border-top: 1px solid var(--c-line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-sm) var(--s-xl);
  justify-content: space-between;
  font-size: 13.5px;
  color: var(--c-muted);
}

/* ============================================================
   7. Type roles
   ============================================================ */

.eyebrow {
  display: block;
  font-family: var(--f-eyebrow);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0.09em;
  text-transform: lowercase;
  color: var(--c-eyebrow);
  margin: 0 0 var(--s-md);
}

.display {
  font-size: clamp(36px, 5.1vw, 56px);
  line-height: 1.08;
  letter-spacing: -0.035em;
  margin: 0;
}

.title {
  font-size: clamp(27px, 3.6vw, 38px);
  line-height: 1.15;
  letter-spacing: -0.028em;
  margin: 0;
}

.subtitle {
  font-size: clamp(19px, 2vw, 22px);
  line-height: 1.3;
  letter-spacing: -0.02em;
  margin: 0;
}

.lede {
  font-size: clamp(18px, 1.9vw, 21px);
  line-height: 1.55;
  color: var(--c-body);
  max-width: 46ch;
}

.measure {
  max-width: var(--w-prose);
}

.muted {
  color: var(--c-muted);
}

.small {
  font-size: 14.5px;
  line-height: 1.6;
}

/* ============================================================
   8. Buttons
   ============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-sm);
  min-height: 52px;
  padding: 14px 26px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-family: var(--f-body);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform var(--t-fast) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out),
    background-color var(--t-fast) var(--ease-out),
    border-color var(--t-fast) var(--ease-out),
    color var(--t-fast) var(--ease-out);
}

/* Filled primary keeps the app's gradient (TouchSemantic.gradientPrimary). */
.btn--primary {
  background-image: linear-gradient(135deg, var(--c-brand-warm), var(--c-brand));
  color: var(--c-on-brand);
  box-shadow: var(--e-1);
}

.btn--primary:hover {
  color: var(--c-on-brand);
  box-shadow: var(--e-2);
  transform: translateY(-1px);
}

.btn--primary:active {
  transform: translateY(0);
  box-shadow: var(--e-1);
}

.btn--ghost {
  background: transparent;
  border-color: var(--c-line-strong);
  color: var(--c-ink);
}

.btn--ghost:hover {
  background: var(--c-raised);
  border-color: var(--c-muted);
  color: var(--c-ink);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-md);
  align-items: center;
}

/*
  The pre-release state marker. Deliberately NOT a button: there is nothing to
  download yet, and a disabled-looking CTA that does nothing is worse than an
  honest sentence. Swap this for a store badge on the day the listing is live.
*/
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 20px 11px 16px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-pill);
  background: var(--c-raised);
  font-size: 15px;
  color: var(--c-body);
  box-shadow: var(--e-1);
}

.status-pill__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c-accent-mark);
  flex: none;
}

/* ============================================================
   9. Cards, steps, promises
   ============================================================ */

.grid {
  display: grid;
  gap: var(--s-xl);
}

@media (min-width: 720px) {
  .grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }
  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  background: var(--c-raised);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: var(--s-xl);
}

.card h3 {
  font-size: 19px;
  line-height: 1.3;
  letter-spacing: -0.015em;
  margin: 0 0 var(--s-sm);
}

.card p {
  font-size: 15.5px;
  line-height: 1.6;
  margin: 0;
}

/*
  The three-step explainer. The step number is a typographic element, not a
  badge or a counter — it reads as an index in a printed page, which is the
  opposite of a notification dot.
*/
.step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-lg);
  align-items: start;
}

.step__n {
  font-family: var(--f-body);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--c-eyebrow);
  padding-top: 5px;
}

.step h3 {
  font-size: clamp(20px, 2.2vw, 24px);
  line-height: 1.25;
  margin: 0 0 var(--s-sm);
}

.step p {
  margin: 0;
  max-width: 42ch;
}

.step + .step {
  margin-top: var(--s-2xl);
  padding-top: var(--s-2xl);
  border-top: 1px solid var(--c-line);
}

/* The privacy promises. A check glyph, never a coloured badge. */
.promises {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-lg);
}

.promises li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: var(--s-md);
  align-items: start;
}

.promises svg {
  width: 22px;
  height: 22px;
  color: var(--c-accent-mark);
  margin-top: 3px;
  flex: none;
}

.promises b {
  display: block;
  font-weight: 600;
  color: var(--c-ink);
  margin-bottom: 2px;
}

.promises span {
  font-size: 15.5px;
  line-height: 1.6;
}

/* "What Touch refuses to be" — the Avoid list, stated positively. */
.refusals {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-md);
}

.refusals li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: var(--s-md);
  align-items: start;
  font-size: 16px;
}

.refusals svg {
  width: 22px;
  height: 22px;
  color: var(--c-muted);
  margin-top: 3px;
  flex: none;
}

/* A quiet pull-quote / statement block. */
.statement {
  border-left: 2px solid var(--c-periwinkle);
  padding-left: var(--s-xl);
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(21px, 2.6vw, 28px);
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: var(--c-ink);
  max-width: 24ch;
}

/* ============================================================
   9b. Landing-page composition
   ============================================================ */

.hero {
  display: grid;
  gap: var(--s-3xl);
  align-items: center;
  padding-block: clamp(8px, 3vw, 32px);
}

@media (min-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr);
    gap: var(--s-4xl);
  }
}

.hero__copy .display {
  margin-bottom: var(--s-xl);
}

.hero__cta {
  margin-top: var(--s-2xl);
}

.hero__cta-note {
  margin: var(--s-lg) 0 0;
  max-width: 40ch;
}

.hero__figure {
  justify-self: center;
  width: 100%;
  max-width: 340px;
}

.journey {
  width: 100%;
  height: auto;
}

.journey__time {
  font-family: var(--f-body);
  font-size: 11px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  fill: var(--c-muted);
}

.journey__time--live {
  fill: var(--c-ink);
  font-weight: 600;
}

/*
  One element breathes, slowly, and only where motion is welcome — the halo
  around the Station that has something in it. 4.5s is deliberately longer
  than a notification pulse: it should read as a heartbeat, not as a nudge.
*/
@media (prefers-reduced-motion: no-preference) {
  .journey__halo {
    transform-box: fill-box;
    transform-origin: center;
    animation: journey-pulse 4.5s var(--ease-out) infinite;
  }
}

@keyframes journey-pulse {
  0%,
  70%,
  100% {
    opacity: 0.55;
    transform: scale(1);
  }
  35% {
    opacity: 1;
    transform: scale(1.14);
  }
}

.section-head {
  max-width: 30ch;
  margin-bottom: var(--s-3xl);
}

.steps {
  max-width: 62ch;
}

.privacy-split,
.refuse-split {
  display: grid;
  gap: var(--s-3xl);
  align-items: start;
}

@media (min-width: 880px) {
  .privacy-split,
  .refuse-split {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
    gap: var(--s-4xl);
  }
}

.privacy-split__lead .title {
  margin-bottom: var(--s-lg);
}

.privacy-split__lead .btn {
  margin-top: var(--s-sm);
}

.refuse-split .title {
  margin-bottom: var(--s-lg);
}

.closing {
  display: grid;
  gap: var(--s-2xl) var(--s-4xl);
  align-items: end;
}

@media (min-width: 880px) {
  .closing {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.closing__aside {
  max-width: 44ch;
}

.closing__aside .btn {
  margin-top: var(--s-md);
}

/* ============================================================
   10. Prose — the legal pages
   ============================================================ */

.prose {
  max-width: var(--w-prose);
}

.prose > h2 {
  font-size: clamp(21px, 2.4vw, 25px);
  line-height: 1.25;
  margin: var(--s-3xl) 0 var(--s-md);
  padding-top: var(--s-xl);
  border-top: 1px solid var(--c-line);
  scroll-margin-top: 88px;
}

.prose > h2:first-child,
.prose > h2.first {
  border-top: 0;
  padding-top: 0;
  margin-top: 0;
}

.prose > h3 {
  font-size: 18px;
  line-height: 1.35;
  margin: var(--s-xl) 0 var(--s-sm);
}

.prose ul,
.prose ol {
  padding-left: 1.3em;
  margin: 0 0 1.1em;
}

.prose li {
  margin: 0.4em 0;
}

.prose li::marker {
  color: var(--c-muted);
}

/* The page's opening promise block. */
.lede-card {
  background: var(--c-raised);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: var(--s-xl);
  margin: var(--s-xl) 0 var(--s-2xl);
  box-shadow: var(--e-1);
}

.lede-card > :first-child {
  margin-top: 0;
}

.lede-card > :last-child {
  margin-bottom: 0;
}

.note {
  background: var(--c-sunken);
  border: 1px solid var(--c-line);
  border-radius: var(--r-section);
  padding: var(--s-lg) var(--s-xl);
  color: var(--c-body);
  font-size: 15.5px;
  line-height: 1.6;
  margin: var(--s-xl) 0;
}

.band--sunken .note {
  background: var(--c-raised);
}

/*
  Tables scroll inside themselves — the page body never scrolls sideways.

  On a wide screen they also break OUT of the prose measure. A 68ch column is
  right for reading sentences and wrong for a three-column data table: inside
  it, the Privacy Policy §2 table wrapped almost every cell to four lines. The
  breakout is centred on the prose column, which is itself centred, so the
  table stays centred on the page.
*/
.table-wrap {
  overflow-x: auto;
  margin: var(--s-lg) 0 var(--s-xl);
  border: 1px solid var(--c-line);
  border-radius: var(--r-section);
  background: var(--c-raised);
  -webkit-overflow-scrolling: touch;
}

@media (min-width: 940px) {
  .prose .table-wrap {
    width: min(980px, calc(100vw - 2 * var(--s-gutter)));
    margin-left: 50%;
    transform: translateX(-50%);
  }
}

.prose table {
  width: 100%;
  min-width: 460px;
  border-collapse: collapse;
  font-size: 15px;
  margin: 0;
}

.prose th,
.prose td {
  text-align: left;
  vertical-align: top;
  padding: 12px 16px;
  border-bottom: 1px solid var(--c-line);
}

.prose thead th {
  color: var(--c-muted);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--c-sunken);
  white-space: nowrap;
}

.prose tbody tr:last-child td {
  border-bottom: 0;
}

.prose td:first-child {
  font-weight: 600;
  color: var(--c-ink);
}

/* Page masthead shared by the legal pages. */
.masthead {
  padding-block: clamp(40px, 7vw, 72px) var(--s-xl);
}

.masthead h1 {
  font-size: clamp(32px, 5vw, 46px);
  line-height: 1.08;
  letter-spacing: -0.032em;
}

.masthead__meta {
  margin: var(--s-md) 0 0;
  font-size: 14.5px;
  color: var(--c-muted);
}

/*
  Contents list. Only the 13-section Privacy Policy gets one — on a short page
  it would be chrome standing between the reader and their answer. It is a
  wayfinding aid on a long legal document, not a navigation pattern.
*/
.toc {
  background: var(--c-sunken);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: var(--s-xl);
  margin-bottom: var(--s-3xl);
  max-width: var(--w-prose);
}

.toc h2 {
  font-family: var(--f-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 var(--s-md);
}

.toc ol {
  list-style: none;
  counter-reset: toc;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: var(--s-2xl);
}

.toc li {
  counter-increment: toc;
  break-inside: avoid;
}

.toc a {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 10px 0;
  font-size: 15px;
  color: var(--c-body);
  text-decoration: none;
}

.toc a::before {
  content: counter(toc);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-eyebrow);
  min-width: 1.2em;
}

.toc a:hover {
  color: var(--c-ink);
  text-decoration: underline;
}

@media (max-width: 620px) {
  .toc ol {
    columns: 1;
  }
}

/*
  Numbered steps inside prose (the in-app deletion instructions).

  NOT a grid. `display: grid` on the <li> made every inline child — each
  <strong> naming a button to tap — its own grid item, so "Tap Delete account"
  shattered into three stacked fragments. The counter is positioned out of
  flow instead, which leaves the list item's inline content intact.
*/
.prose ol.steps-list {
  counter-reset: step;
  list-style: none;
  padding-left: 0;
}

.prose ol.steps-list > li {
  counter-increment: step;
  position: relative;
  padding-left: 34px;
  margin: 0.7em 0;
}

.prose ol.steps-list > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 22px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  line-height: inherit;
  color: var(--c-eyebrow);
}

/* ============================================================
   11. Responsive + motion + print
   ============================================================ */

/*
  The header must stay ONE row. Wrapped, it grew to ~200px on a 390px phone
  and pushed the whole hero off the first screen — the opposite of a calm
  first impression. Two measures, in order of preference:
    1. In-page anchors are dropped below 620px. They only ever shortcut a
       scroll the reader is about to do anyway, and the section is still
       reachable — nothing becomes unreachable, which is the rule.
    2. The remaining items tighten. Height stays 44px: the tap target is
       preserved, only the horizontal padding gives.
*/
@media (max-width: 620px) {
  .site-nav {
    flex-wrap: nowrap;
  }

  .site-nav a[href^='#'] {
    display: none;
  }

  .site-nav a {
    padding: 0 8px;
    font-size: 14.5px;
  }

  .lockup--nav {
    font-size: 17px;
  }
}

@media (max-width: 560px) {
  body {
    font-size: 16.5px;
  }

  .site-header__inner {
    min-height: 60px;
  }

  .btn {
    width: 100%;
  }

  .statement {
    padding-left: var(--s-lg);
  }

  .step {
    grid-template-columns: 1fr;
    gap: var(--s-sm);
  }

  .step__n {
    padding-top: 0;
  }
}

@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;
  }

  .btn--primary:hover {
    transform: none;
  }
}

/*
  People genuinely print privacy policies — for their own records, and to hand
  to a DPO. Give them a readable document rather than a screenshot of a website.
*/
@media print {
  :root {
    --c-canvas: #ffffff;
    --c-raised: #ffffff;
    --c-sunken: #ffffff;
    --c-ink: #000000;
    --c-body: #1a1a1a;
    --c-muted: #444444;
    --c-line: #cccccc;
  }

  .site-header,
  .site-footer__links,
  .toc,
  .skip {
    display: none;
  }

  body {
    font-size: 11pt;
    line-height: 1.5;
  }

  .band,
  .masthead {
    padding-block: 0;
  }

  .prose,
  .shell,
  .shell--prose {
    max-width: none;
    padding-inline: 0;
  }

  .prose > h2 {
    break-after: avoid;
    margin-top: 20pt;
  }

  .table-wrap,
  .lede-card,
  .note {
    break-inside: avoid;
    box-shadow: none;
  }

  a {
    color: #000000;
    text-decoration: underline;
  }

  /* Printed links are dead ends unless the URL comes with them. */
  .prose a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
    color: #444444;
    word-break: break-all;
  }
}
