/* Generated by web/build.mjs from web/tokens.mjs and design/system/tokens.mjs. Do not edit. */
:root {
  color-scheme: light dark;
  --font-serif: "Newsreader", "Newsreader Fallback", "New York", ui-serif, Georgia, serif;
  --font-sans: "Inter", "Inter Fallback", -apple-system, BlinkMacSystemFont, system-ui, "Helvetica Neue", Arial, sans-serif;
  --type-display-size: 2.5rem;
  --type-display-line: 1.2;
  --type-display-weight: 600;
  --type-display-tracking: 0em;
  --type-h1-size: 2rem;
  --type-h1-line: 1.25;
  --type-h1-weight: 600;
  --type-h1-tracking: 0em;
  --type-card-title-size: 1.5rem;
  --type-card-title-line: 1.25;
  --type-card-title-weight: 600;
  --type-card-title-tracking: 0em;
  --type-quote-size: 1.375rem;
  --type-quote-line: 1.364;
  --type-quote-weight: 600;
  --type-quote-tracking: 0em;
  --type-h3-size: 1.0625rem;
  --type-h3-line: 1.353;
  --type-h3-weight: 600;
  --type-h3-tracking: 0em;
  --type-body-lg-size: 1.0625rem;
  --type-body-lg-line: 1.529;
  --type-body-lg-weight: 400;
  --type-body-lg-tracking: 0em;
  --type-body-size: 0.9375rem;
  --type-body-line: 1.533;
  --type-body-weight: 400;
  --type-body-tracking: 0.005em;
  --type-body-sm-size: 0.8125rem;
  --type-body-sm-line: 1.462;
  --type-body-sm-weight: 400;
  --type-body-sm-tracking: 0.01em;
  --type-label-size: 0.75rem;
  --type-label-line: 1.333;
  --type-label-weight: 600;
  --type-label-tracking: 0.06em;
  --type-chip-size: 0.8125rem;
  --type-chip-line: 1.308;
  --type-chip-weight: 600;
  --type-chip-tracking: 0.005em;
  --type-eyebrow-size: 0.8125rem;
  --type-eyebrow-line: 1.385;
  --type-eyebrow-weight: 600;
  --type-eyebrow-tracking: 0.01em;
  --type-caption-size: 0.75rem;
  --type-caption-line: 1.417;
  --type-caption-weight: 400;
  --type-caption-tracking: 0.012em;
  --type-wordmark-size: 1.875rem;
  --type-wordmark-line: 1.2;
  --type-wordmark-weight: 600;
  --type-wordmark-tracking: 0em;
  --space-0: 0rem;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-7: 1.75rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-14: 3.5rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;
  --space-0-5: 0.125rem;
  --space-1-5: 0.375rem;
  --space-2-5: 0.625rem;
  --radius-sm: 0.75rem;
  --radius-md: 1.125rem;
  --radius-lg: 1.5rem;
  --radius-block: 1.875rem;
  --radius-full: 999px;
  --gutter: 1rem; /* 16 px each side at phone width */
  --content-max: 70rem;
  --reading-max: 45rem;
  --phone-width: 15.5rem;
  --c-bg: #F7F7F7;
  --c-surface: #FFFFFF;
  --c-sunken: #EEEEEE;
  --c-border: #E6E6E6;
  --c-border-strong: #D2D2D2;
  --c-ink: #1D1D1D;
  --c-ink-secondary: #575757;
  --c-link: #0F3D2C;
  --c-hero: #1E2326;
  --c-on-hero: #FFF6E6;
  --c-on-hero-secondary: #C3CACD;
  --c-control: #1D1D1D;
  --c-on-control: #FFF6E6;
  --c-focus: #1D1D1D;
  --c-on-hero-focus: #FFF6E6;
  --c-phone: #2E3134;
  --c-phone-rim: #2E3134;
  --c-phone-rim-on-hero: #5A5F63;
  --c-phone-edge: #1F2124;
  --c-hero-lit: #303435;
  --c-hero-wash: #393C3D;
  --c-score-red: #FF6B7D;
  --c-score-amber: #FFB23F;
  --c-score-green: #6CD362;
  --shadow-card: 0 1px 2px rgba(29, 29, 29, 0.05), 0 4px 14px rgba(29, 29, 29, 0.06);
  --shadow-device: 0 2px 4px rgba(29, 29, 29, 0.1), 0 30px 80px rgba(29, 29, 29, 0.22);
  --shadow-block: 0 2px 4px rgba(20, 24, 26, 0.14), 0 18px 36px -10px rgba(20, 24, 26, 0.34);
  --c-hero-wash-alpha: rgba(255, 246, 230, 0.12);
  --c-hero-rule: rgba(255, 246, 230, 0.24);
  --c-dial-track: rgba(255, 246, 230, 0.14);
  --c-scan-ring: #9FB8AC;
  --illo-pack-sky: #4A78B8;
  --illo-pack-sky-deep: #30588F;
  --illo-pack-plum: #7A4A8C;
  --illo-pack-plum-deep: #5B3369;
  --illo-oat: #F3E6CC;
  --illo-oat-deep: #DCC59B;
  --illo-crust: #C98A47;
  --illo-berry: #6A4FD6;
  --illo-berry-deep: #4A33A8;
  --illo-tomato: #FF6A4D;
  --illo-tomato-deep: #D9472F;
  --illo-leaf: #7DCB4A;
  --illo-leaf-deep: #4E9A2E;
  --illo-white: #FFFFFF;
  --illo-cream: #FFF6E6;
  --illo-metal: #EEEEEE;
  --illo-metal-deep: #D2D2D2;
  --illo-hi: rgba(255, 255, 255, 0.5);
  --illo-shade: rgba(29, 29, 29, 0.14);
  --illo-ink: #1D1D1D;
  --illo-print: rgba(29, 29, 29, 0.34);
  --illo-print-head: rgba(29, 29, 29, 0.62);
  --illo-print-edge: rgba(29, 29, 29, 0.16);
  --illo-ground: rgba(4, 8, 12, 0.34);
  --spring-default: linear(0, 0.0164, 0.0578, 0.115, 0.1812, 0.2513, 0.3221, 0.3911, 0.4567, 0.5181, 0.5747, 0.6262, 0.6728, 0.7145, 0.7517, 0.7846, 0.8136, 0.839, 0.8613, 0.8807, 0.8976, 0.9122, 0.9248, 0.9358, 0.9452, 0.9532, 0.9602, 0.9661, 0.9712, 0.9755, 0.9792, 0.9824, 0.9851, 0.9874, 0.9893, 0.991, 0.9924, 0.9935, 0.9946, 0.9954, 0.9961, 0.9967, 0.9973, 0.9977, 0.9981, 0.9984, 0.9986, 0.9988, 1);
  --spring-default-dur: 516ms;
  --spring-default-damping: 1;
  --spring-default-response: 0.35;
  --spring-snappy: linear(0, 0.0165, 0.058, 0.1154, 0.1817, 0.2521, 0.323, 0.3921, 0.4578, 0.5192, 0.5758, 0.6273, 0.6738, 0.7155, 0.7527, 0.7855, 0.8145, 0.8399, 0.8621, 0.8814, 0.8982, 0.9128, 0.9254, 0.9362, 0.9456, 0.9536, 0.9605, 0.9664, 0.9714, 0.9758, 0.9794, 0.9826, 0.9852, 0.9875, 0.9894, 0.9911, 0.9925, 0.9936, 0.9946, 0.9955, 0.9962, 0.9968, 0.9973, 0.9977, 0.9981, 0.9984, 0.9986, 0.9989, 1);
  --spring-snappy-dur: 325ms;
  --spring-snappy-damping: 1;
  --spring-snappy-response: 0.22;
  --spring-sheet: linear(0, 0.0164, 0.0578, 0.115, 0.1812, 0.2513, 0.3221, 0.3911, 0.4567, 0.5181, 0.5747, 0.6262, 0.6728, 0.7145, 0.7517, 0.7846, 0.8136, 0.839, 0.8613, 0.8807, 0.8976, 0.9122, 0.9248, 0.9358, 0.9452, 0.9532, 0.9602, 0.9661, 0.9712, 0.9755, 0.9792, 0.9824, 0.9851, 0.9874, 0.9893, 0.991, 0.9924, 0.9935, 0.9946, 0.9954, 0.9961, 0.9967, 0.9973, 0.9977, 0.9981, 0.9984, 0.9986, 0.9988, 1);
  --spring-sheet-dur: 516ms;
  --spring-sheet-damping: 1;
  --spring-sheet-response: 0.35;
  --spring-dial-fill: linear(0, 0.0163, 0.0577, 0.1148, 0.1808, 0.2508, 0.3215, 0.3904, 0.456, 0.5174, 0.5739, 0.6255, 0.672, 0.7138, 0.751, 0.7839, 0.813, 0.8385, 0.8608, 0.8802, 0.8971, 0.9118, 0.9245, 0.9354, 0.9449, 0.953, 0.9599, 0.9659, 0.971, 0.9754, 0.9791, 0.9823, 0.985, 0.9873, 0.9892, 0.9909, 0.9923, 0.9935, 0.9945, 0.9954, 0.9961, 0.9967, 0.9972, 0.9977, 0.998, 0.9983, 0.9986, 0.9988, 1);
  --spring-dial-fill-dur: 795ms;
  --spring-dial-fill-damping: 1;
  --spring-dial-fill-response: 0.54;
  --spring-draw: linear(0, 0.0163, 0.0575, 0.1145, 0.1804, 0.2503, 0.3209, 0.3897, 0.4553, 0.5166, 0.5731, 0.6246, 0.6712, 0.713, 0.7502, 0.7832, 0.8123, 0.8379, 0.8602, 0.8797, 0.8967, 0.9114, 0.9241, 0.9351, 0.9445, 0.9527, 0.9597, 0.9657, 0.9708, 0.9752, 0.9789, 0.9821, 0.9848, 0.9872, 0.9891, 0.9908, 0.9922, 0.9934, 0.9945, 0.9953, 0.996, 0.9967, 0.9972, 0.9976, 0.998, 0.9983, 0.9986, 0.9988, 1);
  --spring-draw-dur: 1029ms;
  --spring-draw-damping: 1;
  --spring-draw-response: 0.7;
  --dur-instant: 80ms;
  --dur-fast: 150ms;
  --dur-medium: 300ms;
  --dur-pulse: 200ms;
  --dur-scan-pulse: 1200ms;
  --dur-label-mark: 320ms;
  --dur-row-stagger: 80ms;
  --dur-ob1-art-stagger: 45ms;
  --dur-settle-stagger: 40ms;
  --ease-out-smooth: cubic-bezier(0.0, 0.0, 0.2, 1.0);
  --ease-in-smooth: cubic-bezier(0.4, 0.0, 1.0, 1.0);
  --ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1.0);
  --scale-press: 0.97;
  --scale-share-press: 0.94;
  --scale-pulse: 1.06;
  --scale-lift: 1.02;
  --scale-ring-from: 0.8;
  --scale-ring-to: 1.2;
  --opacity-pulse-start: 0.5;
  --offset-card-rise-y: 1.5rem;
  --offset-ob1-settle-y: -0.75rem;
  --offset-settle-y: 0.5rem;
}
@media (prefers-color-scheme: dark) {
  :root {
    --c-bg: #121212;
    --c-surface: #1C1C1C;
    --c-sunken: #262626;
    --c-border: #333333;
    --c-border-strong: #5A5A5A;
    --c-ink: #EDEDED;
    --c-ink-secondary: #A8A8A8;
    --c-link: #8CCFB1;
    --c-hero: #1E2326;
    --c-on-hero: #FFF6E6;
    --c-on-hero-secondary: #C3CACD;
    --c-control: #EDEDED;
    --c-on-control: #121212;
    --c-focus: #EDEDED;
    --c-on-hero-focus: #FFF6E6;
    --c-phone: #3A3D40;
    --c-phone-rim: #55585B;
    --c-phone-rim-on-hero: #5A5F63;
    --c-phone-edge: #232528;
    --c-hero-lit: #303435;
    --c-hero-wash: #393C3D;
    --c-score-red: #FF6B7D;
    --c-score-amber: #FFB23F;
    --c-score-green: #6CD362;
    --shadow-card: 0 0 0 1px rgba(255, 255, 255, 0.04);
    --shadow-device: 0 2px 4px rgba(0, 0, 0, 0.5), 0 30px 80px rgba(0, 0, 0, 0.6);
    --shadow-block: 0 0 0 1px rgba(255, 246, 230, 0.08);
  }
}
@media (prefers-contrast: more) {
  :root {
    --c-bg: #F7F7F7;
    --c-surface: #FFFFFF;
    --c-sunken: #EEEEEE;
    --c-border: #BCBCBC;
    --c-border-strong: #7F7F7F;
    --c-ink: #1D1D1D;
    --c-ink-secondary: #3E3E3E;
    --c-link: #0F3D2C;
    --c-hero: #1E2326;
    --c-on-hero: #FFF6E6;
    --c-on-hero-secondary: #DEE3E5;
    --c-control: #1D1D1D;
    --c-on-control: #FFF6E6;
    --c-focus: #1D1D1D;
    --c-on-hero-focus: #FFF6E6;
    --c-phone: #2E3134;
    --c-phone-rim: #2E3134;
    --c-phone-rim-on-hero: #5A5F63;
    --c-phone-edge: #1F2124;
    --c-hero-lit: #303435;
    --c-hero-wash: #393C3D;
    --c-score-red: #FF6B7D;
    --c-score-amber: #FFB23F;
    --c-score-green: #6CD362;
  }
}
@media (prefers-color-scheme: dark) and (prefers-contrast: more) {
  :root {
    --c-bg: #121212;
    --c-surface: #1C1C1C;
    --c-sunken: #262626;
    --c-border: #8A8A8A;
    --c-border-strong: #8A8A8A;
    --c-ink: #FFFFFF;
    --c-ink-secondary: #CFCFCF;
    --c-link: #A0D1BA;
    --c-hero: #1E2326;
    --c-on-hero: #FFF6E6;
    --c-on-hero-secondary: #DEE3E5;
    --c-control: #FFFFFF;
    --c-on-control: #121212;
    --c-focus: #FFFFFF;
    --c-on-hero-focus: #FFF6E6;
    --c-phone: #3A3D40;
    --c-phone-rim: #55585B;
    --c-phone-rim-on-hero: #5A5F63;
    --c-phone-edge: #232528;
    --c-hero-lit: #303435;
    --c-hero-wash: #393C3D;
    --c-score-red: #FF6B7D;
    --c-score-amber: #FFB23F;
    --c-score-green: #6CD362;
  }
}

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-400.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-600.woff") format("woff");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("/assets/fonts/newsreader-600.woff") format("woff");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("/assets/fonts/newsreader-600-italic.woff") format("woff");
  font-weight: 600;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-800-figures.woff") format("woff");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial"), local("ArialMT");
  font-weight: 400;
  font-style: normal;
  size-adjust: 107.48%;
  ascent-override: 90.14%;
  descent-override: 22.44%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 600;
  font-style: normal;
  size-adjust: 101.32%;
  ascent-override: 95.62%;
  descent-override: 23.81%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia Bold"), local("Georgia-Bold");
  font-weight: 600;
  font-style: normal;
  size-adjust: 84.75%;
  ascent-override: 86.72%;
  descent-override: 31.27%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia Bold Italic"), local("Georgia-BoldItalic");
  font-weight: 600;
  font-style: italic;
  size-adjust: 79.16%;
  ascent-override: 92.86%;
  descent-override: 33.48%;
  line-gap-override: 0%;
}

/* The marketing site's stylesheet (web/build.mjs puts the generated tokens and the @font-face rules above it).
   Every colour is a token (--c-*, web/tokens.mjs, from design/system/tokens.mjs); sizes are tokens or rem, so the
   reader's text size scales the page (WCAG 1.4.4); breakpoints are in em. Phone width first, a 16 px gutter.
   Direction B (D09): a neutral off-white page, white cards, Ink type, and one bold colour moment per page, the Charcoal
   hero field with Cream type; Forest only on links. Newsreader 600 for the page's one serif line, Inter for everything
   else (D11; DESIGN §3.3: one serif headline per screen).
   Motion (DESIGN §5; apple-design-motion; `motion.md › Best practices`: "Add motion purposefully"): one signature moment,
   the hero's story; everything else is quiet. Only transform and opacity move (the dial's arc, a stroke, is the one
   paint), springs are the app's own as CSS linear() easings (web/tokens.mjs › MOTION), critically damped, with no bounce
   (nothing here follows a flick). The base styles are always the last frame, so Reduce Motion shows it at once
   (`accessibility.md › Cognitive`), and nothing waits on the script (web/site.js) to be read. */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--space-4);
}

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-size: var(--type-body-lg-size);
  line-height: var(--type-body-lg-line);
  font-optical-sizing: auto;
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }
p, ul, ol, dl, figure { margin: 0; }
p + p { margin-top: var(--space-3); }

h1, h2, h3 { margin: 0; text-wrap: balance; }
h1 {
  font-family: var(--font-serif);
  font-weight: var(--type-h1-weight);
  font-size: var(--type-h1-size);
  line-height: var(--type-h1-line);
  letter-spacing: var(--type-h1-tracking);
}
h2 {
  font-size: var(--type-card-title-size);
  line-height: var(--type-card-title-line);
  font-weight: var(--type-card-title-weight);
}
h3 {
  font-size: var(--type-quote-size);
  line-height: var(--type-quote-line);
  font-weight: var(--type-quote-weight);
}
strong { font-weight: 600; }
code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.88em; overflow-wrap: anywhere; }

/* Links: Forest, underlined, so a link never depends on colour alone (WCAG 1.4.1).
   Press and hover (apple-design-motion §1: "Respond on pointer-down, not on release"; DESIGN §5: "Feedback on touch, not
   on release"; `buttons.md › Best practices`: "Always include a press state for a custom button"). Every link dims the
   frame it is pressed (no fade in: the press is instant) and eases back on release; a link that stands as its own
   block (the nav, the footer, the brand, a "more" link) also presses in to --scale-press on the snappy spring. On a
   pointer, an underline thickens or sweeps in on hover, and the brand, which has no underline, dims a little: the
   highlight a small control on a clear ground gets (`pointing-devices.md › Standard pointers and effects`: "Use
   highlight for a small element that has a transparent background"; without it "people might think they're broken").
   web/site.js adds the touch listener Safari needs for :active.
   Apple's App Store badge is the one exception: it is shown as Apple draws it, never dimmed or moved. */
a {
  color: var(--c-link);
  text-decoration-line: underline;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.2em;
  transition: opacity var(--dur-fast) var(--ease-out-smooth), text-decoration-thickness var(--dur-fast) var(--ease-out-smooth);
}
a:active { opacity: 0.6; transition-duration: 0s; }
@media (hover: hover) {
  a:hover { text-decoration-thickness: 0.14em; }
  .brand:hover:not(:active) { opacity: 0.8; } /* the press still dims it to 0.6 */
}
.brand, .site-nav a, .site-footer__links a, .links a, .more a, .store__available a, .scene__control {
  transition:
    opacity var(--dur-fast) var(--ease-out-smooth),
    transform var(--spring-snappy-dur) var(--spring-snappy),
    text-decoration-thickness var(--dur-fast) var(--ease-out-smooth);
}
.more a { display: inline-block; }
:is(.brand, .site-nav a, .site-footer__links a, .links a, .more a, .store__available a):active {
  transform: scale(var(--scale-press));
  transition: opacity 0s, transform var(--spring-snappy-dur) var(--spring-snappy);
}
:focus-visible {
  outline: 3px solid var(--c-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

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

.skip {
  position: absolute;
  inset-inline-start: var(--gutter);
  top: var(--space-2);
  z-index: 10;
  padding: var(--space-2) var(--space-4);
  background: var(--c-control);
  color: var(--c-on-control);
  border-radius: var(--radius-full);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-300%);
}
.skip:focus { transform: none; }

.wrap {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--reading { max-width: calc(var(--reading-max) + 2 * var(--gutter)); }

/* ---------------------------------------------------------------- header and footer */
.site-header__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0 var(--space-4);
  padding-block: var(--space-2);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  color: var(--c-ink);
  text-decoration: none;
}
.brand__icon { width: 1.75rem; height: 1.75rem; border-radius: 22.37%; }
.wordmark {
  font-family: var(--font-serif);
  font-weight: var(--type-wordmark-weight);
  font-size: var(--type-wordmark-size);
  line-height: 1;
}
.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-4);
  list-style: none;
  padding: 0;
}
.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--c-ink);
  font-size: var(--type-body-size);
  font-weight: 600;
  text-decoration: none;
}
/* the nav's underline sweeps in from the leading edge on hover (transform only), and back out when the pointer leaves */
.site-nav a { position: relative; }
.site-nav a::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0.55rem;
  height: 2px;
  border-radius: var(--radius-full);
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--spring-snappy-dur) var(--spring-snappy);
}
@media (hover: hover) {
  .site-nav a:hover::after { transform: none; }
}
.site-nav a:focus-visible::after { transform: none; }

.site-footer {
  border-top: 1px solid var(--c-border);
  padding-block: var(--space-8) var(--space-10);
  color: var(--c-ink-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}
.site-footer__inner { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
.wordmark--footer { color: var(--c-ink); }
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-5);
  list-style: none;
  padding: 0;
}
.site-footer__links a { display: inline-flex; align-items: center; min-height: 2.75rem; }
/* Apple's credit line: legal copy, small and quiet at the foot of the page, in the footer's own secondary ink */
.site-footer__legal {
  max-width: 46em;
  margin-top: var(--space-2);
  font-size: var(--type-body-sm-size);
  line-height: var(--type-body-sm-line);
}

/* ---------------------------------------------------------------- sections */
.section { padding-block: var(--space-12) 0; }
.section--last { padding-bottom: var(--space-16); }
.section h2 { margin-bottom: var(--space-3); }
.lede {
  color: var(--c-ink-secondary);
  max-width: 38em;
  margin-bottom: var(--space-6);
}
.note {
  color: var(--c-ink-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  max-width: 44em;
  margin-top: var(--space-5);
}
.more { margin-top: var(--space-5); font-weight: 600; }
.card {
  background: var(--c-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-card);
}

/* ---------------------------------------------------------------- the hero: the page's one colour moment */
.hero { padding-block: var(--space-2) 0; }
.hero__field {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  padding: var(--space-8) var(--space-5) var(--space-4);
  background: var(--c-hero);
  color: var(--c-on-hero);
  border-radius: var(--radius-block);
  box-shadow: var(--shadow-block);
  overflow: hidden;
}
/* The ambient light: two soft pools of Cream, at most AMBIENT_MAX of it (web/tokens.mjs, where the hero's text is gated
   on the field lit that much), drifting across the field on 26 s and 34 s half-cycles: calm, far from the 0.2 Hz a
   vestibular trigger sits near (apple-design-motion §14), transform only. It moves only once the script is there to
   offer the hero's pause control (WCAG 2.2.2; `accessibility.md › Cognitive`), and never under Reduce Motion, Reduce
   Transparency (it is a translucent layer) or Increase Contrast. */
.hero__ambient {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.hero__ambient::before, .hero__ambient::after {
  content: "";
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--c-on-hero) 8%, transparent), transparent);
}
.hero__ambient::before { width: 80%; top: -30%; right: -20%; }
.hero__ambient::after { width: 60%; bottom: -30%; left: -5%; background: radial-gradient(closest-side, color-mix(in srgb, var(--c-on-hero) 5%, transparent), transparent); }
@media (prefers-reduced-motion: no-preference) {
  .js .hero__ambient::before { animation: ambient-a 26s var(--ease-in-out) infinite alternate; }
  .js .hero__ambient::after { animation: ambient-b 34s var(--ease-in-out) infinite alternate; }
}
@keyframes ambient-a { to { transform: translate(-22%, 18%) scale(1.12); } }
@keyframes ambient-b { to { transform: translate(30%, -14%) scale(0.9); } }
.hero :focus-visible { outline-color: var(--c-on-hero-focus); }
.eyebrow {
  color: var(--c-on-hero-secondary);
  font-size: var(--type-eyebrow-size);
  line-height: var(--type-eyebrow-line);
  font-weight: var(--type-eyebrow-weight);
  letter-spacing: var(--type-eyebrow-tracking);
  margin-bottom: var(--space-3);
}
.hero__title em { font-style: italic; }
.hero__lede {
  color: var(--c-on-hero-secondary);
  max-width: 32em;
  margin-top: var(--space-4);
}
.store { margin-top: var(--space-6); }
/* "Coming soon" is a status, not a control: plain text with a rule beside it, never a capsule that reads as a button
   (`buttons.md › Best practices`: people expect a button's shape to do something). */
.store__pill {
  padding-inline-start: var(--space-3);
  border-inline-start: 3px solid var(--c-on-hero);
  color: var(--c-on-hero);
  font-weight: 600;
}
/* Once the app is on the store: Apple's badge as Apple draws it, 40 px tall (Apple's least on screen) with a quarter of
   its height clear around it, never dimmed, moved or animated (Marketing Resources and Identity Guidelines › App Store
   badges: "Don't modify, angle, or animate the App Store badge"); the focus ring still shows. Until its file is in
   place, a plain link in Apple's words, in the hero's own ink. */
.store__badge {
  display: inline-block;
  margin-block: 0.625rem;
  line-height: 0;
  transition: none;
}
.store__badge:active { opacity: 1; }
.store__badge img { display: block; height: 2.5rem; width: auto; }
.store__available a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--c-on-hero);
  font-weight: 600;
}
.store__note {
  color: var(--c-on-hero-secondary);
  font-size: var(--type-body-sm-size);
  line-height: var(--type-body-sm-line);
  margin-top: var(--space-2);
}

/* ---------------------------------------------------------------- the hero's story (web/scene.mjs): the signature
   A pack on a pantry shelf, the scanner's frame closing on its barcode as the scan pulse reads it, the result rising with every
   flagged name ringed one by one, and the dial filling to the sample's real score: CL-03 becoming CL-04 (DESIGN §5.4),
   told in about four seconds, then at rest. The base styles below are the last frame. */
.scene {
  width: 100%;
  max-width: 28rem;
  justify-self: center;
  display: grid;
  gap: var(--space-2);
}
.scene__stage { display: grid; gap: var(--space-3); -webkit-tap-highlight-color: transparent; }
.scene__shelf { display: block; width: 100%; height: auto; overflow: visible; }
.scene__shelf .f-pack-sky { fill: var(--illo-pack-sky); }
.scene__shelf .f-pack-sky-deep { fill: var(--illo-pack-sky-deep); }
.scene__shelf .f-pack-plum { fill: var(--illo-pack-plum); }
.scene__shelf .f-pack-plum-deep { fill: var(--illo-pack-plum-deep); }
.scene__shelf .f-oat { fill: var(--illo-oat); }
.scene__shelf .f-oat-deep { fill: var(--illo-oat-deep); }
.scene__shelf .f-crust { fill: var(--illo-crust); }
.scene__shelf .f-berry { fill: var(--illo-berry); }
.scene__shelf .f-berry-deep { fill: var(--illo-berry-deep); }
.scene__shelf .f-tomato { fill: var(--illo-tomato); }
.scene__shelf .f-tomato-deep { fill: var(--illo-tomato-deep); }
.scene__shelf .f-leaf { fill: var(--illo-leaf); }
.scene__shelf .f-leaf-deep { fill: var(--illo-leaf-deep); }
.scene__shelf .f-white { fill: var(--illo-white); }
.scene__shelf .f-cream { fill: var(--illo-cream); }
.scene__shelf .f-metal { fill: var(--illo-metal); }
.scene__shelf .f-metal-deep { fill: var(--illo-metal-deep); }
.scene__shelf .f-hi { fill: var(--illo-hi); }
.scene__shelf .f-shade { fill: var(--illo-shade); }
.scene__shelf .f-ink { fill: var(--illo-ink); }
.scene__shelf .f-print { fill: var(--illo-print); }
.scene__shelf .f-print-head { fill: var(--illo-print-head); }
.scene__shelf .f-print-edge { fill: var(--illo-print-edge); }
.scene__shelf .f-ground { fill: var(--illo-ground); }
.scene__shelf .f-plank { fill: var(--c-hero-wash-alpha); }
.scene__shelf .f-plank-edge { fill: var(--c-hero-rule); }
/* the scanner, as the app draws it: Cream brackets that close onto the code, a soft sage ring pulsing out of it while it
   reads (no laser line: SCREENS CL-02), and a thin Cream ring once it locks. No zone colour: none of this is a score. */
.scene__shelf .s-frame { fill: none; stroke: var(--c-on-hero); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.scene__pulse { fill: none; stroke: var(--c-scan-ring); stroke-width: 2; opacity: 0; }
.scene__locked { fill: none; stroke: var(--c-on-hero); stroke-width: 1.4; }
.scene__frame, .scene__lock, .scene__piece, .scene__pulse, .scene__locked { transform-box: fill-box; transform-origin: center; }
.scene__lock { transform: scale(0.92); } /* closed onto the code */
.scene__others { opacity: 0.55; } /* the neighbours step back once the box is read: dim to focus */

.scene__result { display: grid; gap: var(--space-3); }
.scene__verdict { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }
.scene__product { flex: 1 1 9rem; min-width: 0; display: grid; justify-items: start; gap: var(--space-2); }
.scene__name { font-weight: 600; }
.scene__list {
  color: var(--c-on-hero-secondary);
  font-size: var(--type-body-size);
  line-height: 2;
}
.scene__lead { color: var(--c-on-hero); font-weight: 600; }
.scene__list .ring { color: var(--c-on-hero); --ring: var(--c-on-hero); }

/* the dial: the app's CleanScoreDial on a field (DESIGN §6.5 `.dial--on-hero`): a neutral track, the arc in the score's
   own zone colour from its first degree (the contract reading, D17 F-04), the 40 and 60 ticks in the field's ink, the
   numeral in Archivo, tabular and lining (DESIGN §3.3) */
.dial { position: relative; flex: none; width: 7.5rem; aspect-ratio: 1; }
.dial__ring { display: block; width: 100%; height: 100%; overflow: visible; }
.dial__track, .dial__arc { fill: none; stroke-width: 16; }
.dial__track { stroke: var(--c-dial-track); }
.dial__arc {
  stroke: var(--score-colour);
  stroke-linecap: round;
  stroke-dasharray: 100 200;
  stroke-dashoffset: var(--score-offset);
}
.dial__tick { stroke: var(--c-on-hero); stroke-width: 2; stroke-linecap: round; }
.dial__center {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  line-height: 1;
}
.dial__num {
  display: inline-block;
  font-family: "Archivo", var(--font-sans);
  font-weight: 800;
  font-size: 2.25rem;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--c-on-hero);
  min-width: 3ch; /* room for 100: the box never changes size as the count grows, so nothing shifts */
  text-align: center;
}
.dial__unit {
  margin-top: var(--space-1);
  color: var(--c-on-hero-secondary);
  font-size: var(--type-label-size);
  font-weight: 600;
}
/* the band pill on a field: the wash, the field's ink, the zone's dot (word and shape, not colour alone) */
.dial-band {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: 0.25em 0.85em;
  background: var(--c-hero-wash-alpha);
  border-radius: var(--radius-full);
  color: var(--c-on-hero);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  font-weight: 600;
}
.dial-band__dot { flex: none; width: 0.6em; height: 0.6em; border-radius: 50%; background: var(--score-colour); }

/* the caption and the hero's one control (pause, then play again): 44 pt, a press state on press (`buttons.md › Best
   practices`), hidden until the script that drives it is there (its space is kept, so nothing shifts) */
.scene__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 2.75rem;
}
.scene__bar figcaption {
  color: var(--c-on-hero-secondary);
  font-size: var(--type-body-sm-size);
  line-height: var(--type-body-sm-line);
}
.scene__control {
  position: relative;
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--c-hero-wash-alpha);
  color: var(--c-on-hero);
  cursor: pointer;
}
.scene__control::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--c-on-hero);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out-smooth);
}
@media (hover: hover) {
  .scene__control:hover::before { opacity: 0.12; }
}
.scene__control:active { transform: scale(var(--scale-share-press)); transition: transform var(--spring-snappy-dur) var(--spring-snappy); }
.scene__control:active::before { opacity: 0.22; transition-duration: 0s; }
.scene:not([data-ready]) .scene__control { visibility: hidden; }
@media (prefers-reduced-motion: reduce) { .scene__control { display: none; } } /* nothing moves, so nothing to pause */
.scene__icon { position: relative; width: 1.25rem; height: 1.25rem; fill: currentColor; }
.scene__control[data-state="pause"] .scene__icon--play,
.scene__control[data-state="play"] .scene__icon--pause { display: none; }

/* The story's timeline (CSS animations, so it starts with the first paint and needs no script; web/site.js only counts
   the numeral with the arc, skips and replays). The scan pulse is the app's (--dur-scan-pulse, --scale-ring-from to
   --scale-ring-to, fading from --opacity-pulse-start), once. Each step ends on the last frame above and fills both ways, so a step
   that has played stays reachable to the script (getAnimations) for a skip or a replay. Tokens: the packs are set
   down as ON-01's (--offset-ob1-settle-y, 45 ms apart, the default spring); the frame closes on the snappy spring; the
   result rises on the sheet spring (--offset-card-rise-y); the rings come 80 ms apart, each in about 320 ms (CL-04's
   rhythm); the arc fills on --spring-dial-fill, critically damped so it never passes the score, and the landing beat
   (the band pill and the numeral's one calm pulse, a score under 60: no bounce, no glow) shares one frame (DESIGN §5.2). */
@media (prefers-reduced-motion: no-preference) {
  .scene {
    --t-set: 60ms;
    --t-frame: 520ms;
    --t-pulse: 640ms;
    --t-lock: 1340ms;
    --t-result: 1460ms;
    --t-rings: 1700ms;
    --t-fill: 2380ms;
    --t-land: calc(var(--t-fill) + var(--land-after)); /* web/scene.mjs › landingAfter */
  }
  .scene__piece { animation: scene-set var(--spring-default-dur) var(--spring-default) calc(var(--t-set) + var(--i, 0) * var(--dur-ob1-art-stagger)) both; }
  .scene__frame { animation: scene-frame var(--spring-snappy-dur) var(--spring-snappy) var(--t-frame) both; }
  .scene__pulse { animation: scene-pulse-ring var(--dur-scan-pulse) var(--ease-out-smooth) var(--t-pulse) both; }
  .scene__lock { animation: scene-lock var(--spring-snappy-dur) var(--spring-snappy) var(--t-lock) both; }
  .scene__locked { animation: scene-frame var(--spring-snappy-dur) var(--spring-snappy) var(--t-lock) both; }
  .scene__others { animation: scene-dim var(--dur-medium) var(--ease-out-smooth) var(--t-lock) both; }
  .scene__result { animation: scene-rise var(--spring-sheet-dur) var(--spring-sheet) var(--t-result) both; }
  .scene__list .ring::after { animation: scene-ring var(--spring-snappy-dur) var(--spring-snappy) calc(var(--t-rings) + var(--i, 0) * var(--dur-row-stagger)) both; }
  .dial__arc {
    animation:
      scene-fill var(--spring-dial-fill-dur) var(--spring-dial-fill) var(--t-fill) both,
      scene-appear 1ms linear var(--t-fill) both;
  }
  .dial__num {
    animation:
      scene-fade var(--dur-fast) var(--ease-out-smooth) var(--t-fill) both,
      scene-pulse var(--dur-pulse) var(--ease-out-smooth) var(--t-land) both;
  }
  .dial-band { animation: scene-land var(--spring-snappy-dur) var(--spring-snappy) var(--t-land) both; }
}
[data-i="1"] { --i: 1; }
[data-i="2"] { --i: 2; }
[data-i="3"] { --i: 3; }
[data-i="4"] { --i: 4; }
[data-i="5"] { --i: 5; }
[data-i="6"] { --i: 6; }
[data-i="7"] { --i: 7; }
@keyframes scene-set { from { opacity: 0; transform: translateY(var(--offset-ob1-settle-y)); } }
@keyframes scene-frame { from { opacity: 0; transform: scale(1.25); } }
/* the ring is unseen until its start (the step fills both ways, so its first frame shows through the delay) */
@keyframes scene-pulse-ring {
  from { opacity: 0; transform: scale(var(--scale-ring-from)); }
  1% { opacity: var(--opacity-pulse-start); transform: scale(var(--scale-ring-from)); }
  to { opacity: 0; transform: scale(var(--scale-ring-to)); }
}
@keyframes scene-lock { from { transform: scale(1); } }
@keyframes scene-dim { from { opacity: 1; } }
@keyframes scene-rise { from { opacity: 0; transform: translateY(var(--offset-card-rise-y)); } }
@keyframes scene-ring { from { opacity: 0; transform: scale(0.86); } }
@keyframes scene-fill { from { stroke-dashoffset: 100; } }
@keyframes scene-appear { from, 99% { opacity: 0; } to { opacity: 1; } }
@keyframes scene-fade { from { opacity: 0; } }
@keyframes scene-pulse { 50% { transform: scale(var(--scale-pulse)); } }
@keyframes scene-land { from { opacity: 0; transform: translateY(0.25rem); } }

/* ---------------------------------------------------------------- the generic phone (D20: no buttons, no camera,
   no island, no logo; a plain graphite slab with an even bezel, standing in 3D perspective, turned about 15 degrees,
   with visible edge depth and a soft two-layer shadow). Apple's own device art may not be tilted or shadowed, so this
   is never an iPhone (Apple's Marketing Resources and Identity Guidelines › Apple Product Images).
   The device holds the perspective and drifts with the scroll (parallax, 1.5 rem either way: CSS scroll-driven where
   the browser has it, web/site.js elsewhere); the phone turns, and on a desktop pointer it tilts toward the pointer and
   lifts (`pointing-devices.md › Pointer shape and content effects`: "The lift effect combines a subtle parallax with
   the appearance of elevation"), then springs back, critically damped, from wherever it is (web/site.js). */
.device {
  --turn: 0deg;
  --lean: 3deg;
  --drift: 1.5rem;
  width: var(--phone-width);
  max-width: 100%;
  margin-inline: auto;
  perspective: 75rem;
}
.device--right { --turn: 15deg; }
.device--left { --turn: -15deg; }
.device--front { --turn: -5deg; }
.phone {
  position: relative;
  padding: 3.2%;
  background: var(--c-phone);
  border-radius: 16.5% / 7.6%;
  box-shadow: inset 0 0 0 1px var(--c-phone-rim);
  transform-style: preserve-3d;
  transform: rotateY(calc(var(--turn) + var(--tilt-y, 0deg))) rotateX(calc(var(--lean) + var(--tilt-x, 0deg))) scale(var(--lift, 1));
}
/* the slab's back, set behind the face: its edge shows on the near side as the phone turns, and it carries the shadow */
.phone::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--c-phone-edge);
  box-shadow: var(--shadow-device);
  transform: translateZ(-0.875rem);
}
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    :root:not(.scroll-js) .device {
      animation: device-drift linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
  }
}
@keyframes device-drift {
  from { transform: translateY(var(--drift)); }
  to { transform: translateY(calc(-1 * var(--drift))); }
}
.phone__screen {
  width: 100%;
  border-radius: 13.7% / 6.3%;
  background: var(--c-surface);
}

/* ---------------------------------------------------------------- what afs flags: the ringed label (the signature:
   CL-04's ringed ingredients and the app icon's circled line) */
.flags { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
.label-card {
  background: var(--c-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-card);
}
.label-card__title {
  color: var(--c-ink-secondary);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  font-weight: var(--type-label-weight);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
  margin-bottom: var(--space-3);
}
.label-card__list { line-height: 2.1; }
.label-card__lead { font-weight: 600; }
/* A flagged name, ringed in pen (CL-04's label, the app icon's circled line). The ring is its own layer, so it can be
   drawn in (pop in) with transform and opacity while the word stays put; a name too long for its line wraps inside
   its ring at large text sizes. */
.ring-group { white-space: nowrap; } /* a ringed name and its comma stay on one line */
.ring {
  position: relative;
  display: inline-block;
  max-width: calc(100% - 0.6em); /* room for the comma that keeps to it */
  padding: 0 0.45em;
  background: none;
  color: inherit;
  line-height: 1.6;
  white-space: normal;
}
/* half the line's height: a capsule on one line, a rounded rectangle when a long name wraps */
.ring::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--ring, var(--c-control));
  border-radius: 0.8em;
  pointer-events: none;
}
.label-card__note {
  color: var(--c-ink-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  margin-top: var(--space-3);
}
.groups { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
.group {
  background: var(--c-surface);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  box-shadow: var(--shadow-card);
}
.group dt { font-weight: 600; }
.group dd {
  margin: var(--space-1) 0 0;
  color: var(--c-ink-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

/* ---------------------------------------------------------------- how it works: a real sequence, so it is numbered */
.steps {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-12);
  list-style: none;
  padding: 0;
  margin-top: var(--space-6);
}
.step { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
.step__n {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-bottom: var(--space-3);
  background: var(--c-sunken);
  border-radius: var(--radius-full);
  font-weight: 600;
}
.step h3 { margin-bottom: var(--space-2); }
.step__text { position: relative; }
.step__text::after { display: none; }
.step__text p:not(.step__n) { color: var(--c-ink-secondary); }

/* ---------------------------------------------------------------- the sections coming in
   Each piece marked data-reveal fades and rises by --offset-card-rise-y as it scrolls into view, in its data-i order:
   on a CSS view() timeline where the browser has one (the scroll is the clock, so it is never late and never replays
   behind the reader), on the sheet spring's curve; elsewhere web/site.js marks it .is-in through an IntersectionObserver
   and it springs in, 80 ms apart (--dur-row-stagger). The steps draw in order on a wide window, each line to the next
   step after its step, and the sample label's flagged names pop in one by one. Nothing is hidden without the script and
   a timeline to bring it back, and nothing moves under Reduce Motion (`accessibility.md › Cognitive`: "Replacing
   transitions in x-, y-, and z-axes with fades": here, no transition at all). */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    :root:not(.scroll-js) [data-reveal] {
      animation: reveal-rise both;
      animation-timing-function: var(--spring-sheet);
      animation-timeline: view();
      animation-range: entry calc(var(--i, 0) * 6%) cover calc(20% + var(--i, 0) * 6%);
    }
    :root:not(.scroll-js) .label-card { view-timeline-name: --label; }
    :root:not(.scroll-js) .label-card .ring::after {
      animation: ring-pop both;
      animation-timing-function: var(--spring-snappy);
      animation-timeline: --label;
      animation-range: entry calc(30% + var(--i, 0) * 8%) cover calc(30% + var(--i, 0) * 6%);
    }
    :root:not(.scroll-js) .step { view-timeline-name: --step; }
    :root:not(.scroll-js) .step__text::after {
      animation: step-line both;
      animation-timing-function: var(--spring-draw);
      animation-timeline: --step;
      animation-range: entry calc(30% + var(--i, 0) * 6%) cover calc(36% + var(--i, 0) * 6%);
    }
  }
  /* the transition rides only the way in: hiding what is off screen is instant */
  .scroll-js [data-reveal].is-in {
    transition:
      opacity var(--spring-sheet-dur) var(--ease-out-smooth),
      transform var(--spring-sheet-dur) var(--spring-sheet);
    transition-delay: calc(var(--i, 0) * var(--dur-row-stagger));
  }
  .scroll-js [data-reveal]:not(.is-in) { opacity: 0; transform: translateY(var(--offset-card-rise-y)); }
  .scroll-js .label-card.is-in .ring::after {
    transition: opacity var(--spring-snappy-dur) var(--ease-out-smooth), transform var(--spring-snappy-dur) var(--spring-snappy);
    transition-delay: calc(var(--dur-medium) + var(--i, 0) * var(--dur-row-stagger));
  }
  .scroll-js .label-card:not(.is-in) .ring::after { opacity: 0; transform: scale(0.86); }
  .scroll-js .step.is-in .step__text::after {
    transition: transform var(--spring-draw-dur) var(--spring-draw);
    transition-delay: calc(var(--dur-medium) + var(--i, 0) * var(--dur-row-stagger));
  }
  .scroll-js .step:not(.is-in) .step__text::after { transform: scaleX(0); }
}
@keyframes reveal-rise { from { opacity: 0; transform: translateY(var(--offset-card-rise-y)); } to { opacity: 1; transform: none; } }
@keyframes ring-pop { from { opacity: 0; transform: scale(0.86); } to { opacity: 1; transform: none; } }
@keyframes step-line { from { transform: scaleX(0); } to { transform: none; } }

/* ---------------------------------------------------------------- family, plans, privacy, notes */
.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-8); align-items: center; }
.split__text p { color: var(--c-ink-secondary); }
.split__text h2 + p { margin-top: var(--space-3); }
.plans { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); margin-top: var(--space-6); }
.plan h3 { margin-bottom: var(--space-3); }
.ticks, .promise {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}
.promise { gap: var(--space-3); margin-top: var(--space-5); max-width: 46em; }
.ticks li, .promise li { position: relative; padding-inline-start: 1.6em; }
.ticks li::before, .promise li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0.25em;
  top: 0.5em;
  width: 0.75em;
  height: 0.4em;
  border-inline-start: 2px solid var(--c-control);
  border-bottom: 2px solid var(--c-control);
  transform: rotate(-45deg);
}
.notes { margin-top: var(--space-5); max-width: 46em; }

/* ---------------------------------------------------------------- support and the 404 page */
.page-head { padding-block: var(--space-10) 0; }
.page-head.section--last { padding-bottom: var(--space-16); }
.page-head .lede { margin-top: var(--space-3); }
.page-head p + p { margin-top: var(--space-4); }
/* FA-04's web page: the invite's code in large type, in its white card (SCREENS FA-04 `web`) */
.join-card { margin-top: var(--space-6); display: grid; gap: var(--space-3); }
.join-code { font-size: 2rem; letter-spacing: 0.08em; font-variant-numeric: tabular-nums; }
.contact { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); margin-bottom: var(--space-10); }
.contact__address {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  font-weight: 600;
}
.contact__address a, .address { overflow-wrap: anywhere; }
.contact p + p { margin-top: 0; }
.chip {
  display: inline-flex;
  align-items: center;
  padding: 0.25em 0.8em;
  background: var(--c-control);
  color: var(--c-on-control);
  border-radius: var(--radius-full);
  font-size: var(--type-chip-size);
  line-height: var(--type-chip-line);
  font-weight: var(--type-chip-weight);
}
.faq { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); margin: var(--space-5) 0 var(--space-10); }
.faq__item h3 { margin-bottom: var(--space-2); }
.faq__item p { color: var(--c-ink-secondary); }
.links { list-style: none; padding: 0; margin-top: var(--space-3); }
.links a { display: inline-flex; align-items: center; min-height: 2.75rem; }

/* ---------------------------------------------------------------- the legal drafts */
.legal { padding-block: var(--space-10) var(--space-16); }
.legal h1 { margin-bottom: var(--space-5); }
.legal h2 { margin-top: var(--space-10); margin-bottom: var(--space-3); }
.legal h3 { margin-top: var(--space-6); margin-bottom: var(--space-2); }
.legal p, .legal ul { margin-top: var(--space-3); }
.legal ul { padding-inline-start: 1.25em; }
.legal li + li { margin-top: var(--space-2); }
.doc-meta {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2);
  margin-block: var(--space-5);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}
.doc-meta div { display: grid; grid-template-columns: minmax(0, 1fr); }
.doc-meta dt { font-weight: 600; }
.doc-meta dd { margin: 0; }
.draft-banner, .draft-note--block {
  background: var(--c-sunken);
  border-inline-start: 4px solid var(--c-control);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}
.draft-banner { margin-block: var(--space-4) var(--space-6); }
.legal .draft-banner p, .legal .draft-note--block p { margin-top: 0; }
.draft-note--block { margin-top: var(--space-4); }
.draft-banner__label {
  display: inline-flex;
  margin-bottom: var(--space-2);
  padding: 0.2em 0.8em;
  background: var(--c-control);
  color: var(--c-on-control);
  border-radius: var(--radius-full);
  font-size: var(--type-chip-size);
  line-height: var(--type-chip-line);
  font-weight: var(--type-chip-weight);
}
.legal .draft-banner p.draft-banner__label { margin-bottom: var(--space-2); }
.draft-note--block .draft-note__label {
  display: inline-flex;
  margin-inline-end: var(--space-1);
  padding: 0.1em 0.6em;
  background: var(--c-control);
  color: var(--c-on-control);
  border-radius: var(--radius-full);
  font-size: var(--type-chip-size);
  line-height: var(--type-chip-line);
  font-weight: var(--type-chip-weight);
}
.draft-note--inline {
  background: var(--c-sunken);
  border-bottom: 2px solid var(--c-control);
  padding: 0.05em 0.2em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.draft-note--inline .draft-note__label { font-weight: 600; }
.placeholder {
  background: var(--c-sunken);
  border-bottom: 2px dotted var(--c-control);
  padding: 0 0.15em;
  overflow-wrap: anywhere;
}
.toc {
  margin-block: var(--space-6);
  padding: var(--space-4) var(--space-5);
  background: var(--c-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.toc__title {
  color: var(--c-ink-secondary);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  font-weight: var(--type-label-weight);
  letter-spacing: var(--type-label-tracking);
  text-transform: uppercase;
}
.legal .toc ul { list-style: none; padding: 0; margin-top: var(--space-2); }
.legal .toc li { margin: 0; padding-block: var(--space-1-5); break-inside: avoid; }
.table { margin-top: var(--space-4); }
table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}
th, td {
  padding: var(--space-3) var(--space-3) var(--space-3) 0;
  border-bottom: 1px solid var(--c-border);
  text-align: start;
  vertical-align: top;
}
thead th { border-bottom: 2px solid var(--c-border-strong); font-weight: 600; }

/* Phone width: each table row becomes a stack, its column names written in, so nothing scrolls sideways. */
@media (max-width: 39.99em) {
  .table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .table tr { display: block; padding-block: var(--space-3); border-bottom: 1px solid var(--c-border); }
  .table td { display: block; padding: var(--space-1) 0; border: 0; }
  .table td::before {
    content: attr(data-label);
    display: block;
    color: var(--c-ink-secondary);
    font-size: var(--type-label-size);
    line-height: var(--type-label-line);
    font-weight: var(--type-label-weight);
    letter-spacing: var(--type-label-tracking);
    text-transform: uppercase;
  }
}

/* ---------------------------------------------------------------- wider windows */
@media (min-width: 40em) {
  .groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .doc-meta div { grid-template-columns: 9em minmax(0, 1fr); gap: var(--space-3); }
  .legal .toc ul { columns: 2; column-gap: var(--space-8); }
}

@media (min-width: 60em) {
  :root { --gutter: var(--space-8); }
  .section { padding-top: var(--space-20); }
  .section--last { padding-bottom: var(--space-24); }
  .hero__field {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: var(--space-12);
    padding: var(--space-12) var(--space-16) var(--space-8);
  }
  .dial { width: 8.5rem; }
  .dial__num { font-size: 2.625rem; }
  .hero__title {
    font-size: var(--type-display-size);
    line-height: var(--type-display-line);
  }
  .flags { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; gap: var(--space-8); }
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-10); }
  .step { align-content: start; }
  /* the line from each step's number to the next step's: the sequence drawn (web/styles.css › the sections coming in) */
  .step:not(:last-child) .step__text::after {
    content: "";
    display: block;
    position: absolute;
    top: calc(1.125rem - 1px);
    left: calc(2.25rem + var(--space-3));
    right: calc(var(--space-3) - var(--space-10));
    height: 2px;
    border-radius: var(--radius-full);
    background: var(--c-border-strong);
    transform-origin: 0 50%;
  }
  .step__figure { order: -1; }
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-16); }
  .split__figure { order: -1; }
}

/* Reduced motion: no smooth scroll, no transition (apple-design-motion §14; accessibility.md › Motion). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* Reduce Transparency: no translucent layer; the washes turn solid (`dark-mode.md › Best practices`: test with Increase
   Contrast and Reduce Transparency, separately and together). */
@media (prefers-reduced-transparency: reduce) {
  .hero__ambient { display: none; }
  .dial-band, .scene__control { background: var(--c-hero-wash); }
}

/* Increase Contrast: the colour tokens already change; links and rings get heavier too, and the field stays flat. */
@media (prefers-contrast: more) {
  a { text-decoration-thickness: 0.14em; }
  .ring::after { border-width: 3px; }
  .hero__ambient { display: none; }
  .card, .group, .label-card, .toc { box-shadow: none; border: 1px solid var(--c-border-strong); }
}

/* the hero's sample (web/scene.mjs) */
.scene { --score-offset: 64; --score-colour: var(--c-score-red); --land-after: 538ms; }
