/* graphnotes.app. Tokens from the GraphNotes design system (docs/design-system/tokens.json, version 1). */

:root {
  color-scheme: light dark;
  --paper: #fbfaf7;
  --paper-raised: #ffffff;
  --paper-sunken: #f3f1ec;
  --rule: #e2ded5;
  --ink: #1c1b19;
  --ink-muted: #6b665c;
  --ink-faint: #9b968b;
  --temporal: #8f5f00;
  --temporal-soft: #fcf0c8;
  --on-temporal: #ffffff;
  --semantic: #0f766e;
  --semantic-soft: #dcf5f1;
  --selection: #1c1b191a;
  --danger: #b42318;
  --grid-dot: #cfcbc3;
  --sticky-yellow: #ffed9e;
  --shadow-card: 0 2px 8px #00000012;
  --shadow-lift: 0 2px 20px #00000029;
  --shadow-chrome: 0 3px 16px #0000001a;
  --shadow-device: 0 40px 80px -30px #3a2f1a59, 0 18px 36px -18px #00000040;
  --focus-ring: 0 0 0 2px var(--paper), 0 0 0 4px var(--temporal);
  --chrome-fill: #fbfaf7c7;
  --bezel: #1d1d1f;
  --bezel-edge: #3a3a3c;

  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px;
  --space-6: 24px; --space-8: 32px; --space-12: 48px;
  --radius-xs: 6px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 14px; --radius-full: 9999px;

  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --font-serif: ui-serif, "New York", "Iowan Old Style", Georgia, serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;

  --measure: 760px;
  --page: 1180px;
  --gutter: clamp(16px, 5vw, 48px);

  /* Motion */
  --ease-in-out: cubic-bezier(0.42, 0, 0.58, 1);   /* SwiftUI UnitCurve.easeInOut: the mark and the scroll settle */
  --ease-out: cubic-bezier(0, 0, 0.58, 1);         /* Core Animation easeOut: opacity and indicators */
  /* A critically damped spring (SwiftUI spring with bounce 0) as a cubic Bézier, within 0.023 of the
     curve. Not linear(): released iOS Safari runs a linear() easing with points on the main thread,
     off Core Animation, so every spring would stall with the page. site.js also reads --ease-spring
     as the sign that this stylesheet (v2) is the one loaded. */
  --ease-spring: cubic-bezier(0.29, 0.5, 0.04, 1);
  --dur-press: 90ms;
  --dur-indicator: 200ms;
  --dur-calm: 300ms;     /* Reduce Motion cross-fades */
  --dur-release: 320ms;
  --dur-control: 450ms;
  --dur-fade: 500ms;
  --dur-move: 900ms;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #151413;
    --paper-raised: #1f1e1c;
    --paper-sunken: #1a1917;
    --rule: #353330;
    --ink: #ecebe6;
    --ink-muted: #a8a49b;
    --ink-faint: #6e6a62;
    --temporal: #f5b82e;
    --temporal-soft: #3b2d06;
    --on-temporal: #151413;
    --semantic: #34d3bf;
    --semantic-soft: #0b2e2a;
    --selection: #ecebe61a;
    --danger: #f47c6c;
    --grid-dot: #2e2c29;
    --shadow-card: 0 2px 8px #00000066;
    --shadow-lift: 0 2px 20px #000000a6;
    --shadow-chrome: 0 3px 16px #00000099;
    --shadow-device: 0 40px 90px -30px #000000cc, 0 18px 36px -18px #000000b3;
    --chrome-fill: #151413c7;
    --bezel: #0b0b0c;
    --bezel-edge: #3a3a3c;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--temporal); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-xs); }
::selection { background: var(--temporal-soft); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: var(--space-4); top: -100px; z-index: 100; background: var(--paper-raised); color: var(--ink); padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm); box-shadow: var(--shadow-chrome); }
.skip:focus { top: var(--space-4); }

.wrap { width: 100%; max-width: calc(var(--page) + 2 * var(--gutter)); margin: 0 auto; padding: 0 var(--gutter); }
.narrow { max-width: calc(var(--measure) + 2 * var(--gutter)); }

/* Navigation: a glass bar, like the app's chrome. */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: var(--chrome-fill);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 0.5px solid var(--rule);
}
@media (prefers-reduced-transparency: reduce) { .nav { background: var(--paper-raised); -webkit-backdrop-filter: none; backdrop-filter: none; } }
.nav .wrap { display: flex; align-items: center; gap: var(--space-6); height: 56px; }
.lockup { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--ink); text-decoration: none; font-weight: 700; font-size: 1.1875rem; letter-spacing: -0.01em; }
.lockup svg { width: 1.1875rem; height: 1.1875rem; transform: translateY(0.12em); flex: none; }
.lockup:hover { text-decoration: none; }
.nav-links { display: flex; gap: var(--space-6); margin-left: auto; align-items: center; }
.nav-links a { color: var(--ink); text-decoration: none; font-size: 0.875rem; opacity: 0.82; }
.nav-links a:hover { opacity: 1; }
.nav-links .btn { opacity: 1; }
@media (max-width: 720px) { .nav-links a:not(.btn) { display: none; } }

/* Buttons (design-system Button: capsule, 44 pt, one prominent per surface). */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 44px; padding: 0 var(--space-5);
  border-radius: var(--radius-full); border: 0;
  font: 600 1.0625rem/1 var(--font-sans);
  text-decoration: none; cursor: pointer;
  background: var(--paper-sunken); color: var(--temporal);
  transition: filter 160ms var(--ease-out);
}
.btn:hover { text-decoration: none; filter: brightness(0.97); }
.btn-prominent { background: var(--temporal); color: var(--on-temporal); }
.btn-small { min-height: 32px; padding: 0 var(--space-4); font-size: 0.875rem; }
.btn-link { background: none; color: var(--temporal); padding: 0 var(--space-2); }

/* Type */
.eyebrow { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 0.875rem; font-weight: 600; letter-spacing: 0.02em; color: var(--temporal); margin: 0 0 var(--space-4); }
.eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
h1, h2, h3 { margin: 0; letter-spacing: -0.022em; }
.display { font-size: clamp(2.5rem, 6.2vw, 4.75rem); line-height: 1.02; font-weight: 700; letter-spacing: -0.035em; }
.headline { font-size: clamp(2rem, 4.4vw, 3.5rem); line-height: 1.06; font-weight: 700; letter-spacing: -0.03em; }
.title { font-size: clamp(1.375rem, 2.2vw, 1.75rem); line-height: 1.2; font-weight: 700; }
.lede { font-size: clamp(1.1875rem, 1.9vw, 1.5rem); line-height: 1.42; color: var(--ink-muted); margin: var(--space-5) 0 0; max-width: 40em; letter-spacing: -0.01em; }
.lede strong { color: var(--ink); font-weight: 600; }
.muted { color: var(--ink-muted); }
.fine { font-size: 0.8125rem; line-height: 1.4; color: var(--ink-muted); }
.center { text-align: center; }
.center .lede { margin-left: auto; margin-right: auto; }

/* Hero */
/* overflow: clip paints like hidden but, unlike hidden, does not make .hero a scroll container,
   which would freeze the iPad's view() timeline (Motion, M3). hidden stays as the fallback. */
.hero { position: relative; padding: clamp(28px, 4.5vw, 80px) 0 0; overflow: hidden; overflow: clip; }
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(var(--grid-dot) 1.1px, transparent 1.4px);
  background-size: 24px 24px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 55%, transparent 92%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 55%, transparent 92%);
}
.hero .display { max-width: 15em; margin: 0 auto; }
.hero .display .soft { color: var(--ink-muted); }
.hero-cta { display: flex; gap: var(--space-3); justify-content: center; align-items: center; flex-wrap: wrap; margin-top: var(--space-8); }
.hero-meta { margin-top: var(--space-4); }
.hero-device { margin: clamp(48px, 7vw, 88px) auto 0; max-width: 1180px; }

/* The iPad: a drawn bezel around a screenshot. */
.ipad {
  position: relative;
  border-radius: clamp(18px, 3vw, 38px);
  padding: clamp(7px, 1.15vw, 15px);
  background: var(--bezel);
  box-shadow: inset 0 0 0 1px var(--bezel-edge), var(--shadow-device);
}
.ipad picture, .ipad img { border-radius: clamp(11px, 1.9vw, 24px); overflow: hidden; }
.ipad img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--paper-sunken); }
.ipad::after { /* camera */
  content: ""; position: absolute; top: 50%; left: calc(clamp(7px, 1.15vw, 15px) / 2 - 2px); width: 4px; height: 4px; border-radius: 50%; background: #2c2c2e; transform: translateY(-50%);
}

/* Sections */
section { position: relative; }
.section { padding: clamp(88px, 12vw, 168px) 0 0; }
.section-head { max-width: 48rem; }
.section-head.center { margin: 0 auto; }
.statement { font-size: clamp(1.5rem, 3.1vw, 2.5rem); line-height: 1.22; font-weight: 600; letter-spacing: -0.025em; max-width: 30em; margin: 0 auto; text-align: center; }
.statement .muted { color: var(--ink-faint); }

.split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
.split.flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.split.flip > :first-child { order: 2; }
@media (max-width: 900px) { .split, .split.flip { grid-template-columns: 1fr; } .split.flip > :first-child { order: 0; } }
.split .lede { font-size: clamp(1.0625rem, 1.5vw, 1.25rem); }
.figure-wide { margin-top: clamp(40px, 6vw, 72px); }

.points { list-style: none; padding: 0; margin: var(--space-8) 0 0; display: grid; gap: var(--space-5); }
.points li { display: grid; grid-template-columns: 28px 1fr; gap: var(--space-3); align-items: start; }
.points li svg { width: 22px; height: 22px; margin-top: 2px; color: var(--temporal); }
.points b { display: block; font-weight: 600; }
.points span { color: var(--ink-muted); }

/* Ink, everywhere it belongs: detail crops from the app. */
.ink-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(14px, 2vw, 24px); margin-top: clamp(40px, 6vw, 64px); }
@media (max-width: 900px) { .ink-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .ink-grid { grid-template-columns: 1fr; } }
.tile { background: var(--paper-raised); border: 1px solid var(--rule); border-radius: 22px; overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--shadow-card); }
.tile .crop { background: var(--paper-sunken); border-bottom: 1px solid var(--rule); aspect-ratio: 4 / 3; overflow: hidden; }
.tile .crop img { width: 100%; height: 100%; object-fit: cover; }
.tile .crop.top img { object-position: top left; }
.tile-body { padding: var(--space-5) var(--space-6) var(--space-6); }
.tile h3 { font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.01em; }
.tile p { margin: var(--space-2) 0 0; color: var(--ink-muted); font-size: 0.9375rem; line-height: 1.45; }

.callout { margin-top: clamp(32px, 4vw, 48px); display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-5) var(--space-6); border-radius: 18px; background: var(--paper-sunken); border: 1px solid var(--rule); }
.callout svg { flex: none; width: 24px; height: 24px; color: var(--ink); margin-top: 2px; }
.callout p { margin: 0; color: var(--ink-muted); }
.callout b { color: var(--ink); font-weight: 600; }

/* Feature rows with a screenshot */
.feature { padding-top: clamp(64px, 9vw, 120px); }
.feature h3 { font-size: clamp(1.625rem, 3vw, 2.375rem); line-height: 1.1; font-weight: 700; letter-spacing: -0.028em; }

/* Audiences: a segmented control (design-system tabs), panels below. */
.audiences { margin-top: clamp(32px, 4vw, 48px); }
.segmented { display: inline-flex; padding: 3px; gap: 2px; border-radius: var(--radius-full); background: var(--paper-sunken); border: 1px solid var(--rule); margin: 0 auto; }
.segmented button { appearance: none; border: 0; background: none; color: var(--ink); font: 600 0.9375rem/1 var(--font-sans); min-height: 40px; padding: 0 clamp(14px, 2.4vw, 26px); border-radius: var(--radius-full); cursor: pointer; }
.segmented button[aria-selected="true"] { background: var(--paper-raised); box-shadow: var(--shadow-card); }
.segmented-row { display: flex; justify-content: center; }
.panel { margin-top: clamp(32px, 4vw, 48px); }
.js .panel[hidden] { display: none; }
.panel-grid { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: clamp(28px, 4vw, 56px); align-items: center; }
@media (max-width: 900px) { .panel-grid { grid-template-columns: 1fr; } }
.panel h3 { font-size: clamp(1.5rem, 2.6vw, 2rem); line-height: 1.12; font-weight: 700; letter-spacing: -0.025em; }
.panel .points { margin-top: var(--space-6); }
.no-js .panel + .panel { margin-top: clamp(64px, 8vw, 96px); }

/* Trust band */
.trust { margin-top: clamp(88px, 12vw, 168px); background: var(--paper-sunken); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: clamp(64px, 9vw, 112px) 0; }
.facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); margin-top: clamp(32px, 5vw, 56px); }
@media (max-width: 900px) { .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .facts { grid-template-columns: 1fr; } }
.fact { background: var(--paper-raised); border: 1px solid var(--rule); border-radius: 18px; padding: var(--space-5) var(--space-5) var(--space-6); }
.fact svg { width: 26px; height: 26px; color: var(--ink); }
.fact b { display: block; margin-top: var(--space-3); font-weight: 600; }
.fact span { display: block; margin-top: var(--space-1); color: var(--ink-muted); font-size: 0.9375rem; line-height: 1.45; }

/* Founder note: a quotation, so the one serif. */
.founder { padding: clamp(88px, 12vw, 160px) 0 0; }
.founder blockquote { margin: 0 auto; max-width: 36em; text-align: center; }
.founder blockquote p { font-family: var(--font-serif); font-style: italic; font-size: clamp(1.5rem, 3vw, 2.25rem); line-height: 1.3; letter-spacing: -0.01em; margin: 0; }
.founder figcaption { margin-top: var(--space-6); text-align: center; color: var(--ink-muted); font-size: 0.9375rem; }
.founder figcaption b { color: var(--ink); font-weight: 600; }

/* FAQ */
.faq { margin-top: clamp(32px, 4vw, 48px); border-top: 1px solid var(--rule); }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-5) 0; font-weight: 600; font-size: 1.125rem; letter-spacing: -0.01em; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; flex: none; width: 10px; height: 10px; border-right: 2px solid var(--ink-muted); border-bottom: 2px solid var(--ink-muted); transform: rotate(45deg) translateY(-3px); }
.faq details[open] summary::after { transform: rotate(-135deg) translateY(-1px); }
.faq .answer { padding: 0 0 var(--space-6); color: var(--ink-muted); max-width: 46em; }
.faq .answer p { margin: 0 0 var(--space-3); }

/* Waitlist */
.join { padding: clamp(88px, 12vw, 160px) 0 clamp(88px, 12vw, 140px); }
.join-card { margin: clamp(32px, 4vw, 48px) auto 0; max-width: 560px; background: var(--paper-raised); border: 1px solid var(--rule); border-radius: 26px; padding: clamp(24px, 4vw, 40px); box-shadow: var(--shadow-card); text-align: left; }
.field { display: grid; gap: var(--space-2); margin-bottom: var(--space-5); }
.field label { font-weight: 600; font-size: 0.9375rem; }
.field input, .field select {
  font: 400 1.0625rem/1.3 var(--font-sans); color: var(--ink);
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-md);
  min-height: 48px; padding: 0 var(--space-4); width: 100%;
}
.field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%), linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%); background-position: calc(100% - 22px) 21px, calc(100% - 16px) 21px; background-size: 6px 6px; background-repeat: no-repeat; padding-right: 44px; }
.field input:focus-visible, .field select:focus-visible { border-color: var(--temporal); }
.honey { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.join-card .btn { width: 100%; margin-top: var(--space-2); }
.join-card .fine { margin: var(--space-4) 0 0; text-align: center; }

/* Footer */
.footer { border-top: 1px solid var(--rule); padding: var(--space-8) 0 var(--space-12); }
.footer .wrap { display: flex; flex-wrap: wrap; gap: var(--space-4) var(--space-8); align-items: center; justify-content: space-between; }
.footer nav { display: flex; gap: var(--space-6); flex-wrap: wrap; }
.footer nav a { color: var(--ink-muted); text-decoration: none; font-size: 0.875rem; }
.footer nav a:hover { color: var(--ink); }
.footer .fine { margin: 0; }

/* Long-form pages (Support, Privacy) */
.doc { padding: clamp(56px, 8vw, 96px) 0 clamp(64px, 9vw, 120px); }
.doc h1 { font-size: clamp(2.25rem, 5vw, 3.25rem); line-height: 1.05; font-weight: 700; letter-spacing: -0.03em; }
.doc .lede { font-size: clamp(1.125rem, 1.8vw, 1.3125rem); }
.doc h2 { font-size: 1.5rem; line-height: 1.2; font-weight: 700; letter-spacing: -0.02em; margin: clamp(40px, 5vw, 56px) 0 var(--space-3); }
.doc h3 { font-size: 1.125rem; font-weight: 600; margin: var(--space-6) 0 var(--space-2); letter-spacing: -0.01em; }
.doc p, .doc li { line-height: 1.6; }
.doc p { margin: 0 0 var(--space-4); }
.doc ul { padding-left: 1.2em; margin: 0 0 var(--space-4); }
.doc li { margin-bottom: var(--space-2); }
.doc li::marker { color: var(--ink-faint); }
/* Support: the maker's sign-off, in the founder caption's size and weight */
.doc .signoff { font-size: 0.9375rem; font-weight: 600; color: var(--ink); }
.summary { margin-top: var(--space-8); background: var(--paper-sunken); border: 1px solid var(--rule); border-radius: 18px; padding: var(--space-6); }
.summary h2 { margin-top: 0; font-size: 1.125rem; }
.summary ul { margin-bottom: 0; }
.toc { margin-top: var(--space-8); columns: 2; column-gap: var(--space-8); padding-left: 1.2em; }
@media (max-width: 560px) { .toc { columns: 1; } }
.toc li { break-inside: avoid; }
.contact-card { margin-top: var(--space-8); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
@media (max-width: 640px) { .contact-card { grid-template-columns: 1fr; } }
.contact-card > div { background: var(--paper-raised); border: 1px solid var(--rule); border-radius: 18px; padding: var(--space-6); }
.contact-card h2 { margin: 0 0 var(--space-2); font-size: 1.125rem; }
.contact-card p { margin: 0 0 var(--space-3); color: var(--ink-muted); }
.kbd { font-family: var(--font-mono); font-size: 0.875em; background: var(--paper-sunken); border: 1px solid var(--rule); border-radius: var(--radius-xs); padding: 0 0.35em; }

/* Recordings: a card with the app's paper behind the clip */
.video-card { border-radius: 26px; overflow: hidden; background: var(--paper-sunken); border: 1px solid var(--rule); box-shadow: var(--shadow-lift); }
.video-card video { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
.video-card.tall video { aspect-ratio: 880 / 1820; max-height: 760px; object-fit: contain; background: var(--paper-sunken); }
.video-card.tall { max-width: 340px; margin: 0 auto; }
figure { margin: 0; }
figcaption.fine { margin-top: var(--space-3); text-align: center; }

.measure { max-width: 44em; }
.mt-4 { margin-top: var(--space-4); }
.mt-6 { margin-top: var(--space-6); }
.mt-8 { margin-top: var(--space-8); }
.hero-device.mt-section { margin-top: clamp(32px, 5vw, 56px); }

/* Balanced headings, no orphans */
.display, .headline, .title, .statement, .lede, .tile h3 { text-wrap: balance; }
p, li { text-wrap: pretty; }
.lockup svg { width: 1.35rem; height: 1.35rem; transform: translateY(0.08em); }

/* ---------- Motion ----------
   Pen, then paper: only the mark draws, once per page; everything else settles on a critically
   damped spring (no overshoot, no bounce, no glow, no loop). The base styles above are the finished
   page. Hidden starting values exist only in keyframes with a backwards fill (the load moments) or
   under .is-pending, which site.js adds only to blocks entirely below the screen. Only transform and
   opacity move (and stroke-dashoffset on the 64 px mark). Reduce Motion: cross-fades only. */

@keyframes gn-fade { from { opacity: 0; } }
@keyframes gn-rise { from { transform: translateY(12px); } }
@keyframes gn-node { from { opacity: 0; transform: scale(0.8); } }
@keyframes gn-drop { from { transform: translateY(-6px); } }
@keyframes gn-settle { from { transform: scale(0.94); } to { transform: none; } }

/* M1. The mark draws itself (the app's launch drawing): the three dots alone for 0.30 s, then the
   teal edge from the top dot (0.30 s), the gold edge from the right dot (0.35 s) and the loop from
   the bottom-left dot back up to the top (0.55 s), each on ease in and out, with no pause. Each line
   is revealed from the dot it starts at. The dash exists only while a line draws (backwards fill),
   so at rest the strokes are the static colour mark. Dash lengths are the paths' lengths
   (33.53, 42.76, 90.67) rounded up; recompute them with getTotalLength() if the paths change. */
.mark-draw { display: block; width: 64px; height: 64px; margin: 0 auto var(--space-4); }
/* The mark's clear space: a disc of paper hides the hero's dot grid around it, so no grid dot reads
   as a fourth node. Paper on paper, so nothing else shows. */
.hero .mark-draw { position: relative; z-index: 0; border-radius: 50%; background: var(--paper); box-shadow: 0 0 0 14px var(--paper); }
.mark-draw .mark-gold { stroke: var(--temporal); }
.mark-draw .mark-teal { stroke: var(--semantic); }
.mark-draw .mark-loop { stroke: var(--ink); }
.mark-draw .mark-nodes { fill: var(--ink); }
@keyframes mark-teal { from { stroke-dasharray: 34 34; stroke-dashoffset: 34; } to { stroke-dasharray: 34 34; stroke-dashoffset: 0; } }
@keyframes mark-gold { from { stroke-dasharray: 43 43; stroke-dashoffset: 43; } to { stroke-dasharray: 43 43; stroke-dashoffset: 0; } }
@keyframes mark-loop { from { stroke-dasharray: 91 91; stroke-dashoffset: 91; } to { stroke-dasharray: 91 91; stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .mark-draw .mark-teal { animation: mark-teal 300ms var(--ease-in-out) 300ms backwards; }
  .mark-draw .mark-gold { animation: mark-gold 350ms var(--ease-in-out) 600ms backwards; }
  .mark-draw .mark-loop { animation: mark-loop 550ms var(--ease-in-out) 950ms backwards; }
}
@media (prefers-reduced-motion: reduce) {
  /* The lines fade in as one group, so overlapping strokes never double up. */
  .mark-draw .mark-lines { animation: gn-fade 200ms linear 300ms backwards; }
}

/* M2. The hero arrives under the mark: copy from 300 ms (with the teal edge), 70 ms apart; the
   board fades only (a rise would be clipped by .hero). Pure CSS, so it always completes. */
@media (prefers-reduced-motion: no-preference) {
  .intro { animation: gn-fade var(--dur-fade) var(--ease-out) var(--intro-delay, 0ms) backwards, gn-rise var(--dur-move) var(--ease-spring) var(--intro-delay, 0ms) backwards; }
  .hero .eyebrow.intro { --intro-delay: 300ms; }
  .hero .display.intro { --intro-delay: 370ms; }
  .hero .lede.intro { --intro-delay: 440ms; }
  .hero .hero-cta.intro { --intro-delay: 510ms; }
  .hero .hero-device.intro { animation: gn-fade 700ms var(--ease-out) 580ms backwards; }
  .hero .display .soft { animation: gn-fade 600ms var(--ease-out) 550ms backwards; }
  .hero::before { animation: gn-fade 900ms var(--ease-out) 300ms backwards; }
}
@media (prefers-reduced-motion: reduce) {
  .intro { animation: gn-fade var(--dur-calm) linear backwards; }
}

/* M3. The two large iPads settle from 0.94 to 1 as they come up the screen, about their top centre,
   and rest at none. The timeline subject is the parent, so the scale never feeds back into its own
   progress. Longhands only: an animation shorthand would reset animation-timeline. The 1ms duration
   is the fallback for an engine without animation-duration: auto (it is normalized to the range). */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero .hero-device, #rediscover .hero-device { view-timeline-name: --device; view-timeline-axis: block; }
    .hero .hero-device > .ipad, #rediscover .hero-device > .ipad {
      transform-origin: 50% 0;
      animation-name: gn-settle;
      animation-duration: 1ms;
      animation-duration: auto;
      animation-timing-function: var(--ease-in-out);
      animation-fill-mode: both;
      animation-timeline: --device;
      animation-range: cover 0% cover 40%;
    }
    #rediscover .hero-device.reveal.is-pending { transform: none; } /* one mechanism moves it */
  }
}

/* M4. Content settles once (the reveal system, driven by site.js). Every .reveal is visible unless
   site.js marks it .is-pending, which it does only for blocks entirely below the screen. Section
   heads cascade by child. .founder sits in the hiding rule because its own transition below would
   otherwise outrank transition: none and fade the quote out as it is hidden. */
.reveal.is-pending,
.founder .reveal.is-pending,
.section-head.reveal.is-pending > * { opacity: 0; transition: none; }
.section-head.reveal.is-pending { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .reveal { transition: opacity var(--dur-fade) var(--ease-out) var(--reveal-delay, 0ms), transform var(--dur-move) var(--ease-spring) var(--reveal-delay, 0ms); }
  .reveal.is-pending, .section-head.reveal.is-pending > * { transform: translateY(16px); }
  .section-head.reveal, .section-head.reveal.is-pending { transform: none; transition: none; }
  .section-head.reveal > * { transition: opacity var(--dur-fade) var(--ease-out) calc(var(--reveal-delay, 0ms) + var(--reveal-step, 0ms)), transform var(--dur-move) var(--ease-spring) calc(var(--reveal-delay, 0ms) + var(--reveal-step, 0ms)); }
  .section-head.reveal > :nth-child(2) { --reveal-step: 70ms; }
  .section-head.reveal > :nth-child(3) { --reveal-step: 140ms; }
}
@media (prefers-reduced-motion: reduce) {
  .reveal, .section-head.reveal > * { transition: opacity var(--dur-calm) linear; }
  .section-head.reveal { transition: none; }
}

/* M5. Eyebrow dots arrive as the design system's indicators: a 200 ms fade with a scale from 0.8,
   120 ms after their eyebrow. They never pulse. */
.section-head.reveal.is-pending .eyebrow .dot { opacity: 0; transition: none; }
@media (prefers-reduced-motion: no-preference) {
  .section-head.reveal.is-pending .eyebrow .dot { transform: scale(0.8); }
  .section-head.reveal .eyebrow .dot { transition: opacity var(--dur-indicator) var(--ease-out) calc(var(--reveal-delay, 0ms) + 120ms), transform var(--dur-indicator) var(--ease-out) calc(var(--reveal-delay, 0ms) + 120ms); }
}
@media (prefers-reduced-motion: reduce) {
  .section-head.reveal .eyebrow .dot { transition: opacity var(--dur-indicator) linear; }
}

/* M6. The statement's second sentence follows its first (opacity only; the text is never split). */
.statement.reveal.is-pending .muted { opacity: 0; transition: none; }
@media (prefers-reduced-motion: no-preference) {
  .statement.reveal .muted { transition: opacity 700ms var(--ease-out) calc(var(--reveal-delay, 0ms) + 240ms); }
}
@media (prefers-reduced-motion: reduce) {
  .statement.reveal .muted { transition: opacity var(--dur-calm) linear 150ms; }
}

/* M7. The founder's words fade in place: no rise, then the name. */
.founder .reveal.is-pending figcaption { opacity: 0; transition: none; }
@media (prefers-reduced-motion: no-preference) {
  .founder .reveal { transition: opacity 900ms var(--ease-out) var(--reveal-delay, 0ms); }
  .founder .reveal.is-pending { transform: none; }
  .founder .reveal figcaption { transition: opacity 600ms var(--ease-out) calc(var(--reveal-delay, 0ms) + 300ms); }
}
@media (prefers-reduced-motion: reduce) {
  .founder .reveal { transition: opacity var(--dur-calm) linear; }
  .founder .reveal figcaption { transition: opacity var(--dur-calm) linear 150ms; }
}

/* M8. The segmented control: equal segments, as in UISegmentedControl, with one thumb that slides
   (translate only, never width or scale) when site.js confirms they fit (.has-thumb); otherwise
   (.seg-natural, or Reduce Motion) natural widths and each segment's own pill, cross-faded. The
   new panel cross-fades in as it leaves display: none. */
.js .segmented { position: relative; flex: none; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
.js .segmented.seg-natural { display: inline-flex; }
.js .segmented button { position: relative; z-index: 1; padding-inline: clamp(9px, 2.4vw, 26px); }
.js .segmented button[aria-selected="true"] { background: none; box-shadow: none; }
.js .segmented button:focus-visible { box-shadow: var(--focus-ring); border-radius: var(--radius-full); }
.js .segmented button::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: var(--radius-full); background: var(--paper-raised); box-shadow: var(--shadow-card); opacity: 0; transition: opacity var(--dur-indicator) linear; }
.js .segmented button[aria-selected="true"]::before { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .js .segmented.has-thumb::before { content: ""; position: absolute; z-index: 0; top: 3px; bottom: 3px; left: 3px; width: calc((100% - 10px) / 3); border-radius: var(--radius-full); background: var(--paper-raised); box-shadow: var(--shadow-card); transform: translateX(calc(var(--tab-index, 0) * (100% + 2px))); transition: transform var(--dur-control) var(--ease-spring); }
  .js .segmented.has-thumb button::before { display: none; }
  .js .panel:not([hidden]) { animation: gn-fade 240ms var(--ease-out) backwards; }
}
@media (prefers-reduced-motion: reduce) {
  .js .panel:not([hidden]) { animation: gn-fade 200ms linear backwards; }
}
@media (forced-colors: active) {
  .segmented button[aria-selected="true"] { outline: 2px solid CanvasText; outline-offset: -2px; }
}

/* M9. A FAQ answer drops 6 px into place as it opens; the chevron turns on the spring. Closing is
   immediate, and height never animates. */
@media (prefers-reduced-motion: no-preference) {
  .faq details[open] > .answer { animation: gn-fade 240ms var(--ease-out), gn-drop var(--dur-control) var(--ease-spring); }
  .faq summary::after { transition: transform var(--dur-control) var(--ease-spring); }
}
@media (prefers-reduced-motion: reduce) {
  .faq details[open] > .answer { animation: gn-fade 200ms linear; }
}

/* M10. Buttons press in over 90 ms and spring back over 320 ms. site.js adds .press-ready (and the
   touch listener iOS needs for :active), so only there is the tap highlight removed: on the buttons,
   and on the segments and FAQ questions, whose thumb, pill or chevron already answers the tap. */
@media (prefers-reduced-motion: no-preference) {
  .btn { transition: transform var(--dur-release) var(--ease-spring), filter 160ms var(--ease-out); }
  .btn:active { transform: scale(0.97); transition: transform var(--dur-press) var(--ease-out), filter 160ms var(--ease-out); }
}
@media (prefers-reduced-motion: reduce) {
  .btn:active { filter: brightness(0.92); }
}
.press-ready .btn,
.press-ready .segmented button,
.press-ready .faq summary { -webkit-tap-highlight-color: transparent; }

/* Print: every block at its end state. */
@media print {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal.is-pending,
  .section-head.reveal.is-pending > *,
  .statement.reveal.is-pending .muted,
  .founder .reveal.is-pending figcaption,
  .section-head.reveal.is-pending .eyebrow .dot { opacity: 1 !important; transform: none !important; }
}
