/* Self-hosted, latin subset, variable weight. See assets/fonts/README.md for why
   these are not linked from a CDN. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('assets/fonts/fraunces-latin-var.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('assets/fonts/inter-latin-var.woff2') format('woff2');
}

/* Theme tokens. Values here are the pre-JS fallback; src/theme.js overwrites them
   from content/theme/default.json so theming stays a data change, not a code change. */
:root {
  --ink: #151c27;
  --raised: #1d2633;
  --line: #2b3645;
  --text: #e9e7e1;
  --muted: #8a94a4;
  --accent-warm: #e2a878;
  --accent-teal: #7aa8a0;
  --accent-clay: #d98c7a;

  --font-display: 'Fraunces', 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Hoefler Text', Georgia, serif;
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Type scale. Seven sizes, and every piece of text uses one of them. Quiet is
     expressed with colour and weight, never by shrinking text — someone reading this
     at 3am with their phone at arm's length should not meet 12px anywhere that
     matters. */
  --text-xs:  0.75rem;
  --text-sm:  0.875rem;
  --text-base: 1rem;
  --text-lg:  1.125rem;
  --text-xl:  1.5rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.25rem;

  --leading-tight: 1.2;
  --leading: 1.55;

  /* Spacing scale. */
  --space-0: 0.125rem;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 2.75rem;
  --space-8: 4rem;

  /* Motion. Short and soft — nothing on this site should feel eager. */
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --dur-fast: 120ms;
  --dur: 200ms;

  --step: 1rem;
  --measure: 34ch;
  --radius: 10px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--ink);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: var(--leading);
  -webkit-text-size-adjust: 100%;
  /* Light type on a dark ground renders too heavy on Apple devices without this. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* The default grey flash on tap looks like a glitch. We supply our own :active. */
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

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

/* One decision per screen: everything is centred, generous, and thumb-reachable. */
#app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

main {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--step) * 1.5);
  padding: calc(var(--step) * 2);
  text-align: center;
}

main:focus { outline: none; }

/* The flow screens must fit between a browser address bar and the crisis link, so
   they use a tighter frame than the prose and landing screens. */
main[data-screen="breathe"],
main[data-screen="ground"],
main[data-screen="reframe"],
main[data-screen="checking"],
main[data-screen="exit"],
main[data-screen="contact"] {
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}

/* A list must start at the top and scroll. */
main[data-screen="help"] {
  justify-content: flex-start;
  padding-top: calc(var(--step) * 2.5);
}

/* The door sits centred in the lower two-thirds: still under the thumb on a phone
   held one-handed, without the bottom-weighted look that reads as unbalanced rather
   than calm. Capped in rem so a short screen does not push the button off the
   bottom. */
main[data-screen="landing"] {
  justify-content: center;
  padding-top: min(22vh, 12rem);
}

.wordmark {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 400;
  line-height: var(--leading-tight);
  /* Fraunces sets loose at display sizes; pull it in slightly so the wordmark
     reads as one shape rather than five letters. */
  letter-spacing: -0.015em;
  margin: 0;
}

.lede {
  max-width: var(--measure);
  color: var(--muted);
  margin: 0;
  text-wrap: pretty;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--raised);
  color: var(--text);
  padding: 0.75rem 1rem;
  z-index: 10;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 2px solid var(--accent-warm);
  outline-offset: 3px;
}

.diagnostics {
  margin: 0;
  max-width: 46ch;
  text-align: left;
  font-size: var(--text-xs);
  color: var(--muted);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
  white-space: pre-wrap;
  overflow-x: auto;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------------ screens */

.screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--step) * 1.5);
  width: 100%;
  max-width: 30rem;
}

/* Three beats, not four evenly spaced things: the name, the decision, the way out.
   The gap below the button is wider than the gap above it so the secondary link
   reads as an escape hatch rather than a second option of equal weight. */
.screen--landing {
  gap: var(--space-6);
}

.wordmark--landing {
  font-size: var(--text-3xl);
  color: var(--text);
}

/* The honest line about what this is. Sits closer to the wordmark than to the
   button, because it belongs to the name, not to the decision. */
.lede--honesty {
  color: var(--muted);
  font-size: var(--text-lg);
  line-height: 1.45;
  margin-top: calc(var(--space-2) * -1);
  text-wrap: balance;
}

.actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
}

/* ------------------------------------------------------- spike flow screens */

/* The spoken lines — first contact, the grounding prompt, "you got through it".
   Display face, generous, the only voice in the product that addresses you directly. */
.spoken {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: -0.01em;
  max-width: 22ch;
  margin: 0;
  text-wrap: balance;
}

.screen__heading {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 500;
  line-height: 1.35;
  margin: 0;
  max-width: 26ch;
  text-wrap: balance;
}

/* Screen 04's heading is an acknowledgement, not a title. It should not shout. */
.screen__heading--soft {
  font-weight: 400;
  color: var(--muted);
  max-width: 32ch;
}

.lede--wide { max-width: 30ch; }
.lede--small { font-size: var(--text-sm); }

/* Sits close under the control it explains, and well clear of the way forward. */
.lede--hint {
  margin-top: calc(var(--space-2) * -1);
  margin-bottom: var(--space-3);
  max-width: 28ch;
}

.screen--contact { gap: var(--space-8); }

/* ------------------------------------------------------------------ the orb */

/* Bounded by both viewport axes so it fits a phone showing its address bar without
   ever collapsing. `aspect-ratio` with an auto width was tried first and resolved to
   the minimum, because the cross size in a centred column is content-based and the
   orb inside sizes from its parent — a circular dependency that always loses. */
.orb__stage {
  position: relative;
  display: grid;
  place-items: center;
  width: min(15rem, 55vw, 40vh);
  height: min(15rem, 55vw, 40vh);
  flex: 0 0 auto;
}

.orb {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  transform: scale(0.62);
  background:
    radial-gradient(circle at 50% 45%,
      color-mix(in srgb, var(--accent-warm) 30%, transparent) 0%,
      color-mix(in srgb, var(--accent-warm) 12%, transparent) 55%,
      transparent 72%);
  border: 1px solid color-mix(in srgb, var(--accent-warm) 30%, transparent);
  /* Linear, not eased: a breath is paced, and easing would rush the middle of it. */
  transition-property: transform;
  transition-timing-function: linear;
  will-change: transform;
}

.orb__seconds {
  position: absolute;
  font-size: var(--text-2xl);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* One line, not two. On a phone the second row was costing the orb its size. */
.orb__status {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--space-3);
  min-height: 1.6em;
}

.orb__phase {
  font-size: var(--text-lg);
  color: var(--text);
  margin: 0;
}

.orb__count {
  font-size: var(--text-sm);
  color: var(--muted);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Reduced motion: the circle holds still and the count does the pacing. */
@media (prefers-reduced-motion: reduce) {
  .orb { transition: none !important; }
}

/* --------------------------------------------------- flow bar: back + position */
/* Orientation, not navigation. Faint enough to ignore, present enough to answer
   "can I go back" and "how much more of this is there" without asking. */

.flow__top {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  padding: calc(var(--space-1) + env(safe-area-inset-top)) var(--space-4) var(--space-1);
}

.flow__back {
  color: var(--muted);
  font-size: var(--text-sm);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-right: var(--space-3);
  opacity: 0.7;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.flow__back:hover,
.flow__back:focus-visible { opacity: 1; color: var(--text); }

/* Holds the dots in place on the last screen, where there is no way back. */
.flow__back--empty { min-height: 44px; }

.flow__dots {
  display: flex;
  align-items: center;
  gap: 6px;
}

.flow__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--line);
  transition: background-color var(--dur) var(--ease);
}

.flow__dot--here { background: var(--muted); }

/* The tallest screen in the flow. Everything must be reachable without scrolling on
   a phone showing its address bar — a hidden Continue is a dead end for someone who
   will not think to scroll. */
.screen--breathe {
  gap: var(--space-3);
}

/* The way forward is a different kind of thing from the settings above it, and needs
   to look like it rather than like a fourth pill in a stack. */
.screen--breathe .btn--quiet { margin-top: var(--space-3); }

.screen--breathe .orb__phase { min-height: 1.4em; }

/* ------------------------------------------------------------------- chips */

.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
}

.chip {
  font: inherit;
  font-size: var(--text-sm);
  color: var(--muted);
  background: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: var(--space-2) var(--space-4);
  min-height: 44px;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}

.chip:hover { color: var(--text); }

.chip[aria-pressed="true"] {
  color: var(--accent-warm);
  border-color: color-mix(in srgb, var(--accent-warm) 55%, transparent);
}

.chip--quiet { border-color: transparent; }

/* Separates the independent toggle from the either/or choice above it. This was a
   negative margin, which cancelled the row gap entirely and left three pills stacked
   with no air between them. */
.chips--aside { margin-top: var(--space-1); }

/* ------------------------------------------------------------------ ground */

.ground__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.ground__count {
  font-family: var(--font-display);
  font-size: 4rem;
  line-height: 1;
  color: var(--accent-teal);
  margin: 0;
  font-variant-numeric: lining-nums;
}

/* ----------------------------------------------------------------- reframe */

.screen--reframe {
  width: 100%;
  gap: var(--space-3);
}

.screen--reframe .screen__heading--soft { margin-bottom: var(--space-1); }

/* Two layouts, chosen by what the screen is likely being driven with.

   Narrow: a horizontal snap deck. A thumb swipes it naturally and the peeking card
   edge says there is more.

   Wide: a plain vertical stack. A horizontal deck on a desktop is a trap — the
   scrollbar is hidden, a trackpad scrolls vertically, and you are left looking at a
   cut-off card you cannot reach. It looked broken because it was. */
.cards {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
}

@media (max-width: 639px) {
  .cards {
    flex-direction: row;
    align-items: stretch;
    padding: 0 calc(50% - 9.5rem);
    width: 100vw;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }

  .cards::-webkit-scrollbar { display: none; }
}

.card {
  flex: 0 0 auto;
  width: min(19rem, 100%);
  scroll-snap-align: center;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: var(--space-4);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.card__thought {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1.35;
  color: var(--accent-clay);
  margin: 0;
}

.card__body {
  font-size: var(--text-base);
  color: var(--text);
  margin: 0;
}

.cards__dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: var(--space-3);
}

/* The dots describe a deck. On the stacked layout every card is already visible, so
   they would be counting things you can see. Must come after the rule above. */
@media (min-width: 640px) {
  .cards__dots { display: none; }
}

.reframe__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

/* -------------------------------------------------------------------- exit */

.screen--exit { gap: var(--space-6); }

.exit__log,
.exit__after {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

/* The soft nudge. Emphasis only — never a modal, never a lock. */
.pointer {
  color: var(--muted);
  font-size: var(--text-base);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding: var(--space-3) var(--space-1);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  max-width: 30ch;
  text-align: center;
  transition: color var(--dur) var(--ease);
}

.pointer:hover,
.pointer:focus-visible { color: var(--accent-teal); }

.pointer--nudged {
  color: var(--accent-teal);
  border-bottom-color: var(--accent-teal);
}

/* ------------------------------------------------------------------ controls */

.btn {
  font: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-decoration: none;
  font-size: var(--text-lg);
  border: 0;
  border-radius: 999px;
  padding: var(--space-4) var(--space-6);
  min-height: 3.5rem;
  width: 100%;
  max-width: 20rem;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}

.btn--primary {
  background: var(--accent-warm);
  color: var(--ink);
  font-weight: 500;
}

.btn--primary:hover { background: #eab98d; }
.btn--primary:active { transform: scale(0.98); }

/* The way forward inside the flow. Must come after .btn, which zeroes the border —
   defined above it, this rule silently lost and every "button" rendered as plain
   text. */
.btn--quiet {
  background: none;
  border: 1px solid var(--line);
  color: var(--text);
  font-size: var(--text-base);
  font-weight: 400;
  width: auto;
  min-width: 10rem;
  transition: border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}

.btn--quiet:hover {
  border-color: var(--accent-warm);
  color: var(--accent-warm);
}

.link {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding: var(--space-3) var(--space-1);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font: inherit;
  background: none;
  border-width: 0 0 1px 0;
  cursor: pointer;
}

.link:hover,
.link:focus-visible { color: var(--text); border-bottom-color: var(--line); }

.link--quiet { font-size: var(--text-base); }

.field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--muted);
}

.select {
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
}

/* ------------------------------------------------- the pinned crisis link */
/* Present on every screen, never hidden, never conditional, never adjacent to
   anything commercial. CLAUDE.md, crisis handling component 1. */

.crisis {
  position: sticky;
  bottom: 0;
  width: 100%;
  padding: var(--space-1) var(--space-4)
           calc(var(--space-1) + env(safe-area-inset-bottom));
  text-align: center;
  background: linear-gradient(to top, var(--ink) 55%, transparent);
}

.crisis__link {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  font-size: var(--text-base);
  text-decoration: none;
  padding: var(--space-3) var(--space-4);
  min-height: 44px;
  border-bottom: 1px solid var(--line);
}

.crisis__link {
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}

.crisis__link:hover,
.crisis__link:focus-visible { color: var(--accent-teal); border-bottom-color: var(--accent-teal); }

/* ------------------------------------------------------------------- help */
/* Not cards. A list of phone numbers someone needs to tap at 3am, set like a
   printed emergency card: the number is the largest thing on the row, the name is
   a quiet label above it, and hairlines separate rows instead of boxes.
   Tier 1 is warm and large. Tier 2 is teal, small, and set apart, so the two can
   never be read as one list. */

.screen--help {
  text-align: left;
  align-items: stretch;
  gap: 0;
}

.tier { width: 100%; }

.tier__heading {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.5rem;
}

.tier__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Rules sit between rows, never above the first or below the last — a hairline
   with nothing above it reads as a stray mark, which is what it was doing while the
   tier headings are unwritten. */
.entry {
  display: flex;
  flex-direction: column;
  gap: var(--space-0);
  padding: var(--space-4) 0;
}

.entry + .entry { border-top: 1px solid var(--line); }

.entry__name {
  color: var(--muted);
  font-size: var(--text-sm);
}

/* The action. Tabular figures so the numerals line up down the column. */
.entry__tel {
  color: var(--accent-warm);
  text-decoration: none;
  font-size: var(--text-2xl);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  letter-spacing: -0.01em;
  line-height: var(--leading-tight);
  padding: var(--space-1) 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  width: fit-content;
}

.entry__tel:hover,
.entry__tel:focus-visible { color: #f0c69c; }

.entry__alt {
  color: var(--accent-warm);
  font-size: var(--text-base);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  width: fit-content;
}

.entry__alt:hover { text-decoration: underline; }

/* No uppercase here. It caught a brand name and turned a full sentence into
   shouting, and small caps cost legibility exactly where it is least affordable. */
.entry__meta {
  color: var(--muted);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
}

.entry__alt-wrap { display: block; }

/* Ongoing care. Deliberately a different register: no large numerals, cooler
   accent, set below a wider gap. Nobody should mistake this for the urgent list. */
/* The width of this gap is the only thing separating urgent from non-urgent while
   both headings are unwritten. It is doing real work; do not tighten it. */
.tier--care {
  margin-top: var(--space-7);
}

.tier--care .entry {
  padding: var(--space-3) 0;
}

.entry__name--link {
  color: var(--accent-teal);
  font-size: var(--text-base);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.entry__name--link:hover { text-decoration: underline; }

/* No box. A notice in a box reads as an alert; this is an admission. */
.lede--notice {
  max-width: none;
  color: var(--muted);
  font-size: var(--text-base);
  margin: 0 0 var(--space-5);
  padding-left: var(--space-3);
  border-left: 2px solid var(--accent-teal);
}

.help__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--step);
  flex-wrap: wrap;
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

/* ------------------------------------------------------- dev: slots + gallery */
/* Neither of these can appear off a private host — see src/dev/dev.js. */

.slot {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
  color: var(--accent-clay);
  border: 1px dashed var(--accent-clay);
  border-radius: 4px;
  padding: 0.4rem 0.6rem;
  opacity: 0.75;
}

main[data-screen="gallery"] {
  justify-content: flex-start;
  padding: calc(var(--step) * 2);
  text-align: left;
}

.screen--gallery {
  max-width: none;
  align-items: stretch;
  gap: calc(var(--step) * 3);
}

.gallery__head { border-bottom: 1px solid var(--line); padding-bottom: var(--step); }

.gallery__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 400;
  margin: 0 0 0.35rem;
}

.gallery__sub { color: var(--muted); font-size: var(--text-sm); margin: 0; max-width: 60ch; }

.gallery__group-title {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 var(--step);
}

.gallery__grid {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--step) * 1.5);
}

.frame { margin: 0; }

.frame__view {
  display: block;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--ink);
  color-scheme: dark;
}

.frame__caption {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding-top: var(--space-3);
  font-size: var(--text-xs);
}

.frame__label { color: var(--text); }
.frame__note { color: var(--muted); flex: 1; }
.frame__open { color: var(--accent-teal); text-decoration: none; }
.frame__open:hover { text-decoration: underline; }

.frame__audit { padding-top: 0.5rem; max-width: 375px; }

.a11y {
  font: inherit;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: none;
  padding: 0.25rem 0.6rem;
  cursor: pointer;
}

.a11y--pass { color: var(--accent-teal); }
.a11y--warn { color: var(--accent-warm); }
.a11y--fail { color: var(--accent-clay); }
.a11y--skip { color: var(--muted); border-style: dashed; }

.a11y__list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: var(--text-xs);
}

.a11y__item {
  display: flex;
  gap: 0.5rem;
  color: var(--muted);
  line-height: 1.4;
}

.a11y__item code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
  flex: 0 0 4.5rem;
}

.a11y__item--fail code { color: var(--accent-clay); }
.a11y__item--warn code { color: var(--accent-warm); }

/* ------------------------------------------------------------------- prose */
/* Static pages: about, disclaimer, privacy. Real paths, real HTML, readable by a
   crawler without running anything — see docs/REACH.md. */

main[data-screen="prose"] {
  justify-content: flex-start;
  align-items: center;
  padding: var(--space-6) var(--space-4) var(--space-8);
  text-align: left;
}

.prose {
  max-width: 36rem;
  width: 100%;
}

.prose h1 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 400;
  line-height: var(--leading-tight);
  letter-spacing: -0.015em;
  margin: 0 0 var(--space-5);
}

.prose h2 {
  font-size: var(--text-lg);
  font-weight: 500;
  margin: var(--space-7) 0 var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.prose h3 {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--muted);
  margin: var(--space-5) 0 var(--space-2);
}

.prose p {
  margin: 0 0 var(--space-4);
  max-width: 62ch;
  text-wrap: pretty;
}

.prose__lede {
  font-size: var(--text-lg);
  line-height: 1.5;
  color: var(--text);
}

.prose__list {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
  max-width: 62ch;
}

.prose__list li { margin-bottom: var(--space-2); }

.prose strong { font-weight: 600; }

.prose a {
  color: var(--accent-warm);
  text-underline-offset: 3px;
}

.prose__meta {
  color: var(--muted);
  font-size: var(--text-sm);
  margin-top: var(--space-6);
}

/* --------------------------------------------------------------- utilities */

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