/* web-studio design system: BASE. Reset, type scale, links, the pill, reveals and write-on words.
   Needs tokens.css first. Generalised from AirwayControl's base.css (2026-09-30); every duration
   and curve is a token (docs/rules/01-motion.md), every colour a palette token. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: auto; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: var(--fs-body)/1.47 var(--font);
  letter-spacing: -0.022em;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip; /* nothing may scroll the page sideways (measure at 320, 360, 393) */
}
img, video { display: block; max-width: 100%; height: auto; }

/* links and controls never change state with a hard cut: the underline is always there in a
   transparent colour and fades in; the focus ring is always there, transparent, and fades in. */
a { color: var(--link); text-decoration: underline; text-decoration-color: transparent;
  transition: color var(--dur-fast) var(--ease-in-out), text-decoration-color var(--dur-fast) var(--ease-in-out),
    background-color var(--dur-fast) var(--ease-in-out), filter var(--dur-fast) var(--ease-in-out),
    opacity var(--dur-fast) var(--ease-in-out), outline-color var(--dur-fast) var(--ease-in-out); }
a:hover { text-decoration-color: currentColor; }
a, button { outline: 2px solid transparent; outline-offset: 3px; }
:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; border-radius: 6px; }

.wrap { width: min(var(--wrap), 100% - 2 * var(--gutter)); margin-inline: auto; }
.narrow { width: min(var(--narrow), 100% - 2 * var(--gutter)); margin-inline: auto; }
.section { padding-block: var(--section-pad); }

/* type scale, with Apple's tracking curve (tighter as it grows) */
.t-hero { font-size: var(--fs-hero); line-height: 1.04; font-weight: 600; letter-spacing: -0.015em; margin: 0; text-wrap: balance; }
.t-h1 { font-size: var(--fs-h1); line-height: 1.06; font-weight: 600; letter-spacing: -0.009em; margin: 0; text-wrap: balance; }
.t-h2 { font-size: var(--fs-h2); line-height: 1.08; font-weight: 600; letter-spacing: -0.003em; margin: 0; text-wrap: balance; }
.t-h3 { font-size: var(--fs-h3); line-height: 1.14; font-weight: 600; letter-spacing: 0.007em; margin: 0; text-wrap: balance; }
.t-lead { font-size: var(--fs-lead); line-height: 1.33; font-weight: 400; letter-spacing: 0.009em; color: var(--soft); margin: 0; text-wrap: pretty; }
.t-body { font-size: var(--fs-body); line-height: 1.47; color: var(--soft); margin: 0; max-width: 34em; text-wrap: pretty; }
.t-body b, .t-lead b { color: var(--ink); font-weight: 600; }
.t-eyebrow { font-size: 17px; line-height: 1.2; font-weight: 600; color: var(--accent); margin: 0; letter-spacing: -0.02em; }
.t-small { font-size: var(--fs-small); line-height: 1.33; color: var(--soft); letter-spacing: -0.01em; }

/* the pill: Apple's button, 44 px tall (the HIG's hit target) */
.btn { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 11px 22px; border-radius: var(--radius-pill); background: var(--ink); color: var(--on-ink); font-size: 17px; font-weight: 400; letter-spacing: -0.022em; }
.btn:hover { text-decoration: none; filter: brightness(1.08); }
.btn:active { filter: brightness(0.92); }
.btn--ghost { background: transparent; color: var(--link); box-shadow: inset 0 0 0 1px var(--link); }
.more::after { content: " \203A"; }

/* reveal: only blocks that START below the fold are ever hidden, and motion.js is what hides them,
   so without JavaScript nothing is hidden (fail-open). */
.reveal { transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease); }
.reveal.is-pending { opacity: 0; transform: translateY(var(--reveal-rise)); }
.reveal[data-delay="1"] { transition-delay: calc(1 * var(--reveal-step)); }
.reveal[data-delay="2"] { transition-delay: calc(2 * var(--reveal-step)); }
.reveal[data-delay="3"] { transition-delay: calc(3 * var(--reveal-step)); }

/* write-on: words brighten one by one as the paragraph scrolls through (motion.js splits them) */
[data-words] .w { color: var(--dim); transition: color var(--dur-word) var(--ease); }
[data-words] .w.on { color: var(--ink); }

/* a photograph still decoding fades in when ready, on its own clock (motion.js data-fade-ready) */
img[data-fade-ready] { transition: opacity var(--dur-enter) var(--ease-out); }
img[data-fade-ready].is-loading { opacity: 0; }
