/* ==========================================================================
   Mirovita Component Library
   Every rule reads from semantic tokens or component knobs: no raw hex,
   no magic numbers. Retune a component by overriding its knob in tokens.css.
   ========================================================================== */

/* ==========================================================================
   Brand lockup
   ========================================================================== */

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--color-brand);
}

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

/* Both glyphs need an explicit size: the SVGs carry a viewBox but no width or
   height, so without this they fall back to the intrinsic replaced-element box
   rather than anything anyone chose. */
.brand__mark {
  height: var(--brand-mark-size);
  width: var(--brand-mark-size);
  color: inherit;
}

.brand__wordmark {
  height: var(--brand-wordmark-height);
  width: auto;
  color: inherit;
}

.brand--lg .brand__wordmark { height: var(--brand-wordmark-height-lg); }

.brand--inverse { color: var(--white); }
.brand--inverse:hover { color: var(--teal-100); }

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--button-height-md);
  padding-inline: var(--button-padding-x-md);
  border-radius: var(--button-radius);
  font-family: var(--button-font);
  font-size: var(--text-base);
  font-weight: var(--button-weight);
  letter-spacing: var(--button-tracking);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  border: var(--border-width) solid transparent;
  transition: var(--transition-colors), var(--transition-transform),
              box-shadow var(--duration-fast) var(--ease-standard);
  white-space: nowrap;
}

.btn:active { transform: translateY(1px); }

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  background: var(--color-brand);
  color: var(--color-on-brand);
  box-shadow: var(--shadow-sm);
}

.btn--primary:hover:not(:disabled) {
  background: var(--color-brand-hover);
  color: var(--color-on-brand);
  box-shadow: var(--shadow-md);
}

.btn--primary:active:not(:disabled) { background: var(--color-brand-active); }

.btn--secondary {
  background: var(--color-surface);
  color: var(--color-brand);
  border-color: var(--border-color);
  box-shadow: var(--shadow-xs);
}

.btn--secondary:hover:not(:disabled) {
  border-color: var(--color-brand);
  background: var(--color-brand-subtle);
  color: var(--color-brand-hover);
}

.btn--ghost {
  background: transparent;
  color: var(--color-brand);
}

.btn--ghost:hover:not(:disabled) {
  background: var(--color-brand-subtle);
  color: var(--color-brand-hover);
}

.btn--inverse {
  background: var(--white);
  color: var(--teal-800);
}

.btn--inverse:hover:not(:disabled) {
  background: var(--teal-50);
  color: var(--teal-900);
}

.btn--outline-inverse {
  background: transparent;
  color: var(--white);
  border-color: color-mix(in srgb, var(--white) 45%, transparent);
}

.btn--outline-inverse:hover:not(:disabled) {
  background: color-mix(in srgb, var(--white) 12%, transparent);
  border-color: var(--white);
  color: var(--white);
}

.btn--sm {
  height: var(--button-height-sm);
  padding-inline: var(--button-padding-x-sm);
  font-size: var(--text-sm);
}

.btn--lg {
  height: var(--button-height-lg);
  padding-inline: var(--button-padding-x-lg);
  font-size: var(--text-lg);
}

.btn--block { width: 100%; }

.btn__icon { width: 1.1em; height: 1.1em; flex-shrink: 0; }

/* ==========================================================================
   Badges & pills
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--badge-padding);
  border-radius: var(--badge-radius);
  font-size: var(--badge-font-size);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--badge-tracking);
  text-transform: uppercase;
  background: var(--color-brand-subtle);
  color: var(--teal-700);
  white-space: nowrap;
}

.badge--accent { background: var(--color-accent-subtle); color: var(--amber-600); }
.badge--neutral { background: var(--ink-100); color: var(--ink-600); }
.badge--early { background: var(--signal-early-bg); color: var(--teal-700); }
.badge--late { background: var(--signal-late-bg); color: var(--red-700); }
.badge--inverse {
  background: color-mix(in srgb, var(--white) 16%, transparent);
  color: var(--white);
}

.badge__dot {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: var(--radius-circle);
  background: currentColor;
}

/* ==========================================================================
   Cards
   ========================================================================== */

.card {
  background: var(--card-bg);
  border: var(--card-border);
  border-radius: var(--card-radius);
  padding: var(--card-padding);
  box-shadow: var(--card-shadow);
  transition: box-shadow var(--duration-base) var(--ease-standard),
              transform var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-standard);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.card--interactive:hover {
  box-shadow: var(--card-shadow-hover);
  transform: translateY(-3px);
  border-color: var(--teal-200);
}

.card--flush { padding: 0; overflow: hidden; }
.card--sunken { background: var(--color-surface-sunken); box-shadow: none; }
.card--brand {
  background: var(--gradient-brand);
  border-color: transparent;
  color: color-mix(in srgb, var(--white) 85%, transparent);
}
.card--brand h2, .card--brand h3, .card--brand h4 { color: var(--white); }

.card--outline { box-shadow: none; border-color: var(--border-color); }

.card__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-medium);
}

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

.card__footer {
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: var(--border-width) solid var(--border-color-subtle);
}

.card__icon {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  background: var(--color-brand-subtle);
  color: var(--color-brand);
  margin-bottom: var(--space-2);
}

.card__icon svg { width: 1.5rem; height: 1.5rem; }

/* ==========================================================================
   Section headings
   ========================================================================== */

.section-head {
  max-width: 44rem;
  margin-bottom: clamp(var(--space-8), 4vw, var(--space-12));
}

.section-head--center {
  text-align: center;
  margin-inline: auto;
}

.section-head p { margin-top: var(--space-4); }

/* ==========================================================================
   Header / navigation
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--header-bg);
  backdrop-filter: blur(var(--header-blur));
  -webkit-backdrop-filter: blur(var(--header-blur));
  border-bottom: var(--header-border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: var(--header-height);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.site-nav__link {
  color: var(--text-body);
  text-decoration: none;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  padding-block: var(--space-2);
  position: relative;
}

.site-nav__link:hover { color: var(--color-brand); }

.site-nav__link[aria-current="page"] {
  color: var(--color-brand);
}

.site-nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--color-brand);
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.nav-toggle {
  display: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-sm);
  color: var(--text-heading);
  place-items: center;
}

.nav-toggle:hover { background: var(--ink-50); }
.nav-toggle svg { width: 1.5rem; height: 1.5rem; }
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

/* Mobile-first: the nav collapses behind a toggle below 900px. */
@media (max-width: 899px) {
  .nav-toggle { display: grid; }

  .site-header__nav {
    position: fixed;
    inset: var(--header-height) 0 auto 0;
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--border-color);
    box-shadow: var(--shadow-lg);
    padding: var(--space-6) var(--gutter) var(--space-8);
    display: none;
  }

  .site-header__nav[data-open="true"] { display: block; }

  .site-nav {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
  }

  .site-nav__link {
    padding: var(--space-3) var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--text-lg);
  }

  .site-nav__link[aria-current="page"]::after { display: none; }
  .site-nav__link[aria-current="page"] { background: var(--color-brand-subtle); }

  .site-header__nav .site-header__actions {
    margin-top: var(--space-5);
    flex-direction: column;
    align-items: stretch;
  }

  .site-header__actions--desktop { display: none; }
}

@media (min-width: 900px) {
  .site-header__nav .site-header__actions { display: none; }
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  background: var(--gradient-hero);
  padding-block: clamp(3rem, 8vw, 6.5rem) clamp(3rem, 7vw, 5.5rem);
  position: relative;
  overflow: hidden;
}

.hero__grid {
  display: grid;
  gap: clamp(var(--space-10), 5vw, var(--space-16));
  align-items: center;
  grid-template-columns: 1fr;
}

/* Weighted toward the text because the headline has to break in two, not three.
   1.25/0.75 is the widest the illustration can take before that breaks, and the
   margin is thin, so the arithmetic is written out rather than left to be
   rediscovered.

   At a 1200px viewport the container is 1200 wide less two 40px gutters, and
   the grid gap has reached its 4rem cap, so 1056px is divided: the text column
   is 1056 * r/2. Measured against the rendered headline, 647px still takes
   three lines and 660px takes two, which puts the cliff just under 1.25fr. The
   figure gets the remainder, 396px, against the 343 a 1.35/0.65 split left it.

   Two caveats on how far to trust that. The threshold moves with the viewport,
   because --text-3xl is itself a clamp on vw and only reaches its 2.75rem cap
   around 1280px; below roughly 1200px the column is too narrow either way and
   the headline is already three lines, which is the state most laptops see.
   And --font-display is a system stack whose first hit, Avenir Next, is macOS
   only, so the exact break is a fact about this machine's font, not a
   guarantee. Tuning past this precision buys nothing real. */
@media (min-width: 960px) {
  .hero__grid { grid-template-columns: 1.25fr 0.75fr; }
}

.hero__content { max-width: var(--container-narrow); }

/* --text-3xl is the h2 size: the hero is set to match the section headlines
   ("Stage is the single biggest predictor of survival") rather than outrank
   them. Size is the only override -- weight, tracking, leading and balance all
   come from the base h1..h6 rule, which is what keeps the two in step if that
   rule ever moves. */
.hero__title { font-size: var(--text-3xl); }

/* Colour alone, no weight bump: lifting the numbers above the surrounding text
   made them read as shouting rather than emphasis. Hue is enough at this size. */
.hero__title em {
  font-style: normal;
  color: var(--color-brand);
  font-weight: inherit;
}

/* 38rem, not the 34rem a measure-based cap would suggest: the lead is now four
   short declaratives rather than a paragraph, and at 34rem it broke after "No"
   and left "referral needed." stranded on its own line. */
.hero__lead {
  font-size: var(--text-lg);
  color: var(--text-muted);
  line-height: var(--leading-normal);
  max-width: 38rem;
  margin-top: var(--space-6);
}

.hero__actions { margin-top: var(--space-8); }

.hero__trust {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: var(--border-width) solid var(--border-color-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6) var(--space-8);
}

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

.hero__trust-value {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-medium);
  color: var(--text-heading);
}

.hero__figure {
  display: flex;
  justify-content: center;
}

/* The artwork carries its own colour, so nothing here paints it. What is left
   is the size cap and the edge.

   The PNG's corners are already alpha, but its glow is a pale cloud painted
   into the art rather than keyed out, and the hero gradient it lands on is
   tinted (teal-100 at top left, amber-50 at top right). A near-white cloud
   over a tinted ground stops somewhere visible, and a light shape with a
   findable boundary is the thing that reads as pasted on. The mask feathers
   that boundary away: opaque through the middle where the scanner and its
   glow are, gone by the time it reaches the ground it has to sit on.

   Not mix-blend-mode: multiply, which is the other way to drop a white
   background. Multiply would take the lit bore and the sparkles down with the
   halo, and the glow is the point of this illustration. */
.mri {
  width: 100%;
  max-width: var(--mri-max-width);
  height: auto;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 48%, transparent 76%);
  mask-image: radial-gradient(ellipse at center, #000 48%, transparent 76%);
}

/* ==========================================================================
   Survival statistics
   ========================================================================== */

.stat-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--border-color-subtle);
  border-radius: var(--card-radius);
  padding: var(--card-padding);
  box-shadow: var(--card-shadow);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  transition: box-shadow var(--duration-base) var(--ease-standard),
              transform var(--duration-base) var(--ease-out);
  /* Containing block for the stretched link on .stat-card__name a. */
  position: relative;
}

.stat-card:hover {
  box-shadow: var(--card-shadow-hover);
  transform: translateY(-3px);
}

.stat-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.stat-card__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  font-family: var(--font-body);
  color: var(--text-heading);
}

/* The card already lifts on hover, so it was promising a click the title alone
   delivered. This grows the title's hit area to the whole card without changing
   what the link is: still one <a> around the cancer name, so the tab stop and
   the accessible name stay "Pancreatic cancer" rather than the card's every
   number read out in one breath, which is what wrapping the <article> in an
   anchor would produce.

   The cost is that text inside the card can no longer be selected -- the
   overlay is what the pointer hits. That is the accepted trade for this
   pattern, and these numbers are repeated on each cancer's own page. */
.stat-card__name a {
  text-decoration: none;
  color: inherit;
}

.stat-card__name a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--card-radius);
}

/* Hovering anywhere on the card tints the title, so the lift reads as "this
   whole thing is the link" rather than as decoration. */
.stat-card:hover .stat-card__name a { color: var(--color-brand); }

.stat-card__multiple {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  color: var(--color-brand);
  line-height: 1;
  white-space: nowrap;
}

.stat-card__multiple span {
  font-size: var(--text-xs);
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  color: var(--text-muted);
  display: block;
  margin-top: var(--space-1);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* Survival comparison bars: one row per stage, both on a shared 0-100 scale so
   the gap is comparable from card to card, which two number tiles never were.
   The track shows where 100% is, which is what lets a bar be read without an
   axis under every card. */
.survival-bars {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  column-gap: var(--space-3);
  row-gap: var(--space-2);
  margin: 0;
}

.survival-bars__label {
  grid-column: 1;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* Ink, not the bar's colour. The bar beside it carries which stage this is;
   colouring the number too doubles the encoding and, at these hues, weakens
   the contrast of the one element that has to stay readable. */
.survival-bars__value {
  grid-column: 2;
  margin: 0;
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: var(--leading-tight);
  color: var(--text-heading);
}

.survival-bars__track {
  grid-column: 1 / -1;
  margin: 0;
  height: var(--stat-bar-height);
  background: var(--stat-bar-track);
  border-radius: 0 var(--stat-bar-radius) var(--stat-bar-radius) 0;
  overflow: hidden;
}

/* The early row's track gets the space; the last one sits flush with the card
   edge so the card does not end in a band of dead air. */
.survival-bars__track:not(:last-child) {
  margin-bottom: var(--space-4);
}

.survival-bars__fill {
  display: block;
  height: 100%;
  /* Square where it leaves zero, rounded at the value. */
  border-radius: 0 var(--stat-bar-radius) var(--stat-bar-radius) 0;
  /* A single-digit percentage is a couple of pixels wide in a card this narrow
     and would round away to nothing. Below this width the bar stops being to
     scale, which is the honest trade against it vanishing entirely. */
  min-width: var(--stat-bar-min-width);
}

.survival-bars__fill--early { background: var(--signal-early); }
.survival-bars__fill--late  { background: var(--signal-late); }

/* Attribution for a whole grid of stat cards. Same type treatment the per-card
   source used, minus the rule above it: it sits under the grid, so it separates
   by position and does not need a border to do it. */
.stat-source-note {
  font-size: var(--text-xs);
  color: var(--text-subtle);
  margin-top: var(--space-6);
  text-align: center;
}

.stat-source-note a { color: inherit; }

/* Big number tiles */
.figure-tile {
  text-align: center;
  padding: var(--space-6) var(--space-4);
}

.figure-tile__value {
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: var(--weight-light);
  line-height: 1;
  letter-spacing: var(--tracking-tighter);
  color: var(--color-brand);
}

.section--inverse .figure-tile__value,
.section--brand .figure-tile__value { color: var(--white); }

.figure-tile__label {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-normal);
}

.section--inverse .figure-tile__label,
.section--brand .figure-tile__label {
  color: color-mix(in srgb, var(--white) 75%, transparent);
}

/* ==========================================================================
   Steps / process
   ========================================================================== */

.steps {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-8);
  counter-reset: step;
}

@media (min-width: 760px) {
  .steps { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
}

/* Two columns: the badge, then everything else. The number used to be absolutely
   positioned above the title, which read as a bullet floating over the step
   rather than as part of it. In-flow grid instead of `position: absolute`,
   because the badge now has to share a row with the title and reserve width from
   it; an out-of-flow circle reserves nothing and the title would run under it. */
.step {
  counter-increment: step;
  margin: 0;
  display: grid;
  grid-template-columns: var(--step-badge-size) 1fr;
  column-gap: var(--space-4);
  row-gap: var(--space-2);
  /* Centred rather than start-aligned: in the four-up desktop layout a title
     often wraps to two lines, and a badge pinned to the first line then sits
     high against the block it labels. */
  align-items: center;
  /* Each step is stretched to the tallest one by the `steps` grid, and auto rows
     absorb that slack by default. Without this, the step with the shortest body
     spreads its two rows down the column and its number stops lining up with the
     numbers beside it. */
  align-content: start;
}

.step::before {
  content: counter(step);
  grid-column: 1;
  grid-row: 1;
  width: var(--step-badge-size);
  height: var(--step-badge-size);
  display: grid;
  place-items: center;
  border-radius: var(--radius-circle);
  background: var(--color-brand);
  color: var(--color-on-brand);
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
}

.step__title {
  grid-column: 2;
  grid-row: 1;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  font-family: var(--font-body);
  /* row-gap owns the space to the body now; a margin here would double it. */
  margin-bottom: 0;
}

/* Column 2, under the title rather than under the badge: the step then reads as
   one indented block instead of two pieces of text starting at different edges. */
.step__body {
  grid-column: 2;
  grid-row: 2;
  font-size: var(--text-base);
  color: var(--text-muted);
}

/* ==========================================================================
   Forms
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--space-2); }

.field__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-heading);
}

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

/* Label for one input inside a group that already carries the real label, e.g.
   "Second choice" under "Three days that work for you". Lighter than
   `.field__label` so the group reads as one question rather than three. */
.field__sublabel {
  display: block;
  margin-block-end: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* The three preferred-date pickers. One column on a phone, where a date input
   is already close to full width and three across would clip the native picker
   affordance. A media query cannot read a custom property, which is why this
   breakpoint is a literal like every other one in this file. */
.date-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}

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

.field__error {
  font-size: var(--text-sm);
  color: var(--color-danger);
  font-weight: var(--weight-medium);
  display: none;
}

.field__error:not(:empty) { display: block; }

.input,
.select,
.textarea {
  width: 100%;
  height: var(--input-height);
  padding-inline: var(--input-padding-x);
  background: var(--input-bg);
  border: var(--input-border);
  border-radius: var(--input-radius);
  font-size: var(--text-base);
  color: var(--text-heading);
  transition: var(--transition-colors),
              box-shadow var(--duration-fast) var(--ease-standard);
}

.textarea {
  height: auto;
  min-height: 6rem;
  padding-block: var(--space-3);
  resize: vertical;
  line-height: var(--leading-normal);
}

.input::placeholder,
.textarea::placeholder { color: var(--text-subtle); }

.input:hover,
.select:hover,
.textarea:hover { border-color: var(--border-color-strong); }

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--input-border-focus);
  box-shadow: var(--shadow-focus);
}

.input[aria-invalid="true"],
.select[aria-invalid="true"] {
  border-color: var(--color-danger);
}

.input[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px var(--color-danger-bg);
}

.select {
  appearance: none;
  /* Inline SVG chevron as a data URI; the CSP allows data: images and this
     avoids an extra request. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%234c5956' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M5 7.5l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  background-size: 1.15rem;
  padding-right: var(--space-10);
}

.field-row {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}

@media (min-width: 560px) {
  .field-row--2 { grid-template-columns: 1fr 1fr; }
}

/* Choice chips: radio/checkbox styled as selectable cards. */
.choice-group {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
}

.choice {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: var(--border-width) solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  transition: var(--transition-colors),
              box-shadow var(--duration-fast) var(--ease-standard);
  font-size: var(--text-base);
}

.choice:hover { border-color: var(--teal-300); background: var(--teal-50); }

.choice__input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.choice__indicator {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  border: var(--border-width-thick) solid var(--border-color-strong);
  border-radius: var(--radius-circle);
  display: grid;
  place-items: center;
  transition: var(--transition-colors);
}

.choice--checkbox .choice__indicator { border-radius: var(--radius-xs); }

.choice__indicator::after {
  content: "";
  width: 0.6rem;
  height: 0.6rem;
  border-radius: inherit;
  background: var(--white);
  transform: scale(0);
  transition: transform var(--duration-fast) var(--ease-spring);
}

.choice__input:checked ~ .choice__indicator {
  background: var(--color-brand);
  border-color: var(--color-brand);
}

.choice__input:checked ~ .choice__indicator::after { transform: scale(1); }

.choice:has(.choice__input:checked) {
  border-color: var(--color-brand);
  background: var(--color-brand-subtle);
  box-shadow: var(--shadow-focus);
}

.choice__input:focus-visible ~ .choice__indicator {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

.choice__label { font-weight: var(--weight-medium); color: var(--text-heading); }
.choice__desc { display: block; font-size: var(--text-sm); color: var(--text-muted); font-weight: var(--weight-regular); }

/* List variant: one question per line, no card.
   The chip grid above suits a short mutually-exclusive choice (two sex-at-birth
   radios). The screener is ten independent yes/no questions, and rendering them
   as ten filled boxes turns a single read-down-the-page into ten separate
   decisions. Rows with a hairline between them scan in one pass. */
.choice-group--list {
  display: block;
  border-top: var(--border-width) solid var(--border-color-subtle);
}

.choice-group--list .choice {
  width: 100%;
  align-items: flex-start;
  border: 0;
  border-bottom: var(--border-width) solid var(--border-color-subtle);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: var(--space-4) var(--space-2);
}

/* The row is the hit area, so it still needs a hover state; it just should not
   grow a border and shift the rows below it. */
.choice-group--list .choice:hover {
  border-color: var(--border-color-subtle);
  background: var(--color-brand-subtle);
}

/* Checked is carried by the checkbox and a faint wash, not by a box outline. */
.choice-group--list .choice:has(.choice__input:checked) {
  border-color: var(--border-color-subtle);
  background: var(--color-brand-subtle);
  box-shadow: none;
}

.choice-group--list .choice__indicator { margin-top: 0.15rem; }

/* Consent checkbox: plain, not a card. */
.consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-normal);
  cursor: pointer;
}

.consent input[type="checkbox"] {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  flex-shrink: 0;
  accent-color: var(--color-brand);
  cursor: pointer;
}

/* ==========================================================================
   Multi-step funnel
   ========================================================================== */

.funnel {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  border: var(--border-width) solid var(--border-color-subtle);
  padding: clamp(var(--space-6), 4vw, var(--space-10));
}

/* Progress bar doubles as the step navigation. Each segment is a real button,
   enabled for any step already reached, so going back to change an answer does
   not mean clicking Back three times. */
.funnel__progress {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-bottom: var(--space-8);
  padding: 0;
  list-style: none;
}

.funnel__progress-step {
  flex: 1 1 0;
  min-width: 0;
}

.funnel__progress-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

.funnel__progress-btn:disabled { cursor: default; }

.funnel__progress-btn::before {
  content: "";
  display: block;
  height: 0.3rem;
  border-radius: var(--radius-pill);
  background: var(--ink-100);
  transition: background-color var(--duration-base) var(--ease-standard);
}

.funnel__progress-step[data-state="active"] .funnel__progress-btn::before,
.funnel__progress-step[data-state="done"] .funnel__progress-btn::before {
  background: var(--color-brand);
}

.funnel__progress-btn:not(:disabled):hover::before { background: var(--teal-300); }

.funnel__progress-btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-xs);
}

.funnel__progress-label {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--text-subtle);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.funnel__progress-step[data-state="active"] .funnel__progress-label,
.funnel__progress-step[data-state="done"] .funnel__progress-label {
  color: var(--color-brand);
}

/* Four labels do not fit side by side on a phone. The bars still do, and the
   step count inside each fieldset already says where you are. */
@media (max-width: 40rem) {
  .funnel__progress-label { display: none; }
}

.funnel__step-count {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-subtle);
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-3);
}

/* The wizard is gated on `data-enhanced`, which funnel.js sets only after it has
   wired up the nav. Keying this on `.no-js` instead would strand anyone whose
   browser ran the head script but failed to fetch funnel.js: they would see one
   step and two dead buttons. The default below is the single-page form, which
   posts and validates server-side no matter what the client does. */
.funnel__step { display: block; }
.funnel__step + .funnel__step { margin-top: var(--space-10); }
.funnel__submit-fallback { display: block; }

.funnel[data-enhanced="true"] .funnel__step { display: none; }
.funnel[data-enhanced="true"] .funnel__step[data-active="true"] { display: block; }
.funnel[data-enhanced="true"] .funnel__step + .funnel__step { margin-top: 0; }
.funnel[data-enhanced="true"] .funnel__submit-fallback { display: none; }

/* Higher specificity than the `display: flex` on each, so source order is free. */
.funnel:not([data-enhanced="true"]) .funnel__progress,
.funnel:not([data-enhanced="true"]) .funnel__nav { display: none; }

.funnel__title {
  font-size: var(--text-2xl);
  margin-bottom: var(--space-2);
}

.funnel__subtitle {
  color: var(--text-muted);
  margin-bottom: var(--space-6);
  font-size: var(--text-base);
}

.funnel__nav {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: var(--border-width) solid var(--border-color-subtle);
}

/* The forward button hugs the right edge whether or not Back is there to push
   it. `space-between` did that only from step 2 on: with Back hidden on step 1
   the sole child had nothing to be spaced against and sat on the left, so the
   button moved sideways under you the first time you advanced. */
.funnel__nav [data-funnel-next],
.funnel__nav [data-funnel-submit] {
  margin-inline-start: auto;
}

.funnel__alert {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-danger-bg);
  color: var(--red-700);
  font-size: var(--text-sm);
  margin-bottom: var(--space-6);
}

.funnel__alert:empty { display: none; }

/* ==========================================================================
   Checkout
   ========================================================================== */

/* The card fields are Stripe's iframe, which brings its own typography and
   spacing (checkout.js passes the tokens across, since the frame cannot read
   this stylesheet). What is left to style here is the box it sits in and the
   two states around it. */
.checkout__element {
  min-height: 14rem;
  margin-top: var(--space-6);
}

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

.checkout__loading[hidden] { display: none; }

/* The wider packages, offered once, immediately above the card fields. An
   evenly bordered block and never a tinted panel with an accent stripe: this
   sits between a visitor and a payment form, and anything that reads as an
   advert dropped onto the page is exactly what does not belong there. See the
   note on `.callout`. */
.upsell {
  border: var(--card-border);
  border-radius: var(--card-radius);
  padding: var(--space-6);
}

.upsell__list {
  list-style: none;
  padding: 0;
  margin-top: var(--space-2);
}

.upsell__item {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-4);
}

.upsell__item + .upsell__item { border-top: var(--card-border); }

.upsell__name {
  font-weight: var(--weight-medium);
  color: var(--text-heading);
}

/* ==========================================================================
   Location cards & finder
   ========================================================================== */

.location-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--border-color-subtle);
  border-radius: var(--card-radius);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  box-shadow: var(--card-shadow);
  transition: box-shadow var(--duration-base) var(--ease-standard),
              border-color var(--duration-base) var(--ease-standard);
}

.location-card:hover {
  box-shadow: var(--card-shadow-hover);
  border-color: var(--teal-200);
}

.location-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.location-card__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--text-heading);
  font-family: var(--font-body);
}

.location-card__name a { color: inherit; text-decoration: none; }
.location-card__name a:hover { color: var(--color-brand); }

.location-card__distance {
  font-size: var(--text-sm);
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}

.location-card__address {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-style: normal;
  line-height: var(--leading-normal);
}

.location-card__services {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-3);
}

.tag {
  font-size: var(--text-2xs);
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--ink-50);
  color: var(--ink-600);
  border: var(--border-width) solid var(--border-color-subtle);
  white-space: nowrap;
}

.tag--brand {
  background: var(--color-brand-subtle);
  color: var(--teal-700);
  border-color: var(--teal-200);
  font-weight: var(--weight-semibold);
}

/* --- ZIP finder + centers map ------------------------------------------- */

.zip-finder {
  max-width: 34rem;
  margin-inline: auto;
}

.zip-finder__label {
  display: block;
  text-align: center;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}

/* Inside `locator` the form is already a narrow column, so it neither needs the
   centring max-width nor reads well centred against a left-aligned column edge.
   Only above the stack breakpoint: while stacked it is centred like the rest. */
@media (min-width: 760px) {
  .zip-finder--inline {
    max-width: none;
    margin-inline: 0;
  }

  .zip-finder--inline .zip-finder__label {
    text-align: left;
    font-size: var(--text-md);
  }
}

.zip-finder__row {
  display: flex;
  gap: var(--space-3);
  /* Wraps to stacked full-width controls on a narrow screen rather than
     squeezing a 5-digit field down to nothing beside the button. */
  flex-wrap: wrap;
}

.zip-finder__input {
  flex: 1 1 12rem;
  font-variant-numeric: tabular-nums;
}

.zip-finder__row .btn { flex: 0 1 auto; }

@media (max-width: 30rem) {
  .zip-finder__row .btn { flex: 1 1 100%; }
}

/* ZIP form beside the map. Stacked by default so the form (the thing that
   actually does something) comes first on a phone, where the map is only
   orientation. Side by side from 760px, matching the other two-column layouts
   in this file. */
.locator {
  display: grid;
  gap: var(--space-8);
  /* Narrower than the container: at full width the pair drifts apart until the
     form and the map stop reading as one control. */
  max-width: 60rem;
  margin-inline: auto;
}

/* `1fr` means minmax(auto, 1fr), and that auto floor is the item's min-content
   width. Without this the map column cannot shrink past the SVG's intrinsic
   width and overflows instead, which bites at the narrow end of the
   two-column range, not on a phone where the two are stacked. */
.locator > * {
  min-width: 0;
}

@media (min-width: 760px) {
  .locator {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-10);
    align-items: center;
  }
}

.centers-map {
  margin: 0;
}

.centers-map__svg {
  display: block;
  width: 100%;
  max-width: var(--map-max-width);
  height: auto;
  margin-inline: auto;
}

.centers-map__land {
  fill: var(--map-land);
  stroke: var(--map-border);
  stroke-width: var(--map-border-width);
  stroke-linejoin: round;
}

/* A pin is four overlapping shapes that have to react as one thing, so the pin
   group holds the whole state as custom properties and each shape just reads
   the one it cares about. That way "pointed at" is defined once, at the bottom
   of this block, instead of once per shape per trigger. */
.centers-map__pin {
  --pin-dot-radius: var(--map-dot-radius);
  --pin-dot-fill: var(--map-dot);
  --pin-dot-stroke: var(--map-land);
  --pin-halo-radius: 0;
  --pin-halo-opacity: 0;
  --pin-label-opacity: 0;
}

/* Outside the current result set: still a real center and still clickable, so
   it keeps its full hover behaviour and only loses emphasis at rest. */
.centers-map__pin.is-dim {
  --pin-dot-fill: var(--map-dot-dim);
  --pin-dot-stroke: transparent;
}

.centers-map__pin.is-active {
  --pin-dot-radius: var(--map-dot-radius-active);
}

.centers-map__pin a {
  cursor: pointer;
  /* The UA focus ring is a box around the pin's bounding shape, and on a dot
     near the coastline half of it renders outside the viewBox and is clipped.
     The pop, the ring, and the name are the focus indicator instead: three
     simultaneous changes, none of which depend on being able to draw outside
     the map. */
  outline: none;
}

.centers-map__dot {
  r: var(--pin-dot-radius);
  fill: var(--pin-dot-fill);
  /* Dots overlap heavily in dense metros. A stroke in the land colour keeps a
     cluster readable as several centers rather than one blob. */
  stroke: var(--pin-dot-stroke);
  stroke-width: 1.2;
  /* `r` rather than a transform: scaling a circle scales it about the SVG
     origin, not its own centre, so it would slide across the map as it grew.
     --ease-spring overshoots and settles, which is what makes the growth read
     as a pop rather than an inflate. */
  transition: r var(--duration-base) var(--ease-spring),
              fill var(--duration-fast) var(--ease-standard);
}

/* `pointer-events: all` rather than a transparent fill: it makes the circle
   hit-testable without painting anything, so there is no chance of a stray
   colour appearing over the map. */
.centers-map__hit {
  fill: none;
  r: var(--map-hit-radius);
  pointer-events: all;
}

.centers-map__halo {
  r: var(--pin-halo-radius);
  fill: var(--map-halo);
  opacity: var(--pin-halo-opacity);
  pointer-events: none;
  /* Slower than the dot and easing out, so the ring is still opening as the dot
     lands. Reversed together they collapse without a straggler. */
  transition: r var(--duration-slow) var(--ease-out),
              opacity var(--duration-base) var(--ease-standard);
}

.centers-map__pin-label {
  font-family: var(--font-body);
  fill: var(--map-label-active);
  font-weight: var(--weight-semibold);
  /* Draw the stroke under the fill so it reads as a halo, letting the name stay
     legible where it crosses dots or the coastline instead of needing a
     background rect. A hovered name lands in the busiest part of the map by
     definition, so the halo is heavy. */
  paint-order: stroke fill;
  stroke: var(--map-label-halo);
  stroke-width: var(--map-label-halo-width-active);
  stroke-linejoin: round;
  pointer-events: none;
  opacity: var(--pin-label-opacity);
  transition: opacity var(--duration-fast) var(--ease-standard);
}

/* The one definition of an engaged pin, for pointer and keyboard alike. Last in
   the block so it outranks .is-dim and .is-active, which match with the same
   specificity.

   No `@media (hover: hover)` guard, unlike the earlier version of this file:
   that existed because a stuck `:hover` after a tap would strand one dot
   enlarged forever. Now that every dot is a link, a tap navigates, so the stuck
   state lasts exactly as long as the page does. */
.centers-map__pin:hover,
.centers-map__pin:focus-within {
  --pin-dot-radius: var(--map-dot-radius-hover);
  --pin-dot-fill: var(--map-dot-active);
  --pin-dot-stroke: var(--map-land);
  --pin-halo-radius: var(--map-halo-radius-hover);
  --pin-halo-opacity: var(--map-halo-opacity);
  --pin-label-opacity: 1;
}

.centers-map__caption {
  margin-top: var(--space-4);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* ==========================================================================
   Pricing
   ========================================================================== */

/* The three packages, side by side. Its own grid rather than `.grid--3`,
   whose 280px minimum lets a five-figure amount and a body-region list wrap
   into each other before the column count drops. */
.price-grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
}

.price-card {
  background: var(--color-surface);
  border: var(--border-width-thick) solid var(--color-brand);
  border-radius: var(--radius-xl);
  padding: clamp(var(--space-6), 2.5vw, var(--space-8));
  box-shadow: var(--shadow-lg);
  position: relative;
  /* Column so `__foot` can claim the leftover height. */
  display: flex;
  flex-direction: column;
}

/* Every package except the recommended one. Three cards wearing the same brand
   border and drop shadow read as three competing headlines; turning two of them
   down is what makes the third one a recommendation. */
.price-card--quiet {
  border: var(--card-border);
  box-shadow: var(--card-shadow);
}

/* Pins the button to the bottom edge, so cards holding different numbers of
   body regions still line their CTAs up on one row. */
.price-card__foot {
  margin-top: auto;
  padding-top: var(--space-6);
}

.price-card__ribbon {
  position: absolute;
  top: 0;
  right: var(--space-8);
  transform: translateY(-50%);
}

.price-card__amount {
  font-family: var(--font-display);
  font-size: var(--text-5xl);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-tighter);
  color: var(--text-heading);
  line-height: 1;
}

.price-card__period {
  font-size: var(--text-base);
  color: var(--text-muted);
  font-family: var(--font-body);
  letter-spacing: var(--tracking-normal);
}

.check-list {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.check-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--text-base);
  margin: 0;
}

.check-list li::before {
  content: "";
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  margin-top: 0.2rem;
  border-radius: var(--radius-circle);
  background: var(--color-brand-subtle);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%230f6b62' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 10.5l3.5 3.5L15 7'/%3E%3C/svg%3E");
  background-size: 0.85rem;
  background-repeat: no-repeat;
  background-position: center;
}

.check-list--excluded li::before {
  background: var(--ink-100);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23869390' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 6l8 8M14 6l-8 8'/%3E%3C/svg%3E");
  background-size: 0.7rem;
  background-repeat: no-repeat;
  background-position: center;
}

.check-list--excluded li { color: var(--text-muted); }

/* ==========================================================================
   Accordion (FAQ)
   ========================================================================== */

.accordion {
  border-top: var(--border-width) solid var(--border-color-subtle);
}

.accordion__item {
  border-bottom: var(--border-width) solid var(--border-color-subtle);
}

.accordion__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) 0;
  cursor: pointer;
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--text-heading);
  list-style: none;
}

.accordion__item summary::-webkit-details-marker { display: none; }

.accordion__item summary::after {
  content: "";
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%230f6b62' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M10 4v12M4 10h12'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  transition: transform var(--duration-base) var(--ease-out);
}

.accordion__item[open] summary::after { transform: rotate(135deg); }

.accordion__body {
  padding-bottom: var(--space-5);
  color: var(--text-muted);
  max-width: var(--container-prose);
}

/* ==========================================================================
   Callouts & disclosure
   ========================================================================== */

/* No accent stripe down the side. An evenly bordered block reads as part of
   the page; a tinted panel with a coloured bar reads as a template widget
   dropped on top of it. Emphasis comes from the title and the border weight. */
.callout {
  padding: var(--space-5);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--border-color);
  background: var(--color-surface);
  font-size: var(--text-base);
  color: var(--text-body);
}

.callout--warning {
  border-color: var(--border-color-strong);
  background: var(--color-surface-sunken);
}

.callout__title {
  font-weight: var(--weight-semibold);
  color: var(--text-heading);
  margin-bottom: var(--space-2);
  font-size: var(--text-base);
}

.disclosure {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-normal);
}

.disclosure a { color: var(--text-muted); }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  margin-top: auto;
  background: var(--teal-950);
  color: color-mix(in srgb, var(--white) 62%, transparent);
  padding-block: var(--space-16) var(--space-8);
  font-size: var(--text-sm);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-10);
  grid-template-columns: 1fr;
  margin-bottom: var(--space-12);
}

@media (min-width: 760px) {
  .site-footer__grid { grid-template-columns: 1.4fr repeat(2, 1fr); }
}

.site-footer h2 {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--teal-200);
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-4);
  font-family: var(--font-body);
}

.site-footer ul { list-style: none; padding: 0; }
.site-footer li { margin-bottom: var(--space-2); }

.site-footer a {
  color: color-mix(in srgb, var(--white) 72%, transparent);
  text-decoration: none;
}

.site-footer a:hover { color: var(--white); text-decoration: underline; }

.site-footer__bottom {
  border-top: var(--border-width) solid color-mix(in srgb, var(--white) 12%, transparent);
  padding-top: var(--space-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  align-items: center;
  font-size: var(--text-xs);
  color: color-mix(in srgb, var(--white) 50%, transparent);
}

/* Lays the legal links out in a row in the bottom bar. The `li` override is
   load-bearing: `.site-footer li` adds a bottom margin for the stacked nav
   columns, which reads as a vertical nudge once the items sit side by side. */
.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.site-footer__legal li { margin-bottom: 0; }

.site-footer__disclaimer {
  font-size: var(--text-2xs);
  line-height: var(--leading-normal);
  color: color-mix(in srgb, var(--white) 48%, transparent);
  margin-bottom: var(--space-6);
}

/* ==========================================================================
   Reveal-on-scroll
   ========================================================================== */

/* Content is visible by default and only hidden once main.js has added
   `reveal-ready` to <html>, immediately before it starts observing. Hiding on
   `.no-js` removal instead would blank out most of the page for anyone whose
   browser ran the head script but never received main.js. */
.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--duration-slow) var(--ease-out),
              transform var(--duration-slow) var(--ease-out);
}

.reveal-ready .reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal-ready .reveal { opacity: 1; transform: none; transition: none; }
}

/* ==========================================================================
   Tables
   ========================================================================== */

.table-wrap {
  overflow-x: auto;
  border: var(--border-width) solid var(--border-color-subtle);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  min-width: 32rem;
}

.table th,
.table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: var(--border-width) solid var(--border-color-subtle);
}

.table th {
  font-weight: var(--weight-semibold);
  color: var(--text-heading);
  background: var(--color-surface-sunken);
  white-space: nowrap;
}

.table tbody tr:last-child td { border-bottom: none; }
.table td.numeric,
.table th.numeric { text-align: right; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Empty state
   ========================================================================== */

.empty-state {
  text-align: center;
  padding: var(--space-16) var(--space-6);
  color: var(--text-muted);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-lg);
}

.empty-state__title {
  font-size: var(--text-xl);
  color: var(--text-heading);
  margin-bottom: var(--space-2);
}
