/* ============================================================================
   bearing.css — the Bearing web design system
   Companion document: apps/uk-net-worth-tracker/docs/WEBSITE_DESIGN.md

   Three rules this file exists to hold:
     1. No box-shadow. Anywhere. Separation is a hairline border + a surface
        shift. The only ring in the file is the focus outline. (DS §5.1)
     2. `accent` is ONE token whose value changes with theme. It is never two
        tokens where one is fixed. That bug cost the app a blocking finding
        (DS §11.1) and the shape of it is easy to reintroduce in CSS.
     3. No font-weight above 600. Authority is size and tracking. (DS §3)
   ========================================================================= */

/* ---- 1. Fonts ------------------------------------------------------------
   Archivo + Instrument Sans ship as WOFF2 (OFL 1.1, no Reserved Font Name).
   IBM Plex Mono ships as the UNMODIFIED TTF: OFL defines a format change as a
   Modified Version, and IBM reserves the name "Plex", so converting it would
   engage the RFN clause. See WEBSITE_DESIGN.md §4.2.                       */

@font-face {
  font-family: 'Archivo';
  src: url('../fonts/Archivo-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('../fonts/InstrumentSans-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('../fonts/InstrumentSans-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/IBMPlexMono-Medium.ttf') format('truetype');
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ---- 2. Tokens -----------------------------------------------------------
   Every colour is defined on bare :root with its LIGHT value, then overridden
   in the dark blocks. No colour has its only definition inside a dark block.
   (DS §2.6)                                                                */

:root {
  /* Colour — values are byte-identical to THEME_SPEC.md §2.1 */
  --ink:            #191B1C;
  --ink-secondary:  #52585A;
  --ink-quiet:      #666D70;
  --ink-faint:      #838A8E;   /* non-text only — never carries meaning */
  --bone:           #EFEEEA;
  --surface:        #FBFBF9;
  --line:           #DDDCD6;
  --line-quiet:     #EAE9E4;
  --accent:         #14513F;
  --accent-subtle:  #DCE9E3;
  --accent-on-fill: #F4FAF7;
  --destructive:    #992D1F;

  /* Type families */
  --font-figure: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-ui:     'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:   'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Type scale — FIXED sizes, in rem so a browser font-size preference scales
     them. This is the web's substitute for Dynamic Type. (WD §3.2)         */
  --t-reading:  1.0625rem;  /* 17px — explainer + policy prose only          */
  --t-body:     0.9375rem;  /* 15px — everything else                        */
  --t-button:   1rem;       /* 16px                                          */
  --t-row:      0.9375rem;  /* 15px                                          */
  --t-row-sub:  0.75rem;    /* 12px                                          */
  --t-figure-row: 1rem;     /* 16px                                          */
  --t-delta:    0.8125rem;  /* 13px                                          */
  --t-label:    0.6875rem;  /* 11px — dataLabel / chipLabel / microNote      */

  /* Type scale — FLUID. Display size is governed by the layout, not the eye,
     so it tracks the viewport. Floors reproduce the app's iOS pt exactly at
     a 360px viewport; ceilings are set at 1440px. (WD §3.3)                 */
  --t-hero:     clamp(2.75rem, 2.10rem + 2.90vw, 4.5rem);   /* 44 → 72px */
  --t-figure-l: clamp(2rem,    1.60rem + 1.80vw, 3rem);     /* 32 → 48px */
  --t-page:     clamp(1.5rem,  1.15rem + 1.60vw, 2.5rem);   /* 24 → 40px */
  --t-section:  clamp(1.25rem, 1.10rem + 0.70vw, 1.5rem);   /* 20 → 24px */
  --t-sheet:    1.0625rem;  /* 17px */

  /* Tracking — THEME_SPEC §4.3, percentages as em */
  --tr-hero:     -0.045em;
  --tr-figure-l: -0.040em;
  --tr-figure-m: -0.030em;
  --tr-figure-r: -0.022em;
  --tr-page:     -0.032em;
  --tr-section:  -0.022em;
  --tr-row:      -0.005em;
  --tr-label:     0.13em;
  --tr-chip:      0.10em;
  --tr-delta:     0.01em;

  /* Spacing — the APOS 8pt scale, unchanged, expressed in rem */
  --s-xxs:  0.125rem;  /*  2 */
  --s-xs:   0.25rem;   /*  4 */
  --s-sm:   0.5rem;    /*  8 */
  --s-md:   0.75rem;   /* 12 */
  --s-lg:   1rem;      /* 16 */
  --s-xl:   1.5rem;    /* 24 */
  --s-xxl:  2rem;      /* 32 */
  --s-xxxl: 3rem;      /* 48 */
  --s-x4:   4rem;      /* 64 — web only, section rhythm (WD §5.3) */
  --s-x5:   6rem;      /* 96 — web only, major page break        */

  /* Radius — Radius scale + the two Bearing extensions */
  --r-sm:      0.25rem;   /*  4 */
  --r-md:      0.5rem;    /*  8 — chip, inline marker */
  --r-lg:      0.75rem;   /* 12 — icon tile, small button */
  --r-control: 0.875rem;  /* 14 — BearingRadius.control */
  --r-xl:      1rem;      /* 16 — card */
  --r-sheet:   1.5rem;    /* 24 — BearingRadius.sheet */

  /* Layout */
  --measure: 32rem;      /* 512px = 66.9 characters at 17px (WD §5.1) */
  --wide:    68rem;      /* 1088px page container                     */
  --rail:    13.75rem;   /* 220px contents rail                       */
  --gutter:  var(--s-xl);/* 24px, stepping up at 640/1024 below       */
  --touch:   2.75rem;    /* 44px click-target floor                   */

  /* Motion — shared tokens, no web-only additions. durationSlow unused. */
  --d-fast:   0.15s;
  --d-normal: 0.25s;
  --ease: cubic-bezier(0.2, 0, 0.2, 1);

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink:            #F0F0EE;
    --ink-secondary:  #A7AEB0;
    --ink-quiet:      #858C8E;
    --ink-faint:      #757D7F;
    --bone:           #191B1C;
    --surface:        #222526;
    --line:           #323637;
    --line-quiet:     #292D2E;
    --accent:         #6FC0A3;
    --accent-subtle:  #1B3B32;
    --accent-on-fill: #0E1F1A;
    --destructive:    #E39387;
  }
}

:root[data-theme="dark"] {
  --ink:            #F0F0EE;
  --ink-secondary:  #A7AEB0;
  --ink-quiet:      #858C8E;
  --ink-faint:      #757D7F;
  --bone:           #191B1C;
  --surface:        #222526;
  --line:           #323637;
  --line-quiet:     #292D2E;
  --accent:         #6FC0A3;
  --accent-subtle:  #1B3B32;
  --accent-on-fill: #0E1F1A;
  --destructive:    #E39387;
}

@media (min-width: 40rem) { :root { --gutter: var(--s-xxl); } }
@media (min-width: 64rem) { :root { --gutter: var(--s-xxxl); } }

/* ---- 3. Reset and base ------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bone);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: 1.6;
  font-variant-numeric: tabular-nums;   /* DS §3.2 — every column, always */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-underline-offset: 0.18em;
}

::selection { background: var(--accent-subtle); color: var(--ink); }  /* 13.84 / 10.71 */

img, svg { max-width: 100%; height: auto; display: block; }

/* The UA stylesheet renders <strong>/<b> at 700. No weight above 600 ships —
   authority is size and tracking. (DS §3) This has to be a global reset, not
   a per-block rule, or the next <strong> outside .prose reintroduces it.    */
strong, b { font-weight: 600; }

/* Focus — 2px accent ring, 2px offset. 7.94 light / 8.02 dark against bone,
   over the 3.0 floor for a focus indicator. (DS §12.3)                     */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

.skip-link {
  position: absolute; left: var(--s-sm); top: var(--s-sm);
  transform: translateY(-200%);
  background: var(--ink); color: var(--bone);
  padding: var(--s-md) var(--s-lg);
  border-radius: var(--r-control);
  font-size: var(--t-button); font-weight: 600;
  text-decoration: none; z-index: 20;
}
.skip-link:focus { transform: translateY(0); }

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

/* `figure-hero`, `figure-medium` and `chip--accent` are defined but not used by
   any page today. They are carried roles from THEME_SPEC.md §4.1–4.2 and
   DESIGN_STANDARDS.md §7.4, kept so the next page that needs a hero figure or
   an accent chip reaches for the token instead of reinventing it. Deliberate,
   not residue. */

/* ---- 4. Type roles ------------------------------------------------------
   Container rules below (`:where(.card) p`, `:where(.prose) p`) are written
   with :where() so their specificity is 0,0,1. A role class here is 0,1,0 and
   always wins. Written as plain `.card p` it is 0,1,1, which silently beat
   `.figure-large` and rendered a 48px hero figure at 15px.                  */

.figure-hero, .figure-large, .figure-medium, .figure-row {
  font-family: var(--font-figure);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1.02;
  color: var(--ink);                 /* never accent — DS §0 */
}
.figure-hero   { font-size: var(--t-hero);     letter-spacing: var(--tr-hero); }
.figure-large  { font-size: var(--t-figure-l); letter-spacing: var(--tr-figure-l); }
.figure-medium { font-size: 1.25rem;           letter-spacing: var(--tr-figure-m); }
.figure-row    { font-size: var(--t-figure-row); letter-spacing: var(--tr-figure-r); }

h1, .page-title {
  font-family: var(--font-figure); font-weight: 500;
  font-size: var(--t-page); letter-spacing: var(--tr-page);
  line-height: 1.1; text-wrap: balance;
}
h2, .section-title {
  font-family: var(--font-figure); font-weight: 500;
  font-size: var(--t-section); letter-spacing: var(--tr-section);
  line-height: 1.2; text-wrap: balance;
}
h3, .sheet-title {
  font-family: var(--font-figure); font-weight: 500;
  font-size: var(--t-sheet); letter-spacing: var(--tr-section);
  line-height: 1.3;
}

/* DataLabel — mono, uppercase, +13%. Permitted ONLY where it names the data
   beneath it and its removal would lose information. (DS §3.3)             */
.data-label {
  display: block;
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--ink-quiet);
}
.data-label--row {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-sm);
}

.micro {
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: 0;
  color: var(--ink-quiet);
}
.delta {
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-delta); letter-spacing: var(--tr-delta);
  font-variant-numeric: tabular-nums;
  color: var(--ink-secondary);
}

.lede    { font-size: var(--t-reading); color: var(--ink-secondary); line-height: 1.55; }
:where(.prose) p { font-size: var(--t-reading); color: var(--ink-secondary); line-height: 1.65; margin-bottom: var(--s-lg); }
:where(.prose) p:last-child { margin-bottom: 0; }
:where(.prose) strong { font-weight: 600; color: var(--ink); }

/* LegalNote — DS §7.1 / §11.5. Defined, so its styling is deliberate. */
.legal-note {
  font-size: var(--t-body); color: var(--ink-quiet); line-height: 1.55;
  border-top: 1px solid var(--line-quiet);
  padding-top: var(--s-lg); margin-top: var(--s-xl);
}
.legal-note p + p { margin-top: var(--s-md); }

a { color: var(--accent); text-decoration-thickness: 1px; }   /* 7.94 / 8.02 */
a:hover { text-decoration-thickness: 2px; }

/* ---- 5. Layout --------------------------------------------------------- */

.page   { max-width: var(--wide); margin: 0 auto; padding: 0 var(--gutter); }

/* The measure CENTRES. A 512px column pinned to the left edge of a 1088px
   container is not calm spacing, it is an unfinished layout. Where a section
   wants the asymmetry it asks for it (.hero-grid, .article-grid).          */
.measure { max-width: var(--measure); margin-inline: auto; }
.section { padding-block: var(--s-x4); }
.section + .section { border-top: 1px solid var(--line-quiet); }

@media (min-width: 64rem) {
  .section { padding-block: 5rem; }   /* 80px. 96 read as a void, not as calm */
}

/* Hero: one column on small viewports; the figures move alongside the
   argument at 64rem, so the right half of a desktop viewport is composed
   rather than empty. (WD §5.2)                                            */
.hero-grid { display: grid; gap: var(--s-xxl); }
@media (min-width: 64rem) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 23rem);
    gap: var(--s-x4);
    align-items: start;
  }
  .hero-grid > :first-child { max-width: var(--measure); padding-top: var(--s-lg); }
}
.hero-figures > * + * { margin-top: var(--s-sm); }
.hero-screen { display: flex; flex-direction: column; gap: var(--s-md); }
.screen-cap { font-size: var(--t-row-sub); color: var(--ink-quiet); line-height: 1.5; }

/* Article: reading column, with a contents rail from 1024px up. */
.article-grid { display: block; }
@media (min-width: 64rem) {
  .article-grid {
    display: grid;
    grid-template-columns: var(--rail) minmax(0, var(--measure));
    gap: var(--s-xxl);
    justify-content: center;
    align-items: start;
  }
  .toc { position: sticky; top: var(--s-x4); }
}
.toc { display: none; }
@media (min-width: 64rem) { .toc { display: block; } }
.toc ol { list-style: none; }
.toc li + li { margin-top: 0; }
.toc a {
  color: var(--ink-quiet); text-decoration: none;
  font-size: var(--t-row-sub); line-height: 1.4;
  display: flex; align-items: center;
  min-height: var(--touch); padding: var(--s-xs) 0;
}
.toc a:hover, .toc a:focus-visible { color: var(--ink); }

/* ---- 6. Navigation ----------------------------------------------------- */
/* Opaque bone with a bottom hairline. No blur, no shadow — DS §5.1 rules out
   `backdrop-filter` as firmly as it rules out `box-shadow`.                */

.nav {
  position: sticky; top: 0; z-index: 10;
  background: var(--bone);
  border-bottom: 1px solid var(--line);
}
.nav-inner {
  max-width: var(--wide); margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex; align-items: center; gap: var(--s-lg);
  min-height: var(--touch);
}
.wordmark {
  font-family: var(--font-figure); font-weight: 500;
  font-size: 1.25rem; letter-spacing: var(--tr-figure-m);
  color: var(--ink); text-decoration: none;
  display: inline-flex; align-items: center;
  min-height: var(--touch); padding-right: var(--s-sm);
}
.nav-links { margin-left: auto; display: flex; gap: var(--s-xs); list-style: none; }
.nav-links a {
  display: inline-flex; align-items: center;
  min-height: var(--touch); padding: 0 var(--s-md);
  border-radius: var(--r-lg);
  font-size: var(--t-row); font-weight: 600;
  color: var(--ink-secondary); text-decoration: none;
  letter-spacing: var(--tr-row);
}
.nav-links a:hover { color: var(--ink); background: var(--surface); }
.nav-links a[aria-current="page"] { color: var(--ink); background: var(--surface); }

@media (max-width: 29.9375rem) {
  .nav-inner { flex-wrap: wrap; padding-bottom: var(--s-sm); }
  .nav-links { margin-left: 0; width: 100%; }
  .nav-links a { padding: 0 var(--s-sm); }
}

/* ---- 7. Card ----------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--s-lg);
}
@media (min-width: 40rem) { .card { padding: var(--s-xl); } }
.card + .card { margin-top: var(--s-sm); }
.card > .data-label { margin-bottom: var(--s-md); }
:where(.card) p { font-size: var(--t-body); color: var(--ink-secondary); }
.card .answer { font-size: var(--t-reading); color: var(--ink); line-height: 1.55; }
:where(.card) p + p { margin-top: var(--s-md); }

/* The one actionable card. accentSubtle ground; the BUTTON is the second,
   non-colour indicator (DS §2.5). A factual card has no button — ever.     */
.card--accent {
  background: var(--accent-subtle);
  border-color: transparent;
}
.card--accent .data-label,
.card--accent h2, .card--accent h3 { color: var(--accent); }
:where(.card--accent) p { color: var(--ink-secondary); }

/* Disclosure only. The single component that sits between a heading and its
   body content, because placement above the pitch is load-bearing (DS §8).  */
.card--disclosure {
  background: var(--surface);
  border-color: var(--accent);
}
.card--disclosure .data-label { color: var(--accent); }

/* ---- 8. Chip ----------------------------------------------------------- */

.chip {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  padding: var(--s-xs) var(--s-sm);
  border-radius: var(--r-md);
  white-space: nowrap;
}
.chip--accent { background: var(--accent-subtle); color: var(--accent); border: 1px solid transparent; }
/* quiet = transparent ground + hairline. NOT a `line` fill: inkQuiet on line
   measures 3.83 light / 3.57 dark and fails AA. (WD §6, contrast table)    */
.chip--quiet  { background: transparent; color: var(--ink-quiet); border: 1px solid var(--line); }

/* ---- 9. Row ------------------------------------------------------------ */

.rows { border-top: 1px solid var(--line-quiet); }
.rows--static .row { cursor: default; }
.row {
  display: flex; align-items: flex-start; gap: var(--s-md);
  width: 100%; min-height: 3.5rem;           /* 56px — WD §5.4 departure */
  padding: var(--s-md) 0;
  border-bottom: 1px solid var(--line-quiet);
  background: none; border-left: 0; border-right: 0; border-top: 0;
  text-align: left; text-decoration: none; color: inherit;
  font-family: inherit; cursor: pointer;
}
a.row:hover .row-title, .row:hover .row-title { text-decoration: underline; }
.row-text { flex: 1; min-width: 0; }
.row-title {
  display: block; font-size: var(--t-row); font-weight: 600;
  letter-spacing: var(--tr-row); color: var(--ink); line-height: 1.35;
}
.row-sub {
  display: block; font-size: var(--t-row-sub); color: var(--ink-quiet);
  margin-top: var(--s-xxs); line-height: 1.45; font-style: normal;
}
.row-value { font-family: var(--font-figure); font-weight: 500; font-size: var(--t-figure-row); }
/* Chevron is inkFaint: decoration reinforcing a target that is already
   obviously tappable. It never carries meaning. (DS §7.2)                  */
.row-chevron { color: var(--ink-faint); font-size: 1rem; line-height: 1.5; flex: none; }
.row-aside { display: flex; align-items: center; gap: var(--s-sm); flex: none; padding-top: 0.1rem; }

.group-header {
  display: block; margin-top: var(--s-lg); margin-bottom: var(--s-xxs);
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--ink-quiet);
}

/* ---- 10. Button -------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 3rem;                        /* 48px — WD §5.4 */
  padding: 0 var(--s-xl);
  border-radius: var(--r-control);
  font-family: var(--font-ui); font-size: var(--t-button); font-weight: 600;
  text-decoration: none; cursor: pointer;
  border: 1px solid transparent;
  transition: transform var(--d-fast) var(--ease), opacity var(--d-fast) var(--ease);
}
.btn:active { transform: scale(0.985); opacity: 0.9; }   /* the 100ms feedback */
.btn--primary { background: var(--ink);    color: var(--bone);           border-color: var(--ink); }
.btn--accent  { background: var(--accent); color: var(--accent-on-fill); border-color: var(--accent); }
.btn--ghost   { background: transparent;   color: var(--ink);            border-color: var(--line); }
.btn--sm      { min-height: var(--touch); padding: 0 var(--s-lg); font-size: var(--t-row); }
.btn--ghost:hover { background: var(--surface); }

/* ---- 11. Marker: awaiting sign-off ------------------------------------- */
/* Uses the `quiet` chip treatment deliberately. This is a neutral fact about
   the document's status, not a feature — the same reasoning that keeps the
   Disclosure chip off the accent. (DS §8.1 rule 5)                         */

.awaiting {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-md);
  border: 1px dashed var(--line);
  border-radius: var(--r-xl);
  padding: var(--s-lg);
  background: transparent;
}
.awaiting p { font-size: var(--t-body); color: var(--ink-quiet); margin: 0; }
.awaiting strong { color: var(--ink); font-weight: 600; }
/* An unfilled field renders as visible words, never as an empty space — the
   same rule as "Not recorded" in the comparison table. */
.pending { color: var(--ink-quiet); font-weight: 600; font-style: italic; }
.awaiting .chip { flex: none; }

/* ---- 12. Key facts ----------------------------------------------------- */

.key-facts { list-style: none; border-top: 1px solid var(--line-quiet); }
.key-facts li {
  border-bottom: 1px solid var(--line-quiet);
  padding: var(--s-md) 0;
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: 0.02em;
  color: var(--ink-secondary);
}

/* ---- 13. Allocation bar (landing only) --------------------------------- */
/* Stepped opacity of a single ink, not a multi-hue chart. Colour-independent
   by construction, and it survives greyscale. (DS §7.9)                    */

.alloc { display: flex; gap: 2px; height: 0.375rem; margin-top: var(--s-lg); }
/* The per-segment flex ratio and opacity are the data. They are the one place
   in this site where a style attribute is generated, because a static class
   cannot carry a value that comes from the content file. (WD §7.4)         */
.alloc span { background: var(--ink); border-radius: var(--r-sm); min-width: 0.3125rem; }
.alloc-key { list-style: none; margin-top: var(--s-md); display: grid; gap: var(--s-sm); }
@media (min-width: 40rem) { .alloc-key { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.alloc-key li { display: flex; align-items: baseline; gap: var(--s-sm); font-size: var(--t-row-sub); color: var(--ink-quiet); }
.alloc-swatch { width: 0.625rem; height: 0.625rem; border-radius: 2px; background: var(--ink); flex: none; transform: translateY(1px); }
.alloc-key .amount { margin-left: auto; font-family: var(--font-figure); font-weight: 500; color: var(--ink-secondary); }

/* ---- 13b. Comparison matrix --------------------------------------------
   Wide content scrolls inside its own container so the page body never scrolls
   sideways. Separation is hairlines and a surface shift, as everywhere else —
   no zebra fill, which would be a second ground the language does not have. */

/* `position: relative` is load-bearing, not decoration. `.visually-hidden` is
   `position: absolute`; with no positioned ancestor those spans resolve against
   the initial containing block and escape the scroll container, widening the
   document instead of the scroller. Measured: 1575px document on a 1440px
   viewport, fixed to 1440 by this one line. */
.table-scroll { position: relative; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-xl); background: var(--surface); }
.matrix { border-collapse: collapse; width: 100%; min-width: 44rem; font-size: var(--t-body); }
.matrix th, .matrix td { text-align: left; vertical-align: top; padding: var(--s-md) var(--s-lg); border-bottom: 1px solid var(--line-quiet); }
.matrix thead th {
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--ink-quiet); white-space: nowrap;
  border-bottom: 1px solid var(--line);
}
.matrix tbody tr:last-child th, .matrix tbody tr:last-child td { border-bottom: 0; }
.matrix tbody th { font-weight: 600; color: var(--ink); letter-spacing: var(--tr-row); white-space: nowrap; }
/* The row-header link is a navigation target, not inline prose, so SC 2.5.8's
   inline exception does not cover it and the 44px house floor applies. Padding
   expands the hit area; the negative margin cancels its effect on the cell, so
   the name still aligns with the top-aligned data cells beside it. */
.matrix tbody th a {
  display: inline-block;
  color: var(--ink); text-decoration-thickness: 1px;
  padding-block: 0.8rem; margin-block: -0.8rem;
}
.matrix tbody th a:hover { color: var(--accent); }
.matrix td { color: var(--ink-secondary); }
/* "Not recorded" is rendered as words, never as a dash. A blank cell reads as
   "none", and a charge that exists but has not been checked reading as "none"
   is a misleading omission (DMCCA 2024 Part 4). */
.matrix td.unknown { color: var(--ink-quiet); font-style: italic; }
.cell-sub { display: block; font-weight: 400; font-size: var(--t-row-sub); color: var(--ink-quiet); margin-top: var(--s-xxs); white-space: normal; }
.matrix .chip { margin-top: var(--s-sm); }
.measure-left { max-width: var(--measure); }

/* The offers grid. Tri-state cells: a tick, the word No, or the words Not
   checked. Never a blank — see the note beside .matrix td.unknown. */
.matrix--grid { min-width: 56rem; }
.matrix--grid thead th:not(:first-child) { text-align: center; }
.matrix--grid td.mark { text-align: center; white-space: nowrap; font-size: var(--t-body); }
.matrix--grid td.mark [aria-hidden] { font-size: 1rem; color: var(--ink); }
.matrix--grid .off { font-family: var(--font-mono); font-weight: 500; font-size: var(--t-label);
  letter-spacing: .06em; color: var(--ink-quiet); }
.matrix--grid .off.unknown { font-style: italic; }

/* ---- 13c. App screens ---------------------------------------------------
   Rendered from the tokens, not screenshotted. Three reasons, and the third is
   the one that decided it:
     1. no image payload, crisp at any density;
     2. they cannot drift from the design system, because they ARE it;
     3. a PNG captured in light mode sits wrongly on a page in dark mode. These
        follow the viewer's appearance setting because they inherit the tokens.
   Nothing floats, tilts or casts a shadow — the precedent set is full of
   angled device mockups and every one of them is ruled out by §5.1. The frame
   is the site's own card treatment at sheet radius. (WD §13.2 D-19)        */

.screens { display: grid; gap: var(--s-xxl); max-width: var(--wide); margin-inline: auto; }
@media (min-width: 48rem) { .screens { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .screens { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* Two screens read better as a centred pair than as two thirds of a three-up. */
.screens--pair { max-width: 52rem; }
@media (min-width: 64rem) { .screens--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.screen-fig { display: flex; flex-direction: column; gap: var(--s-md); min-width: 0; }
.screen-fig figcaption { font-size: var(--t-row-sub); color: var(--ink-quiet); line-height: 1.5; }
.screen-fig figcaption strong { color: var(--ink); font-weight: 600; }

.screen {
  background: var(--bone);
  border: 1px solid var(--line);
  border-radius: var(--r-sheet);
  padding: var(--s-lg);
  display: flex; flex-direction: column; gap: var(--s-sm);
  min-height: 19rem;
}
.screen .figure-large { font-size: 2rem; }        /* the app's figureLarge, fixed */
.screen .delta { color: var(--ink-secondary); }
.screen .chip { align-self: flex-start; }
.screen-h { font-family: var(--font-figure); font-weight: 500; font-size: 1.25rem; letter-spacing: var(--tr-figure-m); }
.screen-micro { margin-top: auto; padding-top: var(--s-sm); }

/* The one gradient permitted in the product: two stops, ink, very low opacity,
   under the net-worth line. DESIGN_STANDARDS §7.10. */
.screen-chart { width: 100%; height: 4.625rem; color: var(--ink); margin-block: var(--s-xs); }

.screen-card { border-radius: var(--r-xl); padding: var(--s-md); background: var(--surface); border: 1px solid var(--line); }
.screen-card--accent { background: var(--accent-subtle); border-color: transparent; }
.screen-card--accent .data-label { color: var(--accent); }
.screen-card b { display: block; font-size: var(--t-row); font-weight: 600; line-height: 1.3; margin-top: var(--s-xs); color: var(--accent); }
.screen-card p { font-size: var(--t-row-sub); color: var(--ink-secondary); margin-top: var(--s-xs); }
/* The exit check is part of the insight, not a footnote to it. Telling someone
   they could earn more while omitting what moving costs them is a misleading
   omission under DMCCA 2024 Part 4 — see REGULATORY_REVIEW.md §2.7. It sits
   inside the card, above the action, for the same reason the Disclosure card
   sits above the pitch (§8). */
.screen-card .screen-check {
  border-top: 1px solid var(--line-quiet);
  margin-top: var(--s-sm); padding-top: var(--s-sm);
  color: var(--ink-secondary);
}
.screen-card .screen-check strong { color: var(--ink); font-weight: 600; }
/* Not a <button>: these screens are an illustration, so nothing in them is
   focusable or announced as a control. */
.screen-btn {
  display: inline-flex; align-items: center; align-self: flex-start;
  margin-top: var(--s-md); padding: var(--s-sm) var(--s-md);
  border-radius: var(--r-control); background: var(--accent); color: var(--accent-on-fill);
  font-size: var(--t-row-sub); font-weight: 600;
}
.screen-btn--ink { background: var(--ink); color: var(--bone); margin-top: var(--s-sm); }

.screen-rows { border-top: 1px solid var(--line-quiet); margin-top: var(--s-xs); }
.screen-row { display: flex; align-items: center; gap: var(--s-sm); padding: var(--s-sm) 0; border-bottom: 1px solid var(--line-quiet); }
.screen-row-t { flex: 1; font-size: var(--t-row-sub); font-weight: 600; color: var(--ink); min-width: 0; }
.screen-row-t em { display: block; font-style: normal; font-weight: 400; color: var(--ink-quiet); margin-top: 1px; }
.screen-row-v { font-family: var(--font-figure); font-weight: 500; font-size: var(--t-row-sub); font-variant-numeric: tabular-nums; }
.screen-tick {
  flex: none; width: 1.375rem; height: 1.375rem; border-radius: var(--r-md);
  border: 1px solid var(--accent); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center; font-size: 0.75rem;
}
/* Not-yet-captured is a different GLYPH as well as a different colour, so the
   state survives greyscale and deuteranopia. §2.5 colour independence. */
.screen-tick--off { border-color: var(--line); color: var(--ink-faint); }

/* ---- 14. Grids --------------------------------------------------------- */

.grid { display: grid; gap: var(--s-sm); }
@media (min-width: 48rem) { .grid--3 { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.grid .card + .card { margin-top: 0; }

/* ---- 15. Footer -------------------------------------------------------- */

.footer {
  border-top: 1px solid var(--line);
  margin-top: var(--s-x5);
  padding-block: var(--s-x4);
}
.footer-cols { display: grid; gap: var(--s-xl); }
@media (min-width: 48rem) { .footer-cols { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.footer ul { list-style: none; }
:where(.footer) li { margin-top: var(--s-xxs); }
.footer a {
  display: inline-flex; align-items: center;
  min-height: var(--touch);
  color: var(--ink-secondary); text-decoration: none; font-size: var(--t-body);
}
.footer a:hover { color: var(--ink); text-decoration: underline; }
.footer .colophon { margin-top: var(--s-xxl); border-top: 1px solid var(--line-quiet); padding-top: var(--s-lg); }
.footer .colophon p { font-size: var(--t-row-sub); color: var(--ink-quiet); max-width: var(--measure); }
.footer .colophon p + p { margin-top: var(--s-sm); }

.theme-toggle {
  margin-top: var(--s-lg);
  display: inline-flex; align-items: center; gap: var(--s-sm);
  min-height: var(--touch); padding: 0 var(--s-md);
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-lg);
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--t-label); letter-spacing: var(--tr-chip); text-transform: uppercase;
  color: var(--ink-quiet); cursor: pointer;
}
.theme-toggle:hover { color: var(--ink); }

/* ---- 16. Utilities ----------------------------------------------------- */

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.mt-sm { margin-top: var(--s-sm); }
.mt-md { margin-top: var(--s-md); }
.mt-lg { margin-top: var(--s-lg); }
.mt-xl { margin-top: var(--s-xl); }
.mt-xxl{ margin-top: var(--s-xxl); }
.mt-x4 { margin-top: var(--s-x4); }
.quiet { color: var(--ink-quiet); }
.secondary { color: var(--ink-secondary); }
.back-link {
  display: inline-flex; align-items: center; gap: var(--s-sm);
  min-height: var(--touch);
  font-size: var(--t-row); font-weight: 600; color: var(--ink-secondary);
  text-decoration: none;
}
.back-link:hover { color: var(--ink); text-decoration: underline; }
