/**
 * PRD §3 design tokens.
 *
 * VALUES COME FROM design/rapater-calculator.html, not from §3.1's table.
 * The two disagreed: §3.1 documented a light app surface with purple #7C3AED,
 * while every design file — and the deployed landing page — is dark with pink
 * #FF4D82. Resolved 2026-08-06 in favour of the design files, and §3.1/§3.2
 * were rewritten to match. Prompt 1.3 names the prototype as the visual truth,
 * and shape (§3.4) and type (§3.3) already agreed with it exactly.
 *
 * THE TOKEN NAMES ARE UNCHANGED, including `--purple`, which now holds a pink.
 * That reads oddly and is deliberate: the name is a role ("the one accent
 * colour"), not a hue, and renaming it would touch every rule in every design
 * file for no behavioural gain. If it is ever renamed, rename it everywhere at
 * once — a half-renamed accent is worse than a misnamed one.
 *
 * §3.5 forbids: black backgrounds, neon or acid accents, chart decoration,
 * rocket/fire/money-bag iconography, emoji, exclamation marks, animated
 * counters, grey drop shadows, and more than one accent beyond the semantic
 * three. Nothing below introduces any of them; nor should anything that
 * imports this file.
 */

:root {
  /* --- Surface and type colour ------------------------------------------ */
  --ink: #ffffff;        /* headings, primary text */
  --body: #b9aecb;       /* body copy */
  --muted: #877c99;      /* uppercase labels */
  --faint: #6e6483;      /* hints, empty states */
  --line: #33264a;       /* 1px borders and rules — never heavier (§3.4) */
  --card: #221831;
  --tint: rgba(255, 255, 255, 0.04); /* inset boxes inside cards */

  /* --- The one accent --------------------------------------------------- */
  --purple: #ff4d82;                        /* every neutral figure, primary buttons */
  --purple-soft: rgba(255, 77, 130, 0.14);  /* soft button fill, step numerals */
  --purple-deep: #ff7ba3;                   /* text on soft accent */

  /* --- The semantic three (§3.5 permits exactly these beyond the accent) - */
  --red: #ff5c7a;
  --red-soft: rgba(255, 92, 122, 0.1);
  --green: #2ed3a0;
  --green-soft: rgba(46, 211, 160, 0.11);
  --amber: #f5a524;
  --amber-soft: rgba(245, 165, 36, 0.1);

  /* --- Shape (§3.4) ------------------------------------------------------ */
  --r-pill: 999px;
  --r-card: 16px;
  --r-verdict: 20px;
  --r-inset: 14px;
  --r-panel: 26px;

  /* --- Depth (§3.4, restated for the dark surface) ----------------------- */
  /* §3.4's light-surface shadows were purple-tinted because a light card
     needs a coloured shadow to read as lifted. On #150F1E a tinted shadow is
     invisible, so the card uses a deep neutral and the accent glow is carried
     by the primary button instead. Same intent, inverted surface. */
  --shadow-card: none;
  --shadow-verdict: 0 30px 70px rgba(0, 0, 0, 0.45);
  --shadow-primary: 0 8px 26px rgba(255, 77, 130, 0.3);
  --shadow-primary-hover: 0 12px 32px rgba(255, 77, 130, 0.42);

  /* --- Type scale (§3.3) ------------------------------------------------- */
  --t-title: 38px;
  --t-section: 22px;
  --t-dir: 30px;      /* direction + symbol in the verdict header */
  /* Supporting figures INSIDE the verdict card — the dose row and the
     account-risk row. 20px, not the design file's 26px, and this is the one
     considered departure from it (2026-08-06).
     WHY: §6 item 3 requires the loss to be "the largest element on the page",
     and at 26px it was not reading that way. Four figures in a row are read as
     one block, and four at 26px collectively out-weigh a single 52px hero
     however large that hero is. Shrinking the supporting row was preferred to
     bumping the hero because it leaves the design file's 52px exactly as drawn.
     ONE TOKEN ON PURPOSE: the dose and account-risk figures are the same class
     of thing — detail that sits below the loss — so they move together. Two
     tokens would be two names for one concept, and the next person to change
     it would have to find both.
     SETTLED 2026-08-06. Chosen against the card in isolation, then re-checked
     in a browser against the full page — header, three 30px rules figures, the
     card below them. The loss still dominates. If a future page changes that
     composition, this is the number to re-check first. */
  --t-stat: 20px;
  --t-hero: 52px;     /* the loss — the largest element on the page */
  --t-lede: 17px;
  --t-body: 16px;
  --t-small: 14px;
  --t-label: 12px;    /* uppercase label */
}

/**
 * The page. Two radial washes over near-black, from the design file — the
 * gradient §3 describes as doing "the job marketing needs", carried into the
 * app surface now that both are dark.
 */
body {
  font-family: 'Poppins', system-ui, sans-serif;
  background:
    radial-gradient(900px 620px at 85% -8%, rgba(255, 77, 130, 0.18), transparent 60%),
    radial-gradient(760px 560px at -12% 55%, rgba(139, 92, 246, 0.14), transparent 60%),
    #150f1e;
  background-attachment: fixed;
  color: var(--ink);
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/**
 * §3.3: "Every number carries font-variant-numeric: tabular-nums. No
 * exceptions — figures must not jitter when they update."
 *
 * Applied by element rather than by class, so a figure cannot be added without
 * it. The stop slider (§6 item 4) re-renders the whole card on every input
 * event, which is where a proportional digit would show as a twitch.
 */
.num,
input[inputmode='decimal'],
td,
th {
  font-variant-numeric: tabular-nums;
}

/** §3.3 "Small" — 14px/400/--body. */
.small {
  font-size: var(--t-small);
  color: var(--body);
}

/** §3.3: an uppercase label sits above every number. This is that label. */
.cap {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--purple);
}

/**
 * `hidden` MUST hide, whatever else a component says.
 *
 * The UA stylesheet's `[hidden] { display: none }` is beaten by any author rule
 * that sets `display` — and `.warn` sets `display: flex`. On 2026-08-06 that
 * put all eight §10.3 warnings on a live card at once, including two that
 * cannot fire in Phase 1 at all, so a reader was told their 1% risk was "above
 * 5%" and that a trade breached a cap no code had evaluated.
 *
 * Declared once, globally, with `!important`, because the failure is silent and
 * per-component: any future component that sets `display` re-opens it, and
 * nothing in a unit test can see it. This is the rule that makes `hidden`
 * mean hidden.
 */
[hidden] {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}
