/* UX-012 - the Raai visual system. CAP-113 holds the stylesheet to it.
 *
 * Supersedes UX-004 (quiet glass), UX-005 (one accent, no red) and UX-011 (its keep list).
 * Read the token block below first: it states what changed and why.
 *
 * The five material tiers survive UX-012 unchanged, because they were never the problem -
 * what changed is what they are made of, not what they mean:
 *
 *   M0  environment   the room. On dark: two soft lights and grain. On light: paper.
 *   M1  content       ink directly on the ground. NO CONTAINER. most of the product
 *   M2  floating      rail, tabbar, capture tray, cards that lift, chips that act
 *   M3  elevated      the conversation dock, sheets. the room stays legible through it
 *   M4  opaque        the ledger, evidence. reading beats material
 *
 * Four laws, down from five. Rule 5 (one accent, no red) is superseded by UX-012:
 *
 *   1. Glass never sits over scrolling content. Content passing behind translucency turns
 *      to mud, and moving mud is worse. Glass belongs over the ground, or over something
 *      still. On light this mostly means: it is not glass, it is paper.
 *   2. Two live blur layers on screen, maximum. A hard budget, not a guideline.
 *   3. Chips are not glass. A 20px blur on a 22px element samples almost entirely outside
 *      itself: invisible effect, real compositor cost. Chips are tinted ink.
 *   4. If you cannot name which of the four facts a surface encodes, it is M1.
 *
 * Kept verbatim from UX-004: nothing counts up - the empty state is the good state - type
 * carries hierarchy, not boxes - never a bounce - plain language only.
 *
 * UX-013 - one typeface. UX-006's two voices (sans for data, serif for narration) are
 * superseded by the Figma's single family. What UX-006 protected still holds: nothing marks
 * WHO composed a sentence - the same sentences arrive from templates when no provider is
 * reachable, so going offline must not look like breakage - and the provenance line, not the
 * typeface, says "composed" or "from rules". The reading is marked by rank and size instead.
 */
/* ─────────────────────────────────────────────────────────── tokens · UX-012, UX-013
 *
 * VALUES since UX-013 (2026-09-23): the light palette is the Figma's, exact; dark is authored in
 * the same slate family, with cards opaque and flat and the ambient lights off. The NAMES, and
 * the three rules below, are UX-012's.
 *
 * UX-012 supersedes UX-004's "quiet glass", UX-005's one-accent rule and UX-011's keep list. Three
 * things changed and everything else in this file is the consequence of them:
 *
 *   1. LIGHT IS THE DEFAULT, and dark is a second designed palette rather than the source
 *      one is derived from. Both are authored; neither is an inversion of the other.
 *   2. COLOUR CARRIES DOMAIN. Each place has a hue, so Money does not look like Work and
 *      Today does not look like Life — one system, several personalities.
 *   3. RED AND GREEN EXIST, and they mean DIRECTION, never judgement. Money leaving is rose
 *      and money arriving is green because that is the convention every person reading a
 *      statement already has; it is not a verdict on the spending. UX-005's "no red token,
 *      nothing in this product means alarm" is superseded by that narrower rule.
 *
 * What survives unchanged, because it was never the problem: nothing counts up · the empty
 * state is the good state · type carries hierarchy, not boxes · plain language only · never a
 * bounce. (UX-006's two voices were dropped by UX-013: one family, the Figma's.)
 *
 * ── Every name below is load-bearing ──────────────────────────────────────────────────
 *
 * The material names (M2/M3/M4, --glass, --hairline, --ink-*) are used by ~2,700 lines of
 * component CSS. This block replaces their VALUES and keeps their NAMES, so the whole product
 * re-skins from one place and no selector had to be rewritten to get there.
 */
/*
 * ── The typeface, self-hosted (UX-013 §1) ─────────────────────────────────────────────
 *
 * Plus Jakarta Sans, the Figma's family, as variable woff2 files in pc/web/fonts/ with the SIL
 * Open Font Licence beside them (OFL.txt). Vendored once from the Fontsource package of the
 * Google Fonts release; the running app requests them from its own server and nowhere else.
 * One variable file per script range covers every weight the Figma uses (400-700), and the
 * italic exists for exactly one Figma treatment ("not stated"). `swap` so a slow first read
 * shows text in the system face rather than nothing.
 */
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-wght-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light dark;

  --ground: #f9fafb;
  --ground-2: #f1f5f9;

  /* M2 · floating: the rail, the tray, chips that act, cards that lift off the ground. */
  --m2: #ffffff;
  --m2-line: #f1f5f9;
  --m2-hi: #f8fafc;
  --m2-shadow: 0 1px 2px rgba(15, 23, 43, 0.06), 0 2px 6px rgba(15, 23, 43, 0.04);
  /* A row card lifts a little more than a card does (Figma 1:1834's two-part shadow). */
  /* An unselected pill's rim and a selected pill's lift (1:1806, 1:1809). */
  --pill-line: rgba(226, 232, 240, 0.6);

  /* M3 · elevated: the conversation dock, sheets. */
  --m3: #ffffff;
  --m3-line: #e2e8f0;
  --m3-shadow: 0 4px 10px rgba(0, 0, 0, 0.05), 0 18px 44px rgba(15, 23, 43, 0.08);

  /* M4 · opaque: the ledger, evidence, anything where reading beats material. */
  --m4: #ffffff;
  --m4-2: #f8fafc;
  --m4-line: #f1f5f9;

  /* The docked chrome on a phone: the tab bar. The capture row sits on the ground (UX-013). */
  --tray: #ffffff;

  /*
   * The dock's field material: the capture pill and Talk's button. The Figma's own values - a
   * slate-100 fill at 80%, a slate-200 hairline at half strength, and a two-part shadow that
   * lifts the pill off the page more than a card's.
   *
   * The fill is that 80% slate-100 composited once over the ground (#f9fafb), so it is opaque.
   * The dock row has no sheet (owner, after D0c), so page text scrolls behind the pill, and at
   * 80% it showed through under the placeholder and under what you type. Over the bare page
   * this is the same colour the frame draws.
   */
  --field: #f3f6f9;
  --field-line: rgba(226, 232, 240, 0.5);

  /*
   * Three ink tiers, the Figma's slate: #0f172b, #62748e, #90a1b9. The third is about 2.6:1 on
   * white - below AA, by the owner's choice (UX-013 §5). It carries only metadata the row also
   * says in a darker tier; the contrast test pins it exactly and holds the other tiers, and the
   * whole dark palette, to 4.5:1.
   */
  --ink: #0f172b;
  --ink-2: #62748e;
  --ink-3: #90a1b9;
  /* NON-TEXT ONLY: dots, rules, decorative glyphs. Never anything a person must read. */
  --ink-faint: #cad5e2;
  /*
   * Two roles the Figma sets between --ink and --ink-2 (M1): the body of an insight card
   * (#45556c) and the heading of the "What Raai knows" card (#314158). Both are text and both
   * clear AA on white by a wide margin.
   */
  --ink-body: #45556c;
  --ink-head: #314158;

  /* The system accent: focus, relevance, the primary action. Not a domain. */
  --accent: #155dfc;
  --accent-soft: rgba(21, 93, 252, 0.09);
  --accent-ring: rgba(21, 93, 252, 0.36);

  /*
   * ── Direction and state, for money ────────────────────────────────────────────────
   *
   * These say WHICH WAY, never whether it was wise. A large outflow you chose is rose because
   * it left, exactly as it is in the statement your bank sends you — and the product still
   * refuses to grade it (P4).
   */
  --in: #009966;
  --in-soft: #ecfdf5;
  --out: #ec003f;
  --out-soft: #fff1f2;
  --transfer: #155dfc;
  --transfer-soft: #eff6ff;
  /* The Coming timeline (1:2792, 1:2810-1:2823): its dots, and a row coming in. */
  --tl-out: #ff6467;
  --tl-in: #00d492;
  --in-wash: rgba(236, 253, 245, 0.5);
  --in-edge: rgba(208, 250, 229, 0.5);
  --in-ink: #004f3b;
  --in-deep: #007a55;
  --in-meta: rgba(0, 153, 102, 0.8);
  --invest: #4f39f6;
  --invest-soft: #eef2ff;
  /* A holding's card: the indigo tint at 30%, its rim, its tile (1:1917). Never cash. */
  --invest-wash: rgba(238, 242, 255, 0.3);
  --invest-edge: #e0e7ff;
  --invest-tile: rgba(224, 231, 255, 0.5);

  /*
   * Earned attention, and the uncertainty that shares its hue.
   *
   * `--attn` and `--attn-soft` were referenced by three rules and never defined, so Work's
   * over-capacity figure and Money's under-floor bar have been rendering in plain ink with a
   * fallback since they were written. They are real now.
   */
  --attn: #bb4d00;
  --attn-soft: #fffbeb;
  --ember: var(--attn);
  --ember-soft: var(--attn-soft);
  /*
   * The uncertain card (Figma 1:1724): the amber-soft wash at half strength, its hairline, and
   * the glyph's amber. UX-013 §10 - amber means uncertain, and a projection is.
   */
  --attn-wash: rgba(255, 251, 235, 0.5);
  --attn-edge: rgba(254, 243, 198, 0.5);
  --attn-mark: #e17100;
  --attn-line: #fef3c6;
  --attn-ink: rgba(123, 51, 6, 0.8);

  /*
   * ── One hue per place ─────────────────────────────────────────────────────────────
   *
   * Used for the place's mark, its section rules and its charts — never as a background wash
   * behind text, which is how a coloured product becomes an unreadable one.
   */
  --d-today: #f54900;
  --d-today-soft: #fff7ed;
  --d-time: #00b8db;
  --d-time-soft: #ecfeff;
  --d-money: #009966;
  --d-money-soft: #ecfdf5;
  --d-work: #4f39f6;
  --d-work-soft: #eef2ff;
  --d-life: #e60076;
  --d-life-soft: #fdf2f8;
  --d-talk: #62748e;
  --d-talk-soft: #f1f5f9;

  /*
   * Charts. The ring's first three are the Figma's (1:2479-1:2485): sky, blue, violet. The rest
   * extend the same cool family, ordered so neighbours stay apart. None is red, green or amber,
   * which mean money out, money in and attention (UX-013 §10). --c-none is "not categorised".
   */
  --c-1: #0ea5e9;
  --c-2: #3b82f6;
  --c-3: #8b5cf6;
  --c-4: #d946ef;
  --c-5: #6366f1;
  --c-6: #f472b6;
  --c-none: #cad5e2;
  --c-grid: rgba(15, 23, 43, 0.08);
  /*
   * The trajectory as the Figma draws it (1:1754): recorded in emerald, projected in slate,
   * and the floor you named in amber, its label a shade deeper so it reads as text.
   */
  --c-recorded: #10b981;
  --c-projected: #94a3b8;
  --c-floor: #f59e0b;
  --c-floor-ink: #d97706;

  /* Three corners (review, 30 September): a tag, a control or row, a card or sheet. Plus the pill. */
  --r-lg: 20px;
  --r-sm: 12px;
  --r-xs: 6px;
  --r-pill: 999px;

  /* 160ms for small things. Sheets are heavier and settle rather than snap. */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
  --dur: 160ms;
  --dur-sheet: 260ms;

  /*
   * ONE typeface: Plus Jakarta Sans, the Figma's (UX-013 §1, superseding UX-006's two voices).
   * Self-hosted from pc/web/fonts/ with its OFL licence beside it - served by this machine, so
   * a private, offline-first shell still fetches nothing from a third party. The system stack
   * after it is the fallback while the file loads, or if it is ever absent.
   */
  --sans: "Plus Jakarta Sans", ui-sans-serif, -apple-system, "Segoe UI Variable Display",
          "Segoe UI", system-ui, "Helvetica Neue", Arial, sans-serif;

  /*
   * ── The type scale, as tokens ────────────────────────────────────────────────────────
   *
   * Seven tiers, and `pc/test/trust/system.spec.ts` fails the build on a raw px font-size
   * anywhere in this file. Retuned upward for a light ground: dark ink on pale paper carries
   * less apparent weight than pale ink on dark, so the body tier that read as calm at 14px
   * reads as small at the same size here.
   */
  --t-figure: 26px;    /* a display figure: data, tabular. The Figma KPI figure */
  --t-reading: 24px;   /* depth 1: the composed sentence. Re-set per screen phase (UX-013) */
  --t-title: 28px;     /* the page title and the header date: the Figma H1 */
  --t-date: 16px;      /* a section heading, a name, a card title: the Figma H2 */
  --t-prose: 16px;     /* narration inline; card and row titles */
  --t-body: 15px;      /* body, structure, lists, controls */
  --t-meta: 13px;      /* secondary, and every "meta" line under a row */
  --t-micro: 11px;     /* wide-tracked uppercase labels */

  --rail: 188px;
  --dock: 356px;
  /*
   * TWO widths, because a sentence and a ledger do not want the same one (UX-011.5).
   * `--measure` is the reading measure and belongs to prose. `--measure-data` is what a
   * surface of accounts, hours or rows may take.
   */
  --measure: 66ch;
  /*
   * The desk's one column (UX-017): every place and reached layer, and the capture field above it,
   * at this width beside the rail. The phone's composition, wider; nothing is recomposed.
   */
  --desk-col: 600px;
  --measure-data: 1120px;
  /* Off on light. Grain over a pale ground is dirt, and the lights have no glass to feed. */
  --grain: 0;

  /*
   * ── The Wishlist layers' stone palette (frames 17:10, 18:264, 18:388; audit §9.4 Q4) ──────
   *
   * The owner's ruling was the frames' exact values, and these three frames are drawn in a warm
   * stone family rather than the slate the rest of the product uses. Scoped by NAME: only the
   * Wishlist layers read --w-*, so the stone never leaks into a slate surface. The third ink
   * (#a6a09b) is below AA as text on the stone ground, like --ink-3, and is pinned exactly by the
   * contrast test for the same reason (UX-013 §5).
   */
  --w-ground: #fcfbf8;
  /* The shell on the Wishlist layers: the dock and tab bar in stone, so they sit on the ground. */
  --w-tray: #ffffff;
  --w-field: #f5f5f4;
  --w-field-line: rgba(231, 229, 228, 0.6);
  /*
   * T1 · Today's warm ground and the timeline's two marks (1:710). The page is #fdfbf9 under a
   * wash of the Today hue's soft tint; a fixed block's dot is indigo, and an uncertain slot
   * takes amber (UX-013 §10). Dark keeps the product's navy ground and only warms it faintly,
   * so the shell never sits on a different colour from the page.
   */
  /*
   * L1 · Life's kind colours and doors (1:9). A person takes the frame's orange (Today's hue);
   * a thing takes Life's own pink where the frame drew #ec003f, the red UX-013 §10 keeps for money
   * going out. An unknown kind has no colour of its own. The doors are the frame's warm card.
   */
  --ent-person: var(--d-today);
  --ent-person-soft: var(--d-today-soft);
  --ent-person-line: #ffedd4;
  --ent-person-wash: rgba(255, 237, 212, 0.5);
  --ent-thing: var(--d-life);
  --ent-thing-soft: var(--d-life-soft);
  --ent-thing-line: #fce7f3;
  --ent-thing-wash: rgba(252, 231, 243, 0.5);
  /* PD-027 kinds (UX-014 §1): a place in Time's cyan where the frame drew amber; a project in its violet. */
  --ent-place: var(--d-time);
  --ent-place-soft: var(--d-time-soft);
  --ent-place-line: #cefafe;
  --ent-place-wash: rgba(206, 250, 254, 0.5);
  --ent-project: #7f22fe;
  --ent-project-soft: #f5f3ff;
  --ent-project-line: #ede9fe;
  --ent-project-wash: rgba(237, 233, 254, 0.5);
  /* W1 · Work's marks (1:5148): its indigo, the blue of a near date, the cyan waiting pill. */
  --wk-ink: #615fff;
  --wk-near: #155dfc;
  --wk-fact: rgba(248, 250, 252, 0.5);
  --wk-pill-ink: #007595;
  --wk-pill-wash: rgba(236, 254, 255, 0.5);
  --wk-pill-line: rgba(206, 250, 254, 0.5);
  /* Ti1 · Time's day blocks and today's mark (1:1505, 1:1175). */
  --ti-block: rgba(236, 254, 255, 0.6);
  --ti-block-line: #cefafe;
  --ti-block-ink: #104e64;
  --ti-today-ink: #0092b8;
  /* The selected day's number on the cyan circle. White on #00b8db was 2.37:1 (review F-10); the dark
     theme's deep ink is used in light too, 6.6:1, and the circle keeps the Figma cyan. */
  --ti-on-time: #06222b;
  --today-ground: #fdfbf9;
  --today-wash: rgba(255, 247, 237, 0.5);
  --tl-block: #7c86ff;
  --tl-attn: #ffb900;
  --attn-deep: #7b3306;
  --attn-meta: rgba(187, 77, 0, 0.8);
  --w-card: #ffffff;
  --w-card-line: rgba(245, 245, 244, 0.5);
  --w-sheet-line: #f5f5f4;
  --w-ink: #1c1917;
  --w-ink-2: #79716b;
  --w-ink-3: #a6a09b;
  --w-ink-body: #57534d;
  --w-ink-deep: #44403b;
  --w-soft: #f5f5f4;
  --w-soft-2: #fafaf9;
  --w-rim: rgba(231, 229, 228, 0.6);
  --w-float: rgba(255, 255, 255, 0.8);
  /* The site chip on a want's hero (18:395): the float, a shade more opaque, as drawn. */
  --w-chip: rgba(255, 255, 255, 0.9);
  --w-down: #00bc7d;
  /* Each want's tile: the frame's two-stop wash and its glyph (17:24 … 17:146). */
  --w-laptop-a: #f1f5f9; --w-laptop-b: #e2e8f0; --w-laptop: #62748e;
  --w-headphones-a: #eff6ff; --w-headphones-b: #e0e7ff; --w-headphones: #615fff;
  --w-armchair-a: #fff7ed; --w-armchair-b: #fef3c6; --w-armchair: #e17100;
  --w-camera-a: #f5f5f4; --w-camera-b: #e7e5e4; --w-camera: #79716b;
  --w-plane-a: #f0f9ff; --w-plane-b: #cefafe; --w-plane: #0092b8;
  /* The want's callout (18:459): amber, because it would take you under your floor. */
  --w-attn-wash: rgba(255, 251, 235, 0.5);
  --w-attn-edge: rgba(254, 230, 133, 0.6);
  --w-attn-title: #7b3306;
  --w-attn-body: rgba(151, 60, 0, 0.9);
  /* Money's "View full Wishlist" (1:3346): the frame's link blue, a shade off the accent. */
  --link: #215ce5;
  --glow-on: 0;

  /*
   * UX-004 names, aliased onto the four materials. Second NAMES for one value, never second
   * values — the palette is defined exactly once, above.
   */
  --glass-hi: var(--m2-hi);
  --hairline: var(--m2-line);
  --hairline-hi: var(--m3-line);
  --inset: var(--m2-hi);
  --font: var(--sans);
}

/*
 * ── Dark, authored rather than inverted ───────────────────────────────────────────────
 *
 * Every hue is re-chosen for a dark ground rather than lightened programmatically: emerald
 * at its light-theme value is nearly black on #0a0e15, and rose becomes brown. The ratios
 * that matter are asserted by the contrast test, in both directions.
 *
 * Declared twice, deliberately. There is no build step (ADR-003, ADR-005), so a shared block
 * would need a preprocessor; the alternative is one list that both selectors point at, and
 * plain CSS has no such construct. The duplication is mechanical and the test reads both.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #0b1020;
    --ground-2: #111827;
    --m2: #141b2d;
    --m2-line: rgba(255, 255, 255, 0.07);
    --m2-hi: rgba(255, 255, 255, 0.05);
    --m2-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
    --pill-line: rgba(255, 255, 255, 0.08);
    --m3: #182033;
    --m3-line: rgba(255, 255, 255, 0.10);
    --m3-shadow: 0 18px 44px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);
    --m4: #141b2d;
    --m4-2: #182033;
    --m4-line: rgba(255, 255, 255, 0.08);
    --tray: #111827;
    --field: #182033;
    --field-line: rgba(255, 255, 255, 0.08);
    --ink: #f1f5f9;
    --ink-2: #b0bdd0;
    --ink-3: #8a9bb4;
    --ink-faint: rgba(255, 255, 255, 0.20);
    --ink-body: #c3cedc;
    --ink-head: #dbe3ee;
    --accent: #6e9dff;
    --accent-soft: rgba(110, 157, 255, 0.14);
    --accent-ring: rgba(110, 157, 255, 0.45);
    --in: #34d399;
    --in-soft: rgba(52, 211, 153, 0.13);
    --out: #ff6b86;
    --out-soft: rgba(255, 107, 134, 0.13);
    --transfer: #6e9dff;
    --transfer-soft: rgba(110, 157, 255, 0.13);
    --tl-out: #ff6b86;
    --tl-in: #34d399;
    --in-wash: rgba(52, 211, 153, 0.07);
    --in-edge: rgba(52, 211, 153, 0.16);
    --in-ink: #a7f3d0;
    --in-deep: #34d399;
    --in-meta: rgba(110, 231, 183, 0.85);
    --invest: #a3a0ff;
    --invest-soft: rgba(163, 160, 255, 0.13);
    --invest-wash: rgba(163, 160, 255, 0.06);
    --invest-edge: rgba(163, 160, 255, 0.18);
    --invest-tile: rgba(163, 160, 255, 0.12);
    --attn: #ffb86a;
    --attn-soft: rgba(255, 184, 106, 0.13);
    --attn-wash: rgba(255, 184, 106, 0.06);
    --attn-edge: rgba(255, 184, 106, 0.16);
    --attn-mark: #ffb86a;
    --attn-line: rgba(255, 184, 106, 0.22);
    --attn-ink: #f5d2ad;
    --d-today: #ff8a4c;
    --d-today-soft: rgba(255, 138, 76, 0.13);
    --d-time: #22d3ee;
    --d-time-soft: rgba(34, 211, 238, 0.13);
    --d-money: #34d399;
    --d-money-soft: rgba(52, 211, 153, 0.13);
    --d-work: #a3a0ff;
    --d-work-soft: rgba(163, 160, 255, 0.13);
    --d-life: #fb64b6;
    --d-life-soft: rgba(251, 100, 182, 0.13);
    --d-talk: #b0bdd0;
    --d-talk-soft: rgba(176, 189, 208, 0.13);
    --c-1: #38bdf8;
    --c-2: #6e9dff;
    --c-3: #a78bfa;
    --c-4: #e879f9;
    --c-5: #a3a0ff;
    --c-6: #f9a8d4;
    --c-none: #4a5a70;
    --c-grid: rgba(255, 255, 255, 0.10);
    --c-recorded: #34d399;
    --c-projected: #7c8ba1;
    --c-floor: #fbbf24;
    --c-floor-ink: #fbbf24;
    --grain: 0;
    --glow-on: 0;
    --w-ground: #151210;
    --w-tray: #1a1613;
    --w-field: #231e1a;
    --w-field-line: rgba(255, 255, 255, 0.08);
    --ent-person: var(--d-today);
    --ent-person-soft: var(--d-today-soft);
    --ent-person-line: rgba(255, 138, 76, 0.18);
    --ent-person-wash: rgba(255, 138, 76, 0.12);
    --ent-thing: var(--d-life);
    --ent-thing-soft: var(--d-life-soft);
    --ent-thing-line: rgba(251, 100, 182, 0.18);
    --ent-thing-wash: rgba(251, 100, 182, 0.12);
    --ent-place: var(--d-time);
    --ent-place-soft: var(--d-time-soft);
    --ent-place-line: rgba(34, 211, 238, 0.18);
    --ent-place-wash: rgba(34, 211, 238, 0.12);
    --ent-project: #c4b5fd;
    --ent-project-soft: rgba(196, 181, 253, 0.13);
    --ent-project-line: rgba(196, 181, 253, 0.18);
    --ent-project-wash: rgba(196, 181, 253, 0.12);
    --wk-ink: #a3a0ff;
    --wk-near: #6e9dff;
    --wk-fact: rgba(255, 255, 255, 0.03);
    --wk-pill-ink: #67e8f9;
    --wk-pill-wash: rgba(34, 211, 238, 0.10);
    --wk-pill-line: rgba(34, 211, 238, 0.20);
    --ti-block: rgba(34, 211, 238, 0.08);
    --ti-block-line: rgba(34, 211, 238, 0.22);
    --ti-block-ink: #a5f3fc;
    --ti-today-ink: #67e8f9;
    --ti-on-time: #06222b;
    --today-ground: #0b1020;
    --today-wash: rgba(255, 138, 76, 0.05);
    --tl-block: #a3a9ff;
    --tl-attn: #ffc94d;
    --attn-deep: #fcd9b0;
    --attn-meta: rgba(255, 184, 106, 0.85);
    --w-card: #1f1b18;
    --w-card-line: rgba(255, 255, 255, 0.06);
    --w-sheet-line: rgba(255, 255, 255, 0.07);
    --w-ink: #f5f5f4;
    --w-ink-2: #c2bab3;
    --w-ink-3: #9c938b;
    --w-ink-body: #d6d3d1;
    --w-ink-deep: #e7e5e4;
    --w-soft: rgba(255, 255, 255, 0.07);
    --w-soft-2: rgba(255, 255, 255, 0.04);
    --w-rim: rgba(255, 255, 255, 0.10);
    --w-float: rgba(31, 27, 24, 0.8);
    --w-chip: rgba(31, 27, 24, 0.9);
    --w-down: #34d399;
    --w-laptop-a: rgba(148, 163, 184, 0.18); --w-laptop-b: rgba(148, 163, 184, 0.08); --w-laptop: #b0bdd0;
    --w-headphones-a: rgba(163, 160, 255, 0.20); --w-headphones-b: rgba(163, 160, 255, 0.08); --w-headphones: #a3a0ff;
    --w-armchair-a: rgba(255, 184, 106, 0.20); --w-armchair-b: rgba(255, 184, 106, 0.08); --w-armchair: #ffb86a;
    --w-camera-a: rgba(255, 255, 255, 0.09); --w-camera-b: rgba(255, 255, 255, 0.04); --w-camera: #c2bab3;
    --w-plane-a: rgba(34, 211, 238, 0.20); --w-plane-b: rgba(34, 211, 238, 0.08); --w-plane: #22d3ee;
    --w-attn-wash: rgba(255, 184, 106, 0.07);
    --w-attn-edge: rgba(255, 184, 106, 0.22);
    --w-attn-title: #ffd3a3;
    --w-attn-body: #f5d2ad;
    --link: #6e9dff;
  }
}

:root[data-theme="dark"] {
  --ground: #0b1020;
  --ground-2: #111827;
  --m2: #141b2d;
  --m2-line: rgba(255, 255, 255, 0.07);
  --m2-hi: rgba(255, 255, 255, 0.05);
  --m2-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  --pill-line: rgba(255, 255, 255, 0.08);
  --m3: #182033;
  --m3-line: rgba(255, 255, 255, 0.10);
  --m3-shadow: 0 18px 44px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);
  --m4: #141b2d;
  --m4-2: #182033;
  --m4-line: rgba(255, 255, 255, 0.08);
  --tray: #111827;
  --field: #182033;
  --field-line: rgba(255, 255, 255, 0.08);
  --ink: #f1f5f9;
  --ink-2: #b0bdd0;
  --ink-3: #8a9bb4;
  --ink-faint: rgba(255, 255, 255, 0.20);
  --ink-body: #c3cedc;
  --ink-head: #dbe3ee;
  --accent: #6e9dff;
  --accent-soft: rgba(110, 157, 255, 0.14);
  --accent-ring: rgba(110, 157, 255, 0.45);
  --in: #34d399;
  --in-soft: rgba(52, 211, 153, 0.13);
  --out: #ff6b86;
  --out-soft: rgba(255, 107, 134, 0.13);
  --transfer: #6e9dff;
  --transfer-soft: rgba(110, 157, 255, 0.13);
  --tl-out: #ff6b86;
  --tl-in: #34d399;
  --in-wash: rgba(52, 211, 153, 0.07);
  --in-edge: rgba(52, 211, 153, 0.16);
  --in-ink: #a7f3d0;
  --in-deep: #34d399;
  --in-meta: rgba(110, 231, 183, 0.85);
  --invest: #a3a0ff;
  --invest-soft: rgba(163, 160, 255, 0.13);
  --invest-wash: rgba(163, 160, 255, 0.06);
  --invest-edge: rgba(163, 160, 255, 0.18);
  --invest-tile: rgba(163, 160, 255, 0.12);
  --attn: #ffb86a;
  --attn-soft: rgba(255, 184, 106, 0.13);
  --attn-wash: rgba(255, 184, 106, 0.06);
  --attn-edge: rgba(255, 184, 106, 0.16);
  --attn-mark: #ffb86a;
  --attn-line: rgba(255, 184, 106, 0.22);
  --attn-ink: #f5d2ad;
  --d-today: #ff8a4c;
  --d-today-soft: rgba(255, 138, 76, 0.13);
  --d-time: #22d3ee;
  --d-time-soft: rgba(34, 211, 238, 0.13);
  --d-money: #34d399;
  --d-money-soft: rgba(52, 211, 153, 0.13);
  --d-work: #a3a0ff;
  --d-work-soft: rgba(163, 160, 255, 0.13);
  --d-life: #fb64b6;
  --d-life-soft: rgba(251, 100, 182, 0.13);
  --d-talk: #b0bdd0;
  --d-talk-soft: rgba(176, 189, 208, 0.13);
  --c-1: #38bdf8;
  --c-2: #6e9dff;
  --c-3: #a78bfa;
  --c-4: #e879f9;
  --c-5: #a3a0ff;
  --c-6: #f9a8d4;
  --c-none: #4a5a70;
  --c-grid: rgba(255, 255, 255, 0.10);
  --c-recorded: #34d399;
  --c-projected: #7c8ba1;
  --c-floor: #fbbf24;
  --c-floor-ink: #fbbf24;
  --grain: 0;
  --glow-on: 0;
  --w-ground: #151210;
  --w-tray: #1a1613;
  --w-field: #231e1a;
  --w-field-line: rgba(255, 255, 255, 0.08);
  --ent-person: var(--d-today);
  --ent-person-soft: var(--d-today-soft);
  --ent-person-line: rgba(255, 138, 76, 0.18);
  --ent-person-wash: rgba(255, 138, 76, 0.12);
  --ent-thing: var(--d-life);
  --ent-thing-soft: var(--d-life-soft);
  --ent-thing-line: rgba(251, 100, 182, 0.18);
  --ent-thing-wash: rgba(251, 100, 182, 0.12);
  --ent-place: var(--d-time);
  --ent-place-soft: var(--d-time-soft);
  --ent-place-line: rgba(34, 211, 238, 0.18);
  --ent-place-wash: rgba(34, 211, 238, 0.12);
  --ent-project: #c4b5fd;
  --ent-project-soft: rgba(196, 181, 253, 0.13);
  --ent-project-line: rgba(196, 181, 253, 0.18);
  --ent-project-wash: rgba(196, 181, 253, 0.12);
  --wk-ink: #a3a0ff;
  --wk-near: #6e9dff;
  --wk-fact: rgba(255, 255, 255, 0.03);
  --wk-pill-ink: #67e8f9;
  --wk-pill-wash: rgba(34, 211, 238, 0.10);
  --wk-pill-line: rgba(34, 211, 238, 0.20);
  --ti-block: rgba(34, 211, 238, 0.08);
  --ti-block-line: rgba(34, 211, 238, 0.22);
  --ti-block-ink: #a5f3fc;
  --ti-today-ink: #67e8f9;
  --ti-on-time: #06222b;
  --today-ground: #0b1020;
  --today-wash: rgba(255, 138, 76, 0.05);
  --tl-block: #a3a9ff;
  --tl-attn: #ffc94d;
  --attn-deep: #fcd9b0;
  --attn-meta: rgba(255, 184, 106, 0.85);
  --w-card: #1f1b18;
  --w-card-line: rgba(255, 255, 255, 0.06);
  --w-sheet-line: rgba(255, 255, 255, 0.07);
  --w-ink: #f5f5f4;
  --w-ink-2: #c2bab3;
  --w-ink-3: #9c938b;
  --w-ink-body: #d6d3d1;
  --w-ink-deep: #e7e5e4;
  --w-soft: rgba(255, 255, 255, 0.07);
  --w-soft-2: rgba(255, 255, 255, 0.04);
  --w-rim: rgba(255, 255, 255, 0.10);
  --w-float: rgba(31, 27, 24, 0.8);
  --w-chip: rgba(31, 27, 24, 0.9);
  --w-down: #34d399;
  --w-laptop-a: rgba(148, 163, 184, 0.18); --w-laptop-b: rgba(148, 163, 184, 0.08); --w-laptop: #b0bdd0;
  --w-headphones-a: rgba(163, 160, 255, 0.20); --w-headphones-b: rgba(163, 160, 255, 0.08); --w-headphones: #a3a0ff;
  --w-armchair-a: rgba(255, 184, 106, 0.20); --w-armchair-b: rgba(255, 184, 106, 0.08); --w-armchair: #ffb86a;
  --w-camera-a: rgba(255, 255, 255, 0.09); --w-camera-b: rgba(255, 255, 255, 0.04); --w-camera: #c2bab3;
  --w-plane-a: rgba(34, 211, 238, 0.20); --w-plane-b: rgba(34, 211, 238, 0.08); --w-plane: #22d3ee;
  --w-attn-wash: rgba(255, 184, 106, 0.07);
  --w-attn-edge: rgba(255, 184, 106, 0.22);
  --w-attn-title: #ffd3a3;
  --w-attn-body: #f5d2ad;
  --link: #6e9dff;
}

/* ─────────────────────────────────────────────────────────────── reset */

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

/*
 * Plan 4: no scrollbar anywhere - the page, the tray, a sheet, a strip. Scrolling still works by
 * wheel, touch, keyboard and trackpad; only the bar is not drawn (the owner asked for it hidden).
 */
* { scrollbar-width: none; }
*::-webkit-scrollbar { display: none; width: 0; height: 0; }
* { margin: 0; }

/*
 * Element normalisation. Not optional decoration - the component rules below assume it.
 *
 * Dropping these three lines in a rewrite left every evidence toggle rendering as a default
 * grey system button, because `.ev-text` styles colour and border and relies on the reset for
 * the rest. Found by looking at the running page: the tests all passed, because a button with
 * the wrong background is still a button with the right text.
 */
button, input, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }

/*
 * The icon set (UX-013 §3): Lucide, vendored as one inline sprite in index.html.
 *
 * Lucide draws on a 24-unit grid with a stroke of 2, and the Figma keeps that ratio at every
 * size it uses (1 at 12px, 1.5 at 18px, 1.83 at 22px). So the weight lives here, once, in grid
 * units: an icon scales with its box and its line thickness keeps the drawn proportion. The
 * symbols carry no stroke of their own, so a rule that sets a width on one use still reaches
 * it. The colour is the text colour around the icon.
 *
 * The sprite itself takes no space. It is not display:none, because some engines stop
 * resolving <use> into a sprite that is not rendered.
 */
.i {
  width: 1em; height: 1em; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/*
 * Talk's mark: the calligraphic R from Computer Modern (cmsy10, AMS, SIL OFL; notice in
 * icons/OFL-cmsy10.txt), as the Figma sets it (UX-013 §7). A filled outline, not a stroke, so
 * it opts out of the base svg rule. Each place that shows it sets its size.
 */
.talk-mark { fill: currentColor; stroke: none; }
.rail button .talk-mark { width: 16px; height: 13.82px; justify-self: center; }

/*
 * The `[hidden]` guard, and it must stay FIRST.
 *
 * Any element given a `display` rule silently stops being hideable by the attribute, because
 * a class selector outbids the UA stylesheet's `[hidden] { display: none }`. That has already
 * happened once here: a pane with `display: flex` stayed on screen while the script believed
 * it was hidden, and every surface rendered at once.
 *
 * Declared before everything it defends against, so ordering cannot bite either.
 */
[hidden] { display: none !important; }

html, body { height: 100%; }

/*
 * ── Pull-to-refresh does nothing, because a reload would throw away a thought ──────────
 *
 * `overscroll-behavior-y` was `auto`, so on Android a downward pull at the top of any surface
 * reloads the page. Two reasons that is wrong here, and the first is the serious one:
 *
 *   · **It discards unsent capture text.** The capture field deliberately keeps what you typed
 *     when a send fails — "the text is put back rather than pretending the capture happened".
 *     A browser reload defeats that, silently, from a gesture you did not mean to make.
 *   · **There is nothing to refresh.** The product re-derives on write, and `refresh()` exists
 *     for records arriving over sync. A manual refresh gesture implies staleness the product
 *     does not have and cannot fix by reloading.
 *
 * `contain` keeps the scroll chaining inside the page without disabling scrolling itself.
 */
html { overscroll-behavior-y: contain; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ───────────────────────────────────────────── M0 · the environment */

.ground {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background: linear-gradient(176deg, var(--ground) 0%, var(--ground-2) 100%);
}
/*
 * The two soft lights exist for ONE reason, stated at the top of this file: `backdrop-filter`
 * refracts what is behind it, and behind a flat fill there is nothing to refract. That is a
 * dark-theme argument. Under UX-012 the light theme's materials are opaque paper — M2, M3 and
 * M4 are all `#ffffff` — so there is no glass for the lights to feed, and at 74vw they render
 * as a blue wash in one corner and a peach one in the other. Which is not atmosphere on paper,
 * it is a printing fault.
 */
.glow { position: absolute; border-radius: 50%; filter: blur(20px); opacity: var(--glow-on); }
.glow-a {
  top: -22%; left: -12%; width: 74vw; height: 74vw; max-width: 1100px; max-height: 1100px;
  background: radial-gradient(circle, var(--accent-soft), transparent 66%);
}
.glow-b {
  bottom: -28%; right: -14%; width: 62vw; height: 62vw; max-width: 900px; max-height: 900px;
  background: radial-gradient(circle, var(--ember-soft), transparent 64%);
}
/*
 * Still, now. `--glow-on` is 0 in every theme, and the two lights still drifted forever - two
 * 20px blurs, 74vw wide, repainted each frame for nothing on screen (review, 30 September). They
 * stay, off by token (UX-012 §4); if a theme ever turns them on, they are still, not moving.
 */

.grain {
  position: absolute; inset: 0; opacity: var(--grain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ───────────────────────────────────────────── the frame */

.frame {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr) 0;
  min-height: 100%;
  transition: grid-template-columns var(--dur-sheet) var(--ease-sheet);
}
.frame.talking { grid-template-columns: var(--rail) minmax(0, 1fr) var(--dock); }

/* ───────────────────────────────────────────── M2 · the rail */

.rail {
  position: sticky; top: 0; align-self: start; height: 100vh;
  display: flex; flex-direction: column;
  padding: 22px 12px 18px;
  border-right: 1px solid var(--m2-line);
  background: var(--m2);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: var(--m2-shadow);
}
/*
 * A browser before its passphrase (ADR-041, cloud/web/browser.js): no screen of the product exists
 * yet, so the rail keeps its column - nothing reflows when Raai opens - but shows nothing and takes
 * no focus. Its places would do nothing until then, and a control that does nothing is not shown.
 */
.frame[data-locked] > .rail { visibility: hidden; }
.rail-mark {
  font-size: var(--t-meta); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-3); margin: 0 0 22px; padding-left: 10px;
}
.places { display: flex; flex-direction: column; gap: 2px; }
.rail-foot { margin-top: auto; display: flex; flex-direction: column; gap: 2px;
  padding-top: 14px; border-top: 1px solid var(--m2-line); }

.rail button {
  display: grid; grid-template-columns: 18px 1fr auto; align-items: center; gap: 10px;
  width: 100%; min-height: 38px; padding: 0 10px;
  font: inherit; font-size: var(--t-body); color: var(--ink-2);
  background: none; border: 0; border-radius: var(--r-sm);
  cursor: pointer; text-align: left;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
/* Size only: every glyph here is a Lucide symbol (.i sets its weight) or Talk's filled "R". */
.rail button svg { width: 18px; height: 18px; }
.rail button:hover { color: var(--ink); background: var(--m2-hi); }
/* Active is ink (UX-013 §2), on both transports. The place's hue is for its marks and charts,
   and --accent stays keyboard focus, so a focused place never looks like the active one. */
.rail button[aria-current="page"] {
  color: var(--ink); background: var(--ground-2); font-weight: 600;
}
.rail button[aria-pressed="true"] { color: var(--ink); background: var(--m2-hi); }
.rail-min { font-size: var(--t-meta) !important; color: var(--ink-3) !important; }
.rail-min:hover { color: var(--ink-2) !important; }
.rail-min[aria-expanded="true"] { color: var(--ink) !important; background: var(--m2-hi) !important; }
.rail kbd {
  font: inherit; font-size: var(--t-micro); color: var(--ink-3);
  letter-spacing: 0.04em;
}

/* ───────────────────────────────────────────── M1 · the surface */

.surface {
  min-width: 0;
  padding: 40px 40px 120px;
  display: flex; flex-direction: column; gap: 0;
}
.head { position: relative; max-width: var(--measure); margin-bottom: 26px; }
.head h1 {
  font-size: var(--t-title); line-height: 1.14; letter-spacing: -0.026em; font-weight: 600;
  margin: 0; color: var(--ink);
}
/* The part of the day, under the date. One family since UX-013; it was serif under UX-006. */
.head-sub {
  font-family: var(--sans); font-size: var(--t-prose); line-height: 1.5;
  color: var(--ink-2); margin: 5px 0 0;
}
/* The phone reaches Settings from the header, not from a sixth dock destination. It is hidden
 * on the desk, where the rail remains the utility's established home. */
/* On Money the reading is the H1 (B-03), so the date and greeting step aside there; the
   phone's search and settings buttons stay, over the reading's right edge (see .m-h1). */
body:has(#money:not([hidden])) .head h1, body:has(#money:not([hidden])) .head-sub { display: none; }
body:has(#money:not([hidden])) .head { margin-bottom: 0; }
/* Today draws its own header (1:533, today.js): the part of day over the date, the reading under. */
body:has(#today:not([hidden])) .head h1, body:has(#today:not([hidden])) .head-sub { display: none; }
body:has(#today:not([hidden])) .head { margin-bottom: 0; }
.head-settings { display: none; }
.head-search { display: none; }

/*
 * ── A READING MEASURE WAS BEING APPLIED TO A LEDGER (UX-011.5) ────────────────────────
 *
 * `.pane` was `--measure`, 66ch, on every surface. 66ch is the right width for a sentence
 * about your life and the wrong width for your accounts: measured on a 1400px viewport, a
 * 188px rail, a ~575px column and ~800px of nothing.
 *
 * The fix is not "make it wider" — it is that **the measure belongs to prose, not to the
 * page**. Narration already caps its own width (`.n-reading`, `.t-lede`, `.w-lede`, `.ti-lede`), so a data pane
 * can take the width it needs without a single sentence stretching.
 */
.pane { max-width: var(--measure-data); }
.pane[hidden] { display: none; }

/*
 * ── SECTION WEIGHT IS THREE TIERS, NOT ONE STYLE TEN TIMES (UX-011.2) ─────────────────
 *
 * There was exactly one section style, and Today rendered TEN of it — NEEDS YOU, WHAT IS
 * MOVING, Waiting on others, Others waiting on you, Coming up, SMALL THINGS, AT THE SHOP,
 * CALLS TO MAKE, TO BRING, LOOSE THOUGHTS — at three nesting levels, all identical. When
 * every heading has the same weight, none of them is a heading.
 *
 *   BAND   the major division of a page. Sentence case, quiet, generous space above.
 *          At most one band is the page's answer; the rest are its supporting parts.
 *   GROUP  the repeatable one. Wide-tracked caps micro — unchanged, because it was never
 *          the problem on its own.
 *   RUN    a label that sits ON a row rather than above a list. Inline, dimmest.
 *
 * Sections are still separated by SPACE, not by rules or boxes (§21) — tiering the weight
 * is what lets that keep working as a page gets fuller.
 */
.band { margin-top: 56px; }
.band:first-child { margin-top: 0; }
/* One section heading across the product (review, 30 September): 16 / 600 / -0.025em, in ink. There
   were fourteen variants at three sizes, two weights and six colours. */
.band-label {
  font-size: var(--t-date); font-weight: 600; letter-spacing: -0.025em;
  color: var(--ink); margin: 0 0 18px;
}

.group { margin-top: 44px; }
.group:first-child { margin-top: 0; }
.band > .group:first-of-type { margin-top: 0; }
/*
 * The uppercase group label, defined ONCE (review, 30 September). It was declared three times -
 * here, in the list-pane block and in the micro-label group - and what rendered was whichever came
 * last: weight 500, 0.12em, the list padding, and the faint third ink. These are those values,
 * with the second ink: a section's label is read, which UX-013 §5 keeps --ink-3 from carrying.
 * Surfaces that reuse it still reset the padding (.a-glabel, #assistant, .a-half).
 */
.group-label {
  padding: 15px 20px 7px; margin: 0 0 12px;
  font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-2);
}

.run-label {
  font-size: var(--t-meta); font-weight: 500; color: var(--ink-3);
  letter-spacing: 0.01em;
}

/* ───────────────────────────────────────────── M2 · capture */

.capture { max-width: var(--measure); margin-bottom: 30px; }
/* On the desk the field is the column's width, so it and the page under it line up (UX-017). */
@media (min-width: 861px) { .capture, .head { max-width: var(--desk-col); } }
/* The Figma's capture pill (D0c): the field material, radius 20, 50px tall with its border. */
#capture-form {
  background: var(--field);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 1px solid var(--field-line);
  box-shadow: var(--m2-shadow);
  border-radius: var(--r-lg);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
#capture-form:focus-within {
  border-color: var(--accent);
  box-shadow: var(--m2-shadow), 0 0 0 3px var(--accent-soft);
}
#capture {
  display: block; width: 100%; min-height: 48px; max-height: 40vh;
  padding: 13.5px 12px; resize: none; overflow-y: auto;
  font: inherit; font-size: var(--t-body); line-height: 1.375; color: var(--ink);
  background: none; border: 0; outline: none;
}
#capture::placeholder { color: var(--ink-2); }

/*
 * No blur in either theme. It was kept for dark on the claim that dark's M3 is a translucent wash;
 * it is not - dark --m2, --m3 and --field are opaque - so a 20px blur was composited under the rail
 * and the capture field for no visible pixel (review, 30 September).
 */

/* The brief reply: a row's meta line (1:3671), shown for a moment under the field. */
.reply {
  display: flex; align-items: center; min-height: 20px;
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-3); margin: 9px 0 0; padding: 0 2px;
  opacity: 0; transform: translateY(-3px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.reply.show { color: var(--ink-2); opacity: 1; transform: none; }

/* A failed write is not an answer and not an unknown fact. Keep it neutral — direction colour
   belongs to Money — but give the admission enough weight that it cannot be mistaken for the
   ordinary quiet reply that precedes a successful capture. */
.reply.show.reply-error { color: var(--ink); }
.reply.show.reply-error::before {
  content: ''; width: 5px; height: 5px; flex: 0 0 auto; border-radius: 50%;
  background: var(--ink-3); margin-right: 7px;
}

/*
 * Offered, never routed. A question was still kept as a record (§14). Since I1 the offer is the
 * pill Money draws (1:3418) beside its words - an action is a pill in every frame, and the focus
 * blue it used to wear means keyboard focus, not "tap here".
 */
.offer {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 10px; padding: 10px 2px 0; border-top: 1px solid var(--m2-line);
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
}
.offer button {
  appearance: none; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 8px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
}
.offer button:hover { color: var(--ink); }
.offer button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ───────────────────────────────────────────── rows — M1, no container */

.row {
  display: grid; grid-template-columns: 1fr auto; gap: 10px 14px;
  align-items: start; padding: 11px 0;
  border-bottom: 1px solid var(--m2-line);
}
.row:last-child { border-bottom: 0; }
.row-acts { display: flex; gap: 6px; flex-wrap: wrap; }

.act {
  font: inherit; font-size: var(--t-meta); color: var(--ink-2);
  background: var(--m2); border: 1px solid var(--m2-line);
  border-radius: var(--r-sm); padding: 5px 11px; cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.act:hover { color: var(--ink); border-color: var(--accent-ring); }
.act:disabled { opacity: 0.45; cursor: default; }

/*
 * A fact chip. NOT glass (law 3): tinted ink with a hairline, on a 22px box where a blur
 * would sample outside itself and cost more than it shows.
 *
 * Every chip is a door. Any figure, date or name — including inside composed prose — opens
 * its evidence (§26). One component, used everywhere, no exceptions.
 */
/*
 * ── A door, not a box (UX-011 "one accent, earned") ───────────────────────────────────
 *
 * This was a filled accent rectangle with its own border and corner radius, set on every
 * figure, date and name — including inside running prose. *"You promised Sara send her the
 * deck by 11 September. You are waiting on garage for call — that was 3 days ago."* rendered
 * as four filled boxes in two sentences, which reads as highlighter, not as a sentence you
 * can open. The accent was carrying no state at all; it was marking that something is
 * tappable, four times a line.
 *
 * So a chip is an underline. §26 is unchanged and the door is unchanged — every figure, date
 * and name still opens its record. The fill arrives on hover and focus, where an affordance
 * is actually being offered, instead of standing permanently on every noun.
 */
/*
 * `text-decoration`, not `border-bottom`, and the difference is the whole reason this works.
 * A border follows the BOX, so the touch rule's horizontal padding stretched the underline
 * past the word and opened a visible gap either side of every name in a sentence. An
 * underline follows the TEXT, so the tap target can be as large as a thumb needs while the
 * mark stays exactly as wide as the word it marks.
 *
 * `display: inline` for the same reason: a chip is a word in a sentence, and an inline-block
 * sits in the line box as an object rather than flowing with the words around it.
 */
/*
 * `line-height: 1` is what keeps the padding free.
 *
 * A `<button>` computes to `inline-block` whatever `display` asks for, so its whole box sits
 * in the line and any box taller than the line pushes the paragraph's lines apart. With the
 * line-height collapsed onto the glyphs, the padding fills the space the leading was already
 * using: the chip's box stays the height of a line, the tap area grows, and the paragraph
 * does not open up. Baseline alignment keeps the word exactly where it was.
 */
.chip {
  font: inherit; font-weight: 500; font-variant-numeric: tabular-nums;
  display: inline; line-height: 1; color: var(--ink); background: none;
  border: 0; border-radius: var(--r-xs); padding: 3px 1px; margin: 0;
  text-decoration: underline; text-decoration-color: var(--accent-ring);
  text-decoration-thickness: 1px; text-underline-offset: 3px;
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.chip:hover, .chip:focus-visible {
  background: var(--accent-soft); text-decoration-color: var(--accent);
}

/* The provenance line. Small, permanent, never behind a disclosure (§26). */
.prov {
  font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-3);
  margin: 10px 0 0; font-variant-numeric: tabular-nums;
}
.prov b { color: var(--ink-2); font-weight: 600; }

/*
 * §26: the LINE is never behind a disclosure; the GROUNDS are what a disclosure is for.
 * So the summary is the line, visible exactly as before, and opening it lists the fact set.
 */
.prov-open { margin-top: 10px; }
.prov-open > .prov {
  margin: 0; cursor: pointer; list-style: none; display: block;
}
.prov-open > .prov::-webkit-details-marker { display: none; }
/*
 * The affordance is permanent, not revealed on hover. UX-010 makes the phone primary and a
 * phone has no hover, so a hover-only affordance is simply invisible on the device most of
 * this gets read on — the same mistake twice over in this refactor if it shipped.
 */
.prov-open > .prov::after {
  content: "· where from"; color: var(--ink-3); margin-left: 6px;
  border-bottom: 1px solid var(--m2-line);
}
.prov-open:hover > .prov::after,
.prov-open > .prov:focus-visible::after { color: var(--ink-2); }
.prov-open[open] > .prov::after { content: "· hide"; }
/* Each limit is its own sentence. They used to be glued into one ungrammatical run. */
.prov-note { margin-top: 6px; }

/*
 * Who is speaking, for someone who cannot see the page.
 *
 * The two voices are carried by indent, weight and a rule — none of which a screen reader
 * can convey. §24 forbids a distinction made by font alone, and this is the surface where the
 * distinction matters most.
 */
.voice {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* Plan 4: Raai's own answer under Raai AI's, folded; the summary is a quiet line you can open. */
.turn-holds { margin-top: 8px; }
.turn-holds-sum { cursor: pointer; font-size: var(--t-meta); font-weight: 600; color: var(--ink-2); }
.turn-holds[open] > .turn-holds-sum { margin-bottom: 6px; }

/* ───────────────────────────────────────────── M3 · the conversation dock */

/*
 * ── The dock is glass only where there is something to refract (UX-012 law 1) ─────────────
 *
 * Law 1, stated at the top of this file: "Glass belongs over the ground, or over something
 * still... On light this mostly means: it is not glass, it is paper." Light's `--m3` is
 * `#ffffff` — fully opaque — so a blur composited underneath it is covered by solid paint and
 * produces no visible pixel difference from `backdrop-filter: none`, ever. It still paid the
 * compositing cost on every frame. Dark's `--m3` was said here to be a translucent wash; it is
 * #182033, opaque, so the dark blur was the same cost for the same nothing, and it is gone too
 * (review, 30 September).
 */
.dock {
  /* Conversation is a neutral aide over the current place, never a sixth destination, so since
   * I2 it carries no hue at all: its turns are the frames' neutral cards (UX-015). */
  position: sticky; top: 0; align-self: start; height: 100vh;
  display: flex; flex-direction: column; overflow: hidden;
  border-left: 1px solid var(--m3-line);
  background: var(--m3);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: var(--m3-shadow);
}
.dock[hidden] { display: none; }

/*
 * ── I2: the conversation, composed from drawn components (UX-015) ─────────────────────
 *
 * No frame draws Talk, so every part is one a frame draws: the head as the reached-layer bar's
 * row - what the thread has in mind on the left, a 36px round close on the right (17:10) - each
 * turn as one Activity card (1:3671), your words quoted as Life's timeline quotes what you said
 * (1:319), the answer as the row's words with each value a tappable emphasis, the way in to a
 * surface and every choice as the pill Money draws (1:3418), the grounds as rows with the row's
 * chip for their F-number, and the ask field as the capture field (D0c).
 */
.dock-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 8px 12px 16px; border-bottom: 1px solid var(--m3-line); min-height: 60px;
}
/*
 * The context spine. A LITERAL readout of what the thread knows, not a summary of it —
 * removing a chip removes the context from every future turn, which is what makes it a
 * privacy control rather than decoration (§5). Each is a pill with its own remove.
 */
.spine { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; }
/* Talk cannot answer on this device yet (DR-07): one plain line above the turns, in ink. */
.talk-needs { margin: 12px 16px 0; font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2); }
/* With nothing in the thread's mind the head is the dock's name (plan 4: "Nothing in mind yet." said nothing). */
.spine:empty::before {
  content: "Talk"; font-size: var(--t-date); font-weight: 650; letter-spacing: -0.02em; color: var(--ink);
}
.spine-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font: inherit; font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  background: var(--m2); border: 1px solid var(--pill-line);
  border-radius: var(--r-pill); padding: 4px 4px 4px 12px;
}
.spine-chip button {
  font: inherit; line-height: 1; color: var(--ink-3);
  background: none; border: 0; cursor: pointer; padding: 4px 6px; border-radius: var(--r-pill);
}
.spine-chip button:hover { color: var(--ink); }
.spine-chip button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The reached-layer bar's round button (17:10), closing the dock. */
.dock-close {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0; border: 0; border-radius: var(--r-pill);
  font: inherit; color: var(--ink-2); background: none; cursor: pointer; line-height: 0;
}
.dock-close svg { width: 20px; height: 20px; }
.dock-close:hover { color: var(--ink); }
.dock-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.turns { flex: 1; overflow-y: auto; padding: 16px; display: flex;
  flex-direction: column; gap: 12px; }
.turns:empty::before {
  content: "Ask about your money, your time, who you are waiting on, or what changed.";
  font-size: var(--t-meta); font-weight: 500; color: var(--ink-2); line-height: 1.5; padding: 0 8px;
}

/*
 * No bubbles, no avatar, no name. Each exchange is one card (1:3671) - where one ends and the
 * next begins is the card's edge, which is what the rule between turns used to say - and inside
 * it the two voices are distinguished by weight, the quote marks and the structural labels
 * (.voice), so the distinction is never conveyed by font only (§24).
 */
.turn {
  padding: 16px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
/* Your own words, quoted as Life quotes everything you said (1:319); the marks are drawn here,
 * the words are exactly yours. */
.turn-you {
  font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink);
  margin: 0; overflow-wrap: anywhere;
}
.turn-you::before { content: '“'; }
.turn-you::after { content: '”'; }
/* The answer: the reading weight of the card, at the body tier. */
.turn-said {
  font-family: var(--sans); font-size: var(--t-body); line-height: 1.6; color: var(--ink);
  margin: 8px 0 0;
}
.turn-said.thinking { color: var(--ink-2); }
/* A found record per line, never one run-on sentence of several (talk.js). */
.turn-line { display: block; }
.turn-line + .turn-line { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--m2-hi); }
/*
 * A value in the answer opens the sentence it came from. Emphasised in ink, as Money's subline
 * emphasises its figures (1:3418), with a quiet underline so it still reads as a door. The
 * underline was the focus blue, which means keyboard focus (B-05).
 */
.turn-said .chip { font-weight: 600; text-decoration-color: var(--m3-line); }
.turn-said .chip:hover, .turn-said .chip:focus-visible { background: var(--m2-hi); text-decoration-color: var(--ink-3); }
/* The one way in to a surface: the pill Money draws (1:3418). */
.turn-open {
  display: inline-flex; align-items: center; margin-top: 12px; appearance: none; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 8px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
}
.turn-open:hover { color: var(--ink); }
.turn-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/*
 * The grounds, answered with no model and no round trip (§5 turn 3). Each fact is a row, its
 * F-number the Activity row's chip (1:3671); no panel around them, because the rows and their
 * numbers already say "these are the grounds" (UX-011.1).
 */
.grounds { margin: 10px 0 0; }
.grounds p { margin: 0; padding: 8px 0; font-size: var(--t-meta); font-weight: 500; line-height: 1.5; color: var(--ink-2); }
.grounds p + p { border-top: 1px solid var(--m2-hi); }
.grounds .gid {
  display: inline-block; margin-right: 8px; padding: 0 6px;
  font-size: var(--t-micro); font-weight: 500; line-height: 1.6; color: var(--ink-2);
  background: var(--m2); border: 1px solid var(--m3-line); border-radius: var(--r-xs);
  font-variant-numeric: tabular-nums;
}

/* The ask field: the capture field (D0c), in the dock's own foot. */
.dock-ask { padding: 12px 16px 16px; border-top: 1px solid var(--m3-line); }
#ask {
  display: block; width: 100%; min-height: 48px; max-height: 30vh;
  padding: 13.5px 12px; resize: none; overflow-y: auto;
  font: inherit; font-size: var(--t-body); line-height: 1.375; color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line);
  border-radius: var(--r-lg); box-shadow: var(--m2-shadow); outline: none;
}
#ask:focus { border-color: var(--accent); box-shadow: var(--m2-shadow), 0 0 0 3px var(--accent-soft); }
#ask::placeholder { color: var(--ink-3); }

/*
 * `.ledger`, `.ledger-row`, `.ledger-amt` and `.ledger-near` had no consumer left in any
 * client file — Money and the single-account page (CAP-104) both render their transaction
 * lists through Activity's `.m-tx` rows since M3 and R1 (see `account.js` and `money.js`),
 * and nothing anywhere emits `class="ledger"`. Deleted rather
 * than kept "in case", per this pass's own charge to remove what the previous refactor
 * orphaned.
 */

/* ───────────────────────────────────────────── M4 · evidence */

.ev-pop {
  /* A record is read, not glanced at. M4 stays opaque so the exact words never compete with
   * moving content beneath them. Since I3 (UX-015) it is the Activity card's shape (1:3671) - its
   * 24px corner and 16px inset - and the dark top edge it wore is gone: no frame draws one, and
   * this one shared disclosure needs no colour it has not earned. */
  /* Search itself is an active layer at 70. A record opened from a search result must be above
   * that layer, or its DOM says it opened while the person still cannot read it. */
  position: fixed; z-index: 80; width: min(380px, calc(100vw - 20px));
  background: var(--m4); border: 1px solid var(--m4-line);
  border-radius: var(--r-lg); box-shadow: var(--m3-shadow);
  padding: 16px;
}
.ev-pop[hidden] { display: none; }
/* "Where this comes from": the uppercase group label every frame draws. */
.ev-label {
  font-size: var(--t-micro); font-weight: 600; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink-3); margin: 0 0 12px;
}
/*
 * Verbatim. Never normalised, never re-cased, never trimmed to fit (§9). Quoted as Life's
 * timeline quotes everything you said (1:319): the marks are drawn here, the words are exactly
 * yours, at reading size.
 */
.ev-pop > .ev-said {
  font-family: var(--sans); font-size: var(--t-prose); font-weight: 500; line-height: 1.45; color: var(--ink);
  margin: 0 0 6px; padding: 0; font-style: normal; overflow-wrap: anywhere;
}
.ev-pop > .ev-said::before { content: '“'; }
.ev-pop > .ev-said::after { content: '”'; }
/* The day it was said, or why there is no one sentence: the row's meta line. */
.ev-pop > .ev-when {
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2); margin: 0;
  font-variant-numeric: tabular-nums;
}
/* The date sits between records in the DOM, so adjacent `.ev-said` could never draw this rule. */
.ev-pop > .ev-when + .ev-said { border-top: 1px solid var(--m4-line); margin-top: 12px; padding-top: 12px; }

/*
 * The ribbon and its week-pressure bars (`.ribbon`, `.rib-block`, `.rib-gap`, `.rib-scale`,
 * `.weeks`, `.week`, `.week-bars`, `.week-bar`, `.week-sum`, `.week-when`) lived here until
 * this pass. `time.js` no longer renders any of them — the Time redesign (CAP-080/phase 14)
 * replaced the horizontal ribbon with the vertical `.day-*` grid below, and the pressure
 * weeks with plain `.row`/`.row-text`/`.t-fits` rows (search this file for "the day is a
 * shape" and for `.t-tight`). Verified against every client file before deleting: zero
 * consumers for any of the nine names.
 */

/* ───────────────────────────────────────────── empty — complete, never empty */

/* A whole surface with nothing is a finished reading, not a card asking to be filled. The
   heading is deliberately named here rather than inheriting the browser's h2: all surface
   empties need the same calm hierarchy, whichever renderer reached one. */
.empty { max-width: var(--measure); padding: 14px 0 10px; }
.empty h2 {
  max-width: 25ch; font-size: var(--t-date); line-height: 1.22; letter-spacing: -0.024em;
  color: var(--ink); margin: 0 0 7px;
}
.empty p {
  max-width: var(--measure); font-family: var(--sans); font-size: var(--t-prose);
  line-height: 1.55; color: var(--ink); margin: 0;
}
.empty span { display: block; font-family: var(--sans); font-size: var(--t-meta);
  color: var(--ink-3); margin-top: 5px; }
.empty code { font-family: var(--mono); font-size: 0.9em; color: var(--ink-2); }

/* ───────────────────────────────────────────── search */

/*
 * ── The scrim's colour is themed the same way the tokens are, not by `prefers-color-scheme`
 * alone ──────────────────────────────────────────────────────────────────────────────────
 *
 * Light is the default (UX-012), so the base rule is the pale scrim; a heavy near-black one
 * belongs only where the page behind it is actually dark. The old order was backwards — a
 * dark base with a `@media (prefers-color-scheme: light)` override — and the override's own
 * guard, `:root:not([data-theme="dark"])`, only reads the OS preference. Force `data-theme=
 * "light"` against a dark OS and the base rule won: the finder opened over a light page under
 * a scrim built for a dark one. The two selectors below are the same pair the token block
 * itself uses to decide "is dark actually active" — media query for the OS default, attribute
 * for the explicit override — so this can't drift out of sync with what the palette is doing.
 */
.overlay {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 12vh 20px 20px;
  background: rgba(40, 50, 66, 0.22);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.overlay[hidden] { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .overlay { background: rgba(3, 5, 8, 0.5); }
}
:root[data-theme="dark"] .overlay { background: rgba(3, 5, 8, 0.5); }

.finder {
  width: 100%; max-width: 620px; max-height: 70vh; display: flex; flex-direction: column;
  /* Search is an inventory of your own words, not a command palette: M4 keeps every returned
   * sentence legible, while this quiet edge distinguishes the deliberate reading layer. */
  background: var(--m4); border: 1px solid var(--m4-line); border-top: 2px solid var(--ink-2);
  border-radius: var(--r-lg); box-shadow: var(--m3-shadow); overflow: hidden;
}
/*
 * The bar (1:5586): Back, then the search field as a pill on the card ground, a hairline and a
 * faint shadow under it. On the desk the finder stays a panel over the place; on a phone it is
 * the full-screen layer the frame draws (below).
 */
.finder-bar {
  display: flex; align-items: center; gap: 12px; padding: 16px;
  background: var(--m2); border-bottom: 1px solid var(--m2-line); box-shadow: var(--m2-shadow);
}
.finder-back {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 36px; height: 36px; margin: 0 -8px 0 -8px; padding: 0; border: 0; border-radius: var(--r-pill);
  background: none; color: var(--ink-2); cursor: pointer;
}
.finder-back .i { width: 20px; height: 20px; }
.finder-back:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.finder-input {
  flex: 1; min-width: 0;
  display: grid; grid-template-columns: 16px 1fr auto; gap: 8px; align-items: center;
  padding: 8px 16px; background: var(--field); border: 1px solid var(--field-line); border-radius: var(--r-pill);
}
.finder-input:focus-within { border-color: var(--accent); }
.finder-input svg { width: 16px; height: 16px; color: var(--ink-3); }
.finder-input input {
  font: inherit; font-size: var(--t-body); color: var(--ink);
  background: none; border: 0; outline: none; width: 100%;
}
.finder-input kbd { font: inherit; font-size: var(--t-micro); color: var(--ink-3);
  padding: 2px 5px; border: 1px solid var(--m4-line); border-radius: var(--r-xs); }
.finder-results { overflow-y: auto; padding: 4px 0 8px; }
.hit { padding: 13px 18px; min-height: 56px; cursor: pointer; border-left: 2px solid transparent;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.hit + .hit { border-top: 1px solid var(--m4-line); }
.hit:hover { background: var(--m4-2); }
.hit:focus-visible { outline: none; background: var(--m4-2); border-left-color: var(--accent); }
/* S1: these were `.hit p` and `.hit span`, and the span rule outranked .hit-text, so every result
   was set at the 11px micro tier. A result reads as a recent line does: body text, meta under it. */
.hit mark { background: var(--accent-soft); color: var(--ink); border-radius: var(--r-xs); padding: 0 2px; }

/* ───────────────────────────────────────────── mobile */

.tabbar, .ai-action { display: none; }

@media (max-width: 860px) {
  .frame, .frame.talking { grid-template-columns: 1fr; }
  .rail { display: none; }
  /*
   * The bottom padding reserves the docked capture tray AND the tab bar beneath it, so the
   * last row of every surface can be scrolled clear of both. It was 108px for a tab bar
   * alone; the tray sits above that now.
   */
  .surface { padding: 48px 16px 200px; }
  /*
   * The tab bar's height, stated once for everything that stands on it: 24px padding either
   * side of a 22px icon, a 4px gap and a 15px label, plus its 1px top rule (Figma 1:1056), and
   * the home-indicator inset on top of that.
   */
  body { --dock-gap: calc(90px + env(safe-area-inset-bottom, 0px)); }
  /* The date at the Figma H1 size wraps rather than running under the two header buttons, which
     together occupy 84px at the right edge (search at right 38 + 44 wide, the gear beside it). */
  .head h1 { font-size: var(--t-title); padding-right: 84px; }
  /* Money's H1 takes the header's place, so it keeps clear of the same two buttons. The head
     is 8px outside the H1's own padding, hence 76 rather than 84. */
  .m-h1 { padding-right: 76px; }
  /* UX-022: the headline is a card now, so the home starts below the two header buttons. */
  .m-home { padding-top: 52px; }
  /* Money and Today hide the header's own H1, so when their read FAILS there is no H1 to keep
     clear of the buttons and the failure sentence ran under the gear (found offline, 30 Sep). */
  #money > .state-error:first-child, #today > .state-error:first-child { padding-right: 76px; }
  .head-settings, .head-search {
    position: absolute; top: -8px; right: -8px;
    width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
    color: var(--ink-2); background: transparent; border: 1px solid transparent;
    border-radius: var(--r-sm);
  }
  /* Beside the gear, one target-width to its left. */
  .head-search { right: 38px; }
  .head-settings svg, .head-search svg { width: 18px; height: 18px; }
  .head-settings:hover, .head-search:hover { color: var(--ink-2); background: var(--m2-hi); border-color: var(--hairline); }
  .head-settings:focus-visible, .head-search:focus-visible {
    outline: none; color: var(--ink); border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
  }
  .pane, .capture, .head { max-width: none; }

  /* M2 · exactly five destinations. Conversation is the adjacent floating action below. */
  .tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    display: flex; align-items: center; justify-content: space-between;
    padding: 24px 24px calc(24px + env(safe-area-inset-bottom, 0px));
    /*
     * NOT glass, and UX-005 rule 1 is the reason: "Glass never sits over scrolling content.
     * Content passing behind translucency turns to mud, and moving mud is worse."
     *
     * The tab bar is fixed over the surface, and the surface is the thing that scrolls. It had
     * been glass since it was built, and phase 20 did not catch it because that pass counted
     * HOW MANY live layers there were without asking what each one sat over — the budget is
     * rule 2, and this is rule 1.
     *
     * Docking capture directly above it (UX-010) is what made it unavoidable: the two are one
     * stack, and a translucent bar beside an opaque tray reads as a mistake.
     *
     * The Figma draws it full width with a top rule, white at 80% over a blur. It is the same
     * bar made opaque, for the reason above.
     */
    background: var(--tray); border-top: 1px solid var(--m2-line);
  }
  /*
   * Icon over word, at their drawn widths, spread edge to edge as the Figma spreads them. The
   * label is 10px in the frame; the nearest tier is 11 (UX-013 §6). A drawn button is 22-33px
   * wide, so the target is a centred 56px pseudo-element, over the 44px floor, that moves
   * nothing on screen.
   */
  .tabbar button {
    position: relative;
    display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 0;
    font: inherit; font-size: var(--t-micro); font-weight: 500; line-height: 15px;
    color: var(--ink-2); background: none; border: 0; cursor: pointer;
  }
  .tabbar button::after {
    content: ''; position: absolute; left: 50%; top: 50%;
    width: 56px; height: 56px; transform: translate(-50%, -50%);
  }
  .tabbar .i { width: 22px; height: 22px; }
  .tabbar button[aria-current="page"] { color: var(--ink); }

  /*
   * The action shares capture's measured bottom anchor but never covers its field: the form
   * gives it one 50px column plus the Figma's 8px gap. It therefore follows --kb with capture,
   * keeps the tab bar's clearance, and adds no height to the reserved bottom space. Same
   * material and radius as the pill beside it (Figma 1:1054).
   */
  #capture-form { margin-right: 58px; }
  .ai-action {
    position: fixed; right: 16px;
    bottom: calc(var(--kb, 0px) + var(--dock-gap) + 14px);
    z-index: 41; width: 50px; height: 50px;
    display: flex; align-items: center; justify-content: center;
    color: var(--ink-2); background: var(--field);
    border: 1px solid var(--field-line); border-radius: var(--r-lg);
    box-shadow: var(--m2-shadow); cursor: pointer;
    transition: color var(--dur) var(--ease), background var(--dur) var(--ease),
                transform var(--dur) var(--ease);
  }
  .ai-action:hover, .ai-action[aria-expanded="true"] {
    color: var(--ink); background: var(--d-talk-soft);
  }
  .ai-action:active { transform: translateY(1px); }
  /* The R's ink box at the frame's 28px: 816 x 705 font units at 0.028px each. */
  .ai-action .talk-mark { width: 22.85px; height: 19.74px; }

  /*
   * ── Capture is docked in the thumb's arc (UX-010) ───────────────────────────────────
   *
   * Measured at 375x812, with the pivot of a one-handed grip at (300, 780):
   *
   *     capture at the top of the surface    655px from the pivot    two-handed
   *     capture docked above the tab bar     150px                   natural
   *     the tab bar itself                   113px                   natural
   *
   * Capture was the only thing in the product outside the stretch band, and it is the thing
   * done most — "the highest-volume interaction in the product by a wide margin", about ten
   * a day against five lookups. The tab bar, used far less, had the best zone.
   *
   * A third candidate opened the field from the tab bar's centre and reached 113px, but cost
   * a second tap. 37px of reach is not worth putting a decision in the path of the one
   * interaction P3 protects, so the field is always present rather than summoned.
   *
   * `column-reverse` puts the FIELD at the bottom of the tray, nearest the thumb, and stacks
   * its reply, answer and receipt upward above it: feedback in the direction you read, input
   * where the thumb already is.
   */
  .capture {
    position: fixed; left: 0; right: 0; z-index: 39;
    /*
     * Anchored to the bottom of the screen and padded out to clear the tab bar, rather than
     * floated above it. The tab bar is an inset pill, so a tray stopping short of it left two
     * transparent strips — one between them, one under the pill — and the surface scrolled
     * through both. One stack, not two floating layers.
     */
    bottom: var(--kb, 0px);
    margin: 0; max-width: none;
    /* 14px under the field, not 12: the frame's row is 76px, because the search button beside
       the pill carries 2px of bottom margin (1:1049). Search moved to the header; its row
       height did not. */
    padding: 12px 16px calc(var(--dock-gap) + 14px);
    display: flex; flex-direction: column-reverse; gap: 2px;
    /*
     * No sheet at all (owner, after D0c). In the Figma the pill and Talk's button float over
     * the page, and only the tab bar is a sheet (1:1040). An opaque ground-coloured tray read
     * as a band behind them.
     *
     * Rule 1 still holds, because it forbids GLASS over scrolling content, and this row has no
     * blur and no material of its own. Everything in it that must be read carries its own
     * opaque backing: the pill (--field), the answer and receipt cards, and, while shown, the
     * reply and offer lines below. The row stays zero live blur layers.
     *
     * It is transparent to taps as well as to sight. The row spans the screen, and the content
     * showing through it has to stay tappable; only the things in it take pointer events.
     */
    background: transparent;
    pointer-events: none;
    max-height: 60vh; overflow-y: auto;
  }
  .capture > #capture-form, .capture > .answer, .capture > .receipt, .capture > .offer {
    pointer-events: auto;
  }
  /*
   * The field stays where the thumb is while the tray is read from the top (app.js
   * readFromTop): a long answer opens on its first line, and scrolling it down never takes the
   * field out of reach.
   */
  .capture > #capture-form { position: sticky; bottom: 0; z-index: 1; }
  /* The two bare-text lines get a ground backing only while there is something to read. */
  .capture .reply.show, .capture .offer:not([hidden]) {
    align-self: flex-start; background: var(--ground);
    border-radius: var(--r-sm); padding: 4px 10px;
  }
  #capture-form { -webkit-backdrop-filter: none; backdrop-filter: none; }

  /* Feedback can grow up from the thumb-reachable field without claiming another sheet or
   * changing the tray's measured 60vh ceiling. The two existing cards only tighten on phone. */
  .capture .answer, .capture .receipt { margin-top: 8px; }

  /*
   * ── While you are typing, the tab bar goes ──────────────────────────────────────────
   *
   * You are not navigating; you are writing. Giving the sentence that room is what makes the
   * docked field win the second measurement as well as the first: with the keyboard up, 376px
   * of the surface stays readable against 108px with the field at the top, and the field is
   * still 361px from the pivot — inside the natural band while you type.
   */
  body.kb-up .tabbar { transform: translateY(calc(100% + 16px)); }
  /* With the tab bar gone there is nothing to clear, so the tray closes up on the keyboard. */
  body.kb-up .capture { padding-bottom: 12px; }
  /* And Talk's button follows the field down, or it floats a tab bar's height above it. */
  body.kb-up .ai-action { bottom: calc(var(--kb, 0px) + 12px); }

  /*
   * ── Settings is a list you tap into ─────────────────────────────────────────────────
   *
   * As one scroll it is 5,253px — ten flicks to reach "About". As a list it is one tap, and
   * the worst group is 1.3 screens. Every group already fitted; only the way in was wrong.
   */
  /* R6: one Activity card of rows, each with the arrow Life's door draws (1:226). */
  .s-index { display: flex; flex-direction: column; margin: 0; }
  #settings .s-entry {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; min-height: 52px; padding: 16px; cursor: pointer; text-align: left;
    font: inherit; background: none; border: 0;
  }
  #settings .s-entry > .i { flex: none; width: 16px; height: 16px; color: var(--ink-3); }
  #settings .s-entry .s-entry-text { flex: 1; }
  #settings .s-entry:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

  /*
   * One thing at a time: the list, or the group you tapped. Each group is named rather than
   * matched by a pattern, because the open group's id is not knowable to a static rule — six
   * groups and the coverage page, which is the whole set.
   */
  #settings .s-group, #settings .s-coverage { display: none; }
  #settings[data-open] .s-index { display: none; }
  #settings[data-open="coverage"] .s-coverage { display: block; }
  #settings[data-open="you"] #set-you,
  #settings[data-open="money"] #set-money,
  #settings[data-open="attention"] #set-attention,
  #settings[data-open="ai"] #set-ai,
  #settings[data-open="data"] #set-data,
  #settings[data-open="about"] #set-about { display: block; }

  #settings .s-group, #settings .s-coverage .s-block { margin: 0 0 24px; }

  /*
   * M3 · the conversation as a sheet, three-quarter height, with the room still visible
   * through it. That is the concept made physical: the aide is a pane of glass over your
   * life, not a door out of it.
   */
  .dock {
    position: fixed; inset: auto 0 0 0; height: 78vh; width: auto;
    border-left: 0; border-top: 1px solid var(--m3-line);
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    z-index: 50;
    animation: sheet-up var(--dur-sheet) var(--ease-sheet);
  }
  .dock-head { padding-left: 13px; }
  .turns { padding: 18px 16px; }
  .dock-ask { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  @keyframes sheet-up { from { transform: translateY(100%); } }

  /* The finder is the full-screen layer the frame draws (1:5585): the ground, the bar on top. */
  .overlay { padding: 0; background: var(--ground); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .finder { max-width: none; height: 100dvh; max-height: none; border: 0; border-radius: 0; box-shadow: none; background: var(--ground); }
  .finder-input kbd { display: none; }
  .ev-pop { left: 12px !important; right: 12px; max-width: none; }
}

/* ───────────────────────────────────────────── touch */

/*
 * Without a pointer there is no hover, so anything revealed by hover is simply unreachable.
 * Nothing here hides actions behind hover any more, but the rule is asserted rather than
 * assumed — a future row that adds a hover-reveal would otherwise be untestable until
 * someone tried it on a phone.
 *
 * 44px is the floor for a control you tap. The row action was 28px and unusable.
 *
 * It was 40px until UX-010, and the number mattered more than it looked. The blueprint's own
 * acceptance criterion for the mobile phases has always read "targets >= 44"; the code and the
 * test that guarded it both said 40. That gap was defensible while the desk was the product
 * and this was a control you occasionally poked with a mouse. Under UX-010 the row action is
 * the primary interaction in the primary experience, and 44 is both the product's own stated
 * bar and the platform floor on either OS.
 */
@media (hover: none) {
  .row-acts { opacity: 1; }
  .act { min-width: 44px; width: 44px; min-height: 44px; display: inline-flex;
    align-items: center; justify-content: center; }
  
  /*
   * More thumb, less gap. `2px 6px` was tuned when a chip was a filled box, where the
   * horizontal padding WAS the visual; on an underlined word it only opened space either
   * side of every name in a sentence. The vertical padding is what a thumb needs and costs
   * nothing on screen, because an inline element's vertical padding does not move a line.
   */
  .chip { padding: 5px 2px; }

  /* Conversation carries real controls: close the layer, open a more useful surface, and
   * disclose the grounds. Their visible words stay compact, while the hit areas meet the
   * phone floor without introducing a second card or a new interaction. */
  .dock-close, .turn-open, .prov-open > .prov {
    min-height: 44px; display: inline-flex; align-items: center;
  }
  .dock-close { min-width: 44px; justify-content: center; }

  /*
   * ── And the taps that are TEXT, which is most of them ─────────────────────────────
   *
   * This block raised `.act` and stopped, so the icon buttons cleared the floor while the
   * three controls a person actually uses did not. Measured at 375px:
   *
   *     .entity-link  23px tall   the door into a person or a thing
   *     .ev-text      37px        "what did I say?" — the one INT the registry calls
   *                               non-negotiable, and the most-tapped thing in the product
   *     .w-link       31px        the way in to what you have written
   *
   * They are text, so they were sized by the type scale and nothing ever measured them as
   * targets. At a desk that is invisible: a pointer hits a 23px line every time. Under
   * UX-010 it is the primary navigation of the primary experience, missed by a thumb.
   *
   * `.ev-text` is the row, so it takes the height directly. The two links are inline inside
   * sentences and cards, where 21px of extra height would push every card apart — so they
   * get a centred pseudo-element instead, which extends the hit area to 44px and moves
   * nothing. The text stays exactly where the desk design put it.
   */
  /*
   * Scoped to `button`, deliberately. Both classes are worn by plain `<span>`s in rows that
   * are not tappable — Money's coming lines, Time's stretches — and a 44px floor on those
   * would pad out every static row in the product to the size of a control. A floor belongs
   * to a target, and only an element you can press is one.
   */
  button.ev-text, button.row-text { min-height: 44px; align-content: center; }

  .entity-link, .w-link { position: relative; }
  .entity-link::after, .w-link::after {
    content: '';
    position: absolute; left: 0; right: 0; top: 50%;
    height: 44px; transform: translateY(-50%);
  }

  /*
   * ── The small icon controls, measured on 30 September ─────────────────────────────────
   *
   * Marking work done (18px), a tree caret (24px), a Talk context chip (22px), a fold (32px), the
   * "…" menu (32px), Back in search and the Wishlist (36px), the Wishlist door (33px), Notes'
   * bring-back (33px). Each gets a 44px hit area from a centred pseudo-element, so nothing on the
   * screen moves; the pills and the tray's buttons, which are already nearly there, take the floor.
   */
  .w-check, .nt-caret, .spine-chip button, .w-fold, .l-more, .finder-back, .wl-back-in, .m-wl-open, .nt-bring {
    position: relative;
  }
  .w-check::after, .nt-caret::after, .spine-chip button::after, .w-fold::after, .l-more::after,
  .finder-back::after, .wl-back-in::after, .m-wl-open::after, .nt-bring::after {
    content: ''; position: absolute; left: 50%; top: 50%;
    width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%);
  }
  .m-lens, .offer button, .c-answer { min-height: 44px; }
  /* Three rules later in the file cancelled the floor for a tap target; these outrank them. */
  .m-bud-spent > button.ev-text, #surface button.e-ev { min-height: 44px; }
  #surface .lq-acts button.act { min-height: 44px; }
}

/* ───────────────────────────────────────────── accessibility */

/* A pane that takes focus when it opens (tabindex="-1", for screen readers) is not a control, so it
   draws no ring; every control keeps the ring below. */
[tabindex="-1"]:focus { outline: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

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

/*
 * Reduced transparency and forced colours both fall back to M4 everywhere: the product loses
 * depth and loses nothing else. Depth was never carrying information that type and space are
 * not also carrying (§24).
 */
@media (prefers-reduced-transparency: reduce), (forced-colors: active) {
  .rail, #capture-form, .dock, .tabbar, .act, .chip, .spine-chip, .overlay {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    background: var(--m4) !important;
  }
  .glow-a, .glow-b, .grain { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   COMPONENTS

   Rows, cards, money, settings, loops, time, evidence and the pricing answer,
   carried forward from UX-004 unchanged. They sit on the four materials through the
   aliases above. Rewriting them would have been churn: the material system changed,
   and what a committed money line looks like did not.
   ═══════════════════════════════════════════════════════════════════════ */

.group + .group { border-top: 1px solid var(--hairline); }

/*
 * ── A row WRAPS, because its evidence is a third line ─────────────────────────────────
 *
 * Every row here is: a label, whatever you can do to it, and — once you tap it — the sentence
 * it came from. That last part is `.ev-said`, declared `flex: 1 0 100%` so it takes a line
 * of its own. In a NOWRAP row it cannot: a 100% basis that refuses to shrink instead squeezed
 * every sibling to nothing, and `word-break: break-word` then broke the label one character
 * per line. Tapping "the bins" on Today turned it into a vertical column of letters.
 *
 * The same missing wrap, in the third place this pass has found it: `.ev-text`, `.row-text`,
 * and here. A layout built from nested flex rows needs the wrap declared at every level that
 * holds something meant to fall underneath, and it had been declared at none of them.
 */
.row {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 12px;
  padding: 9px 20px 10px;
  transition: background var(--dur) var(--ease);
}
/*
 * ── The hover wash is a token now, not a hand-tuned white at two opacities ────────────────
 *
 * This was `rgba(255, 255, 255, 0.022)` with a `@media (prefers-color-scheme: light)` override
 * to `rgba(255, 255, 255, 0.5)` — white-on-white at half alpha, which is nearly invisible on
 * the new pale ground (UX-012): a wash of white over `#f7f8fa` barely moves the pixel. It also
 * only read the OS preference, so forcing `data-theme="light"` against a dark OS kept the
 * 0.022 value meant for a near-black ground. `--m2-hi` is exactly this wash, authored per
 * theme and already correct for an explicit override — the same token `.rail button:hover`
 * uses for the same job.
 */
.row:hover { background: var(--m2-hi); }

/*
 * ── The text part of a row, and it is a WRAPPING FLEX ROW ─────────────────────────────
 *
 * Same job as `.ev-text`, so the same treatment: a label, and optionally a secondary line
 * underneath it. It was a block, and that cost two things at once.
 *
 * `white-space: pre-wrap` is here so a sentence you typed across three lines still reads as
 * three lines — never normalised, never re-flowed (§9). But in a BLOCK it also preserved the
 * whitespace in the markup, and six of these rows are built by templates that put each child
 * span on its own indented line. The browser rendered the source code's own indentation:
 *
 *     Money's account row      129px tall, name indented 38px, balance floating above it
 *     Time's stretches         every secondary line indented under its label
 *     Money's coming lines     the same
 *
 * In a flex row those whitespace-only nodes stop being rendered, while a genuinely multi-line
 * verbatim text still breaks exactly as before — measured both ways in a browser, identical.
 * And the wrap is what lets a `.meta` child take its own line here too, which is the other
 * half of the same fix.
 *
 * The alternative was `white-space: normal` and reindenting six templates. That would have
 * traded a real guarantee for a formatting convention, and the guarantee is the product.
 */
.row-text {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 7px;
  letter-spacing: -0.006em; white-space: pre-wrap; word-break: break-word;
}

.row-acts {
  flex: 0 0 auto; display: flex; gap: 2px; margin-left: -4px;
  opacity: 0; transform: translateX(3px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.row:hover .row-acts, .row:focus-within .row-acts { opacity: 1; transform: none; }

.act {
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: var(--r-xs);
  color: var(--ink-3);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.act svg { width: 13px; height: 13px; }
.act:hover { color: var(--ink); background: var(--glass-hi); }
.act.on { color: var(--accent); }
.act.on svg { fill: currentColor; stroke: none; }

/* Newly captured things arrive quietly: fade and rise 4px. Nothing springs (UX-004 rule 7). */
@keyframes arrive { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.row.arriving { animation: arrive 220ms var(--ease) both; }

/*
 * The backdrop-filter fallback that used to live here — `.pane, .segmented { background:
 * ... }` for browsers without the feature — was fixing a surface neither selector has any
 * blur on. `.segmented` names no component anywhere in this product (no consumer in any
 * client file, and no other rule in this stylesheet), and `.pane` is M1: "content ink directly
 * on the ground, NO CONTAINER" (see the file banner), so it carries no background or
 * backdrop-filter to fall back FROM. Giving `.pane` an opaque box here, in browsers lacking
 * the feature, would have boxed every surface in the product — the opposite of what M1 asks
 * for — and never once actually happened, because nothing sets `.pane`'s backdrop-filter in
 * the first place.
 */

@media (max-width: 480px) {
  
  .head h1 { font-size: var(--t-title); }
  .capture textarea { font-size: var(--t-body); padding: 15px 15px; }
  .row, .group-label { padding-left: 16px; padding-right: 16px; }
}

/* Below the floor is said in WORDS, never in red (UX-004 rule 2). Amber arrives with the
   attention model (phase PD). */
.m-note { font-size: var(--t-meta); color: var(--ink-2); margin-top: 7px; }
.m-caveat { font-size: var(--t-meta); color: var(--ink-3); margin-top: 8px; text-wrap: pretty; }

/*
 * ── A want: the thing, what it would do, and then the qualifications ──────────────────
 *
 * `.m-says` is the row's one SENTENCE — what buying this would do to your position, which is
 * the entire reason this lens exists. It used to be the first clause of a middot run that
 * also held two more sentences and two date clauses, all at meta size and meta colour.
 *
 * It takes its own line at body size, and the facts that qualify it stay in `.m-meta` beneath.
 */

/*
 * A want that would take you under your own floor, marked as well as said.
 *
 * `breaches` was computed, used for the ordering, sent to the client and rendered by nothing,
 * so the one row with a real consequence looked exactly like the one without. Amber, because
 * this is what "earned" means (UX-005, UX-011) — and the sentence stays, because a colour
 * alone is not an answer.
 */
.m-breach { border-left: 2px solid var(--ember); padding-left: 11px; }

.m-lands { margin-top: 9px; font-size: var(--t-meta); color: var(--ink-2); }
.m-lands i { color: var(--ink-3); font-style: normal; margin: 0 7px; }

/* Settings is a reached utility, not a sixth place. Its active rail mark stays neutral; the
 * system accent is reserved for keyboard focus, not for claiming Settings as a domain. */
#open-settings[aria-pressed="true"] {
  color: var(--ink); background: var(--m2-hi); border-color: var(--hairline-hi);
}
#open-settings-mobile[aria-pressed="true"] {
  color: var(--ink); background: var(--m2-hi); border-color: var(--hairline-hi);
}

/*
 * R6 (UX-015): a setting is a row of its group's Activity card (1:3671) - the sentence as the row's
 * words, the control under it, then the effect and where the value came from.
 */
.s-row { padding: 16px; }
.s-sentence {
  margin: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink);
  text-wrap: pretty;
}
.s-control {
 display: flex; align-items: center; gap: 8px; margin-top: 10px;
 flex-wrap: wrap; gap: 10px;
}

/*
 * The number field: the capture field's own look (D0c) - its fill, line, shadow and focus ring -
 * at a number's width. No frame draws a number field; the owner ruled on 26 September that it
 * takes the one field the frames do draw.
 */
.s-control input {
  width: 96px; min-height: 40px; padding: 8px 12px;
  font: inherit; font-size: var(--t-body); font-variant-numeric: tabular-nums; color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/*
 * The same field at a phrase's width: a browser's enrolment code, passphrase and AI key (ADR-041,
 * cloud/web/browser.js). A passphrase in a number's 96px would scroll inside itself as you type.
 */
.s-control input.s-text { width: min(100%, 320px); max-width: none; font-variant-numeric: normal; }
.s-control input.s-code { width: 5.5em; text-transform: uppercase; font-variant-numeric: normal; }
.s-control input::placeholder { color: var(--ink-3); }
.s-control input:focus-visible {
  outline: none; border-color: var(--accent);
  box-shadow: var(--m2-shadow), 0 0 0 3px var(--accent-soft);
}

/*
 * "never" and the price-check switch (PD-028) are the pills Money draws (1:3418). A switch names
 * what tapping it does; a chosen "never" is the active pill, near-black ink (B-05) - a value the
 * person chose, not a warning, a destination or a focus state.
 */
.s-never, .s-switch {
  appearance: none; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 8px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.s-never:hover, .s-switch:hover { color: var(--ink); }
.s-never.on { color: var(--m2); background: var(--ink); border-color: var(--ink); box-shadow: var(--m2-shadow); }
.s-never:focus-visible, .s-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The effect. Not a tooltip and not fine print - a control whose effect is hidden is not
   control, so this sits in the flow at the row's meta line. */
.s-effect { margin: 10px 0 0; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2); text-wrap: pretty; }
.s-note { margin: 4px 0 0; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-3); }
.s-note.s-yours { color: var(--ink-2); }

/*
 * A settings refusal and a receipt are compact M2 notices. On paper, a hairline alone cannot
 * reliably separate their opaque surface from the page, so the material system's named M2
 * shadow supplies that quiet edge. A priced answer is intentionally different: its own rule
 * raises it to M3 because it is meant to be read, not merely acknowledged.
 */
.s-refusal {
  margin-top: 7px; font-size: var(--t-meta); color: var(--ink-2);
  padding: 7px 11px; border-radius: var(--r-sm);
  background: var(--m2-hi); border: 1px solid var(--m2-line);
  
  animation: arrive 180ms var(--ease) both;
}

/* What it knows: each kind and how many, an Activity row's words and figure (UX-004 rule 1) -
   quantities of what is held, not a score and not a target. */
.s-know { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 12px 16px; }
.s-source { padding: 16px; }
.s-source .m-tx-what, .s-source .m-tx-meta { display: block; margin: 0; }
.s-source .m-tx-meta { margin-top: 4px; }

/* ────────────────────────────────── people and things (CAP-076)
 *
 * A card, not a contact record. The name carries the weight and the lines sit under it in a
 * lighter tier - reading down a card should feel like remembering, not like querying.
 */

@media (max-width: 480px) {  }

/* ── evidence, on every surface ────────────────────────────────────────────────
 *
 * The sentence a line came from used to live in a `title` attribute: invisible on a phone,
 * unreachable from a keyboard, and absent on exactly the surface where you would most want to
 * check a claim about a friend. It is a button now, like the money rows always were.
 */

.ev-text {
  /*
   * WRAP, and it is what makes the meta line a line (phase 20).
   *
   * This is an inline-flex ROW. Without wrap, a meta child with `flex-basis: 100%` cannot
   * move to a second line, so it shrinks to share the first one instead - and it squeezed
   * every label in the product to its minimum width. "the bins" rendered as "the" / "bins"
   * in a 38px column beside a 385px detail.
   */
  flex: 1 1 auto; display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 2px 7px;
  padding: 3px 0; text-align: left;
  font: inherit; font-size: var(--t-meta); line-height: 1.45; color: var(--ink-2);
  text-wrap: pretty;
  border-bottom: 1px solid transparent;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.ev-text:hover { color: var(--ink); border-color: var(--hairline); }
.ev-text[aria-expanded="true"] { color: var(--ink); }

.ev-said {
  flex: 1 0 100%;
  padding: 2px 0 8px 14px; font-size: var(--t-meta); color: var(--ink-3);
  animation: arrive 180ms var(--ease) both;
}
.ev-said em { font-style: normal; color: var(--ink-2); }

/*
 * The slot/gap list that used to answer "the shape of a day" here (`.t-slots`, `.t-slot`,
 * `.t-when`, `.t-label`, `.t-note`, `.t-gaps`, `.t-gap`, `.t-length`, `.t-kind`) has no
 * consumer left in `time.js` - CAP-080/phase 14 replaced it with a vertical `.day-*` grid, and
 * plan 4 replaced that with the card kit's rows (`.k-slot`), which is where "the shape of a day"
 * is drawn now. Confirmed against every client file before deleting.
 */

/* ───────────────────────────────────────────────── the answer (CAP-042)
 *
 * Sits under capture, where the reply already is, because asking is the same one field.
 * No verdict colour anywhere: the accent marks the DATE, which is the actionable part, and
 * being under the floor is said in words like everything else (UX-004 rule 2).
 */

/* An answer is what someone stopped to read. It gets M3 above the capture tray, while a
 * receipt stays quieter at M2: result before confirmation, without a new semantic colour. */
/* I1: the Activity card's shape (1:3671) - its 24px corner and 16px inset - on the answer's M3. */
.answer {
  margin-top: 12px; padding: 16px;
  border-radius: var(--r-lg);
  background: var(--m3); border: 1px solid var(--m3-line);
  box-shadow: var(--m3-shadow);
  animation: arrive 200ms var(--ease) both;
}

/* What was asked: the card's header line, as Activity's day header sits over a rule. */
.a-asked {
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
  padding-bottom: 12px; margin-bottom: 4px;
  border-bottom: 1px solid var(--m2-line);
}

.a-halves { display: grid; gap: 4px; }
/* Side by side only when there are two, and only with room. Both currencies in one glance is
   the whole point of the capability. */
@media (min-width: 620px) {
  .a-halves.a-both { grid-template-columns: 1fr 1fr; gap: 22px; }
}

.a-half { padding-top: 12px; }
.a-half .group-label { padding: 0 0 8px; }

/* The first line is the row's words; what follows is its meta, as an Activity row reads. */
.a-line {
  font-size: var(--t-body); font-weight: 600; color: var(--ink); line-height: 1.5;
  text-wrap: pretty;
}
.a-line + .a-line { margin-top: 4px; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2); }

/* The date that matters closes the card, as Activity's month line does. Ink, never a hue: the
   focus blue it wore means keyboard focus (B-05), not "this matters". */
.a-date {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--m2-line);
  font-size: var(--t-meta); font-weight: 500; line-height: 1.5; color: var(--ink-2);
}
.a-date b { color: var(--ink); font-weight: 600; }

/* What it could not see: the "What Raai knows" card, inside the answer it limits (P8). */
.answer .a-unknown { margin: 12px 0 0; }

/* Close: the pill Money draws (1:3418). */
.a-close {
  display: block; margin-top: 12px; appearance: none; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 8px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
  transition: color var(--dur) var(--ease);
}
.a-close:hover { color: var(--ink); }
.a-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Touch sizing for the settings controls.
 *
 * This block has to come AFTER the base rules above, not with the other hover:none rules near
 * the top: same specificity, so source order decides, and a media query does not change that.
 * The 40px targets were silently doing nothing until the real page was measured on a phone. */
@media (hover: none) {
  
  .s-control input { min-height: 44px; }
  .s-never, .s-switch { min-height: 44px; }
  .a-close { padding: 10px 16px; }
  /* Evidence must be reachable with a thumb. It was hover-only once, which meant it did not
     exist here at all. */
  .ev-text { padding: 9px 0; }
}

@media (max-width: 480px) {
  .head { flex-wrap: wrap; }
  
  .s-control input { width: 100%; max-width: 140px; }
}

/*
 * Needs You (CAP-053) used to be styled here, under `.needs-row`, `.needs-if` and
 * `.needs-line`. CAP-108 moved the surface onto Today and rendered it through `.t-needs` and
 * `.t-if` instead (see "one system - phase 20", further down this file, which already
 * documents that the `.needs-*` selectors stopped rendering) — but the dead rules themselves
 * were left behind rather than removed, so the CSS kept describing a component `today.js`
 * had stopped emitting. Confirmed against every client file: no consumer of `.needs-row`,
 * `.needs-if` or `.needs-line` remains.
 */

/* ───────────────────────────────────────────── the pieces the shell still owns */

.empty-mark {
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; margin-bottom: 12px;
  background: var(--m2); border: 1px solid var(--m2-line); color: var(--ink-3);
}
.empty-mark svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.5; }

.hit { display: block; width: 100%; text-align: left; background: none; border: 0;
  font: inherit; color: var(--ink); }
.hit-text { letter-spacing: -0.006em; white-space: pre-wrap; word-break: break-word;
  display: block; font-size: var(--t-body); }
.hit-text mark { background: var(--accent-soft); color: var(--ink); border-radius: var(--r-xs); padding: 0 1px; }
.hit-when { font-size: var(--t-meta); color: var(--ink-3); margin-top: 3px; display: block; font-variant-numeric: tabular-nums; }
.finder-note { padding: 16px 18px; margin: 0; font-size: var(--t-meta); color: var(--ink-3); line-height: 1.5; }

/*
 * ── The empty search (1:5585, PD-026) ─────────────────────────────────────────────────────
 * Two sections on the ground: the kinds as a two-up grid of tiles, then what you said last as
 * one card of rows. The frame's 14px names and 12px meta take the tiers above them (ties go up);
 * its labels are the 13px caps every group label on the page uses. Kind colours are Life's own
 * (UX-014 §1) rather than the frame's rose and amber, which mean money and attention here.
 */
/* The frame puts the first section 24px under the bar; the hit list's own 4px top is not wanted here. */
.finder-results:has(.find-sec) { padding-top: 0; }
.find-sec { padding: 24px 16px 16px; }
.find-sec + .find-sec { padding-top: 8px; }
.find-h {
  margin: 0 0 16px; padding: 0 4px; font-size: var(--t-meta); font-weight: 700; line-height: 19.5px;
  letter-spacing: 0.65px; text-transform: uppercase; color: var(--ink-3);
}
.find-kinds { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.find-kind {
  display: flex; align-items: center; gap: 12px; min-width: 0; padding: 12px; text-align: left;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow); font: inherit; color: inherit; cursor: pointer;
}
.find-mark { display: inline-flex; flex: none; padding: 8px; border-radius: var(--r-sm); background: var(--m2-hi); color: var(--ink-2); }
.find-mark .i { width: 16px; height: 16px; }
.find-kind.is-people .find-mark { background: var(--ent-person-soft); color: var(--ent-person); }
.find-kind.is-things .find-mark { background: var(--ent-thing-soft); color: var(--ent-thing); }
.find-kind.is-places .find-mark { background: var(--ent-place-soft); color: var(--ent-place); }
.find-kind.is-projects .find-mark { background: var(--ent-project-soft); color: var(--ent-project); }
.find-kind.is-accounts .find-mark { background: var(--d-money-soft); color: var(--d-money); }
.find-kt { display: flex; flex-direction: column; min-width: 0; }
.find-kname { font-size: var(--t-body); font-weight: 600; line-height: 21px; color: var(--ink); }
.find-kcount { font-size: var(--t-meta); font-weight: 500; line-height: 18px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.find-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg); box-shadow: var(--m2-shadow);
}
.find-said {
  display: flex; flex-direction: column; gap: 6px; width: 100%; padding: 16px; text-align: left;
  background: none; border: 0; font: inherit; color: inherit; cursor: pointer;
}
.find-said + .find-said { border-top: 1px solid var(--m2-hi); }
.find-text { font-size: var(--t-body); font-weight: 500; line-height: 20.625px; color: var(--ink); white-space: pre-wrap; word-break: break-word; }
.find-meta { display: flex; align-items: center; gap: 8px; font-size: var(--t-meta); font-weight: 500; line-height: 18px; color: var(--ink-2); }
.find-meta .i { width: 12px; height: 12px; margin-right: -4px; }
.find-more { padding: 12px 4px 0; }
.find-kind:focus-visible, .find-said:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .find-kind:hover { border-color: var(--m3-line); }
  .find-said:hover { background: var(--m2-hi); }
}

/* ───────────────────────────────────────────── the receipt — CAP-099
 *
 * What one sentence actually changed. Deliberately quieter than the pricing answer beside it:
 * an answer is something you asked for and are reading, a receipt is something you glance at
 * to confirm the system understood you. Same glass, no emphasis, no colour.
 *
 * Amber does not appear here. UX-005 law 5 gives it to Needs You alone, and a refusal is not
 * an alarm - nothing happened, and nothing was lost.
 */
/* The receipt is a quick account of a completed write, so it remains one material quieter than
   an answer. Neither gets a domain hue: capture is shared by every place. */
/* I1: the Activity card's shape (1:3671) on the receipt's quieter M2. */
.receipt {
  margin-top: 10px; padding: 8px;
  border-radius: var(--r-lg);
  background: var(--m2); border: 1px solid var(--m2-line);
  box-shadow: var(--m2-shadow);
  animation: arrive 200ms var(--ease) both;
}
.receipt[hidden] { display: none; }

/*
 * Plan 4 - what Raai did, a line per thing made (receipt.js). Each line is a row with the icon of
 * the place it went, and the row opens that place. The close button sits in the corner; the state
 * line ("Raai AI is reading this", "Kept as a note") is the card's quiet foot.
 */
.did { position: relative; display: flex; flex-direction: column; }
.did-list { list-style: none; margin: 0; padding: 0 36px 0 0; display: flex; flex-direction: column; }
.did-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 8px; border: 0; border-radius: var(--r-sm); background: transparent;
  font: inherit; color: var(--ink); text-align: left; cursor: pointer;
}
.did-row:hover { background: var(--m2-hi); }
.did-tile {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px;
  border-radius: var(--r-sm); background: var(--accent-soft); color: var(--accent);
}
.did-tile .i { width: 16px; height: 16px; }
.did-text { display: flex; flex-direction: column; min-width: 0; }
.did-what { font-size: var(--t-body); font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.did-meta { font-size: var(--t-meta); color: var(--ink-2); line-height: 1.4; font-variant-numeric: tabular-nums; }
.did-state {
  display: flex; align-items: center; gap: 8px; margin: 0; padding: 8px 44px 8px 8px;
  font-size: var(--t-meta); color: var(--ink-2); line-height: 1.4;
}
.did-list + .did-state { border-top: 1px solid var(--m2-hi); margin-top: 4px; }
.did-pulse { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); animation: did-pulse 1.2s var(--ease) infinite alternate; }
@keyframes did-pulse { from { opacity: 0.25; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .did-pulse { animation: none; } }
.did-close {
  position: absolute; top: 4px; right: 4px; display: grid; place-items: center;
  width: 32px; height: 32px; border: 0; border-radius: var(--r-pill); background: transparent;
  color: var(--ink-3); cursor: pointer;
}
.did-close:hover { color: var(--ink); background: var(--m2-hi); }
.did-close .i { width: 16px; height: 16px; }

/* ───────────────────────────────────────── the entity page — CAP-101
 *
 * A page, not a card: one column, generous headings, and the paragraph reading first because
 * it is how the entity reads rather than a list of its parts.
 *
 * `entity-link` is the control that opens one, and it is deliberately a class rather than an
 * attribute hook: an entity is reachable from anywhere it is named, and the handler keys on
 * the control's own identity so a rendered-but-unwired one cannot hide (see the trust suite).
 */
.entity-link {
  font: inherit; color: inherit; background: none; border: 0; padding: 0;
  cursor: pointer; text-align: left;
  border-bottom: 1px solid transparent;
}
.entity-link:hover { border-bottom-color: var(--accent-ring); }

/* An empty section SAYS something. It is never a blank space (P6, P8). */
/*
 * ── "Nothing is due today." is narration, and speaks like the reading (UX-006, then UX-013)
 *
 * There are two empty states in the product and the distinction between them is real: a
 * SURFACE with nothing at all gets `.empty` — a mark, a sentence, a sub — while a SECTION
 * with nothing inside a surface that has other content gets this. Twenty-one places use it.
 *
 * What was not right is that the two spoke in different voices. On Work, where every section
 * is empty, the reading said "Nothing outstanding that you have told me about." in serif and
 * the three lines directly beneath it said almost the same thing in sans. Two adjacent
 * sentences about your life, in two typefaces, for no reason a reader could recover.
 *
 * Serif, and deliberately at `--t-body` rather than `--t-prose`: it belongs to the section
 * it is standing in for, and an empty section has no business being louder than a full one.
 */
.e-empty {
  font-family: var(--sans);
  font-size: var(--t-body); color: var(--ink-2); margin: 8px 0 0;
}

/* The same words carry two contracts. An `.e-empty` is an honest unknown about the person's
   life; a failed request is an honest admission about this read. The latter must not masquerade
   as the former, but it also must not acquire an alarm colour, retry control or offline claim. */
.state-error {
  border-inline-start: 2px solid var(--ink-3); padding-inline-start: 11px;
}
.e-empty.state-error {
  font-family: var(--sans); font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2);
}
.empty.state-error { padding-inline-start: 13px; }
.empty.state-error p { font-family: var(--sans); font-size: var(--t-body); color: var(--ink-2); }
.empty.state-error .empty-mark {
  background: transparent; border-color: var(--m2-line); color: var(--ink-3);
}

/* ───────────────────────────────────────── Work, as the Figma draws it — CAP-102 / W1 (1:5148)
 *
 * NOT A BOARD. There is no column, no lane, no swimlane, no drag affordance and no drop
 * target here, and none is coming: an item closes because you said it did (UX-008).
 *
 * One column of the frame's parts: the H1, the headline facts and the reading; Today in one
 * card with its pair and callout; Outstanding as folds by who asked; Waiting on others; the
 * working context and Settled as folds; the knows card. The desk hosts the frame's 420 column
 * (UX-013 §12). Sizes between tiers take the nearer, ties up (UX-013 §6): 14 sets at 15, 12 at 13.
 */
#work {
  --place: var(--d-work);
  --place-soft: var(--d-work-soft);
}
@media (min-width: 861px) { #work { max-width: var(--desk-col); } }
@media (max-width: 860px) { #work { padding: 0 4px; } }
/* Work draws its own H1 (1:4745); the shared date header steps aside, as on the other places. */
body:has(#work:not([hidden])) .head h1, body:has(#work:not([hidden])) .head-sub { display: none; }
body:has(#work:not([hidden])) .head { margin-bottom: 0; }

.w-head { padding: 20px 0 12px; margin: 0 0 8px; }
.w-h1 { margin: 0; font-size: var(--t-title); font-weight: 600; line-height: 1; letter-spacing: -0.025em; color: var(--ink); }
.w-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 16px 0 0; }
.w-fact {
  display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 12px;
  background: var(--wk-fact); border: 1px solid transparent; border-radius: var(--r-sm);
}
.w-fact-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.w-fact-fig {
  font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-head);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.w-fact .i { flex: none; width: 14px; height: 14px; }
.w-fact-label {
  margin: 0; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* One item (1:4835): the circle that says it happened, the words, the date and the cost. */

.w-check {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-top: 2px; padding: 0; border: 0; background: none;
  color: var(--ink-2); cursor: pointer;
}
.w-check .i { width: 18px; height: 18px; }
.w-check:hover { color: var(--wk-ink); }
#work .w-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; margin: 6px 0 0; }
.w-dot { font-size: var(--t-micro); color: var(--ink-3); }

/* Folds (1:4902): the heading says what it holds; the chevron hides or shows the rest. */

.w-fhead { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 32px; }
.w-fname { margin: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.4; letter-spacing: -0.025em; color: var(--ink); }
.w-fold {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  padding: 0; border: 0; border-radius: var(--r-sm); background: none; color: var(--ink-2); cursor: pointer;
}
.w-fold .i { width: 16px; height: 16px; transition: transform var(--dur) var(--ease); }
.w-fold[aria-expanded="true"] .i { transform: rotate(180deg); }
.w-fbody { padding-top: 8px; }

/* Owner testing found the explanations competing with the answer. Disclosure stays reachable,
 * while material unknowns stay beside the figure they qualify rather than inside this fold. */
summary.knows-h { cursor: pointer; display: list-item; list-style-position: inside; margin: 0; }
.knows[open] > .knows-h { margin-bottom: 12px; }
.knows-h .i { display: none; }
/* A group is a label and its rows inside the Small things card, not a second card inside the first
   (review F-19: two nested boxes, each with its own border, fill and radius). A rule divides groups. */

.s-entry-text { display: flex; flex-direction: column; gap: 5px; text-align: left; }
.s-entry-purpose, .m-kpi-note { display: block; font-size: var(--t-meta); color: var(--ink-2); line-height: 1.5; }
.s-entry-purpose { font-weight: 400; }
.layer-back, .nt-round, .nt-more, .nt-crumb, .n-attach { min-height: 44px; min-width: 44px; }
.m-more {
  /*
   * The pills WRAP at narrow widths (owner testing, 28 September 2026): a row that scrolled
   * sideways hid them off the edge at 375px, and none should need a swipe to be found.
   */
  display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px;
}
.s-unit { font-size: var(--t-meta); color: var(--ink-2); }
.s-save, .s-device-notifications { padding: 10px 16px; min-height: 44px; background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-sm); color: var(--ink); font: inherit; }
.s-save { margin-left: auto; }

/* The working context (1:5020): links into the domain that owns each thing, never copies. */

.w-check:focus-visible, .w-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A link into the domain that owns the thing — never a copy of it. Shared by every surface. */
.w-link {
  font: inherit; font-size: var(--t-meta); color: var(--ink); background: var(--m2);
  border: 1px solid var(--m2-line); border-radius: var(--r-sm);
  padding: 5px 10px; margin: 0 6px 6px 0; cursor: pointer;
}
.w-link:hover { border-color: var(--accent-ring); }

/* ───────────────────────────────────────── Today, redesigned — CAP-108
 *
 * "The fix is not more cards — it is bigger, fewer, better-ranked content" (§I).
 *
 * HIERARCHY IS CARRIED BY SIZE, SPACE AND MATERIAL: the reading is the one raised briefing,
 * the working middle is a set of content-bearing sections, and the tail recedes. The desktop
 * grid is deliberately asymmetric; it composes two reading columns rather than tiling peers.
 */
/*
 * The depth-1 reading once had one class here, `.t-reading`, shared by Today and Time. T1 and
 * Ti1 set both readings as the frame's body-size paragraph under a title (`.t-lede`, `.ti-lede`),
 * so it had no user left and went. Reminders keeps its own (`.r-reading`); Notes' `.n-reading` became
 * the subline under the bar's title at R3.
 */

/*
 * T1 · Today as the Figma draws it (1:710, UX-013).
 *
 * One column of the frame's cards on a warm ground: the header, the two figures, the timeline,
 * then every section the frame's refused tabs held (UX-013 §9). The desk hosts the column at the
 * frame's own width until desktop frames exist (UX-013 §12), so the two-column desk layout of
 * UX-011.5 is gone.
 */
#today {
  /* Phase 1C bound this identity on the transport. The surface binds the same pair locally so
   * every Today-specific mark has one source and the system focus accent stays a focus colour. */
  --place: var(--d-today);
  --place-soft: var(--d-today-soft);
}
@media (min-width: 861px) { #today { max-width: var(--desk-col); } }

/* The ground token itself, so every surface that paints the ground paints Today's here. */
body:has(#today:not([hidden])) {
  --ground: var(--today-ground);
  background: linear-gradient(var(--today-wash), transparent 900px) no-repeat, var(--today-ground);
}

/* The header (1:533). The eyebrow's 12 and the date's 28 take the micro and title tiers. */
.t-head { padding: 8px 8px 0; margin: 0 0 24px; }
.t-eyebrow {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-size: var(--t-micro); font-weight: 700; line-height: 18px; letter-spacing: 0.05em;
  text-transform: uppercase; color: color-mix(in srgb, var(--d-today) 80%, transparent);
}
.t-eyebrow .i { width: 14px; height: 14px; }
.t-h1 {
  font-size: var(--t-title); font-weight: 600; line-height: 1.25; letter-spacing: -0.025em;
  color: var(--ink); margin: 8px 0 0;
}
.t-lede {
  font-family: var(--sans); max-width: 62ch;
  font-size: var(--t-body); line-height: 1.5; color: var(--ink-2);
  margin: 4px 0 0; text-wrap: pretty; font-variant-numeric: tabular-nums;
}

/*
 * ── The card kit (plan 4, UX-024) ────────────────────────────────────────────────────────
 *
 * One card for every place that is a set of answers - Today first, then Time and Work: an icon
 * tile in the place's hue and a label, a "See all" to the page that has the rest, and rows that
 * each open the sentence behind them. The owner asked for "cards that have a label or an icon"
 * instead of loose text; this is that card, once.
 */
.k-card {
  margin: 0 0 12px; padding: 16px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
  --k-hue: var(--place, var(--accent)); --k-soft: var(--place-soft, var(--accent-soft));
}
.k-head { display: flex; align-items: center; gap: 10px; margin: 0 0 6px; min-height: 32px; }
.k-icon {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px;
  border-radius: var(--r-sm); background: var(--k-soft); color: var(--k-hue);
}
.k-icon .i { width: 16px; height: 16px; }
.k-title { flex: 1; margin: 0; font-size: var(--t-date); font-weight: 650; line-height: 1.3; letter-spacing: -0.025em; text-transform: none; color: var(--ink); }
.k-link {
  display: inline-flex; align-items: center; gap: 2px; min-height: 32px; padding: 0 2px;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--t-meta); font-weight: 600; color: var(--ink-2);
}
.k-link .i { width: 14px; height: 14px; }
.k-link:hover { color: var(--ink); }

/* A row: an optional lead (a circle to say it happened), the words and a quiet second line. */
.k-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px;
  padding: 10px 0; border-top: 1px solid var(--m2-hi);
}
.k-head + .k-row, .k-head + .k-slot { border-top: 0; }
.k-row > .w-check { margin-top: 0; }
.k-text {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 0; border: 0; background: none; text-align: left; cursor: pointer; font: inherit;
}
/*
 * A row's words are a column: on a touch screen the shared evidence rule (`button.ev-text`, a
 * wrapping row centred for a 44px target) centred this column across the card - every title sat in
 * the middle of its row on the phone (seen on the emulator, plan 4). Left, top to bottom, vertically
 * centred in its 44px; the circle beside it centres with it.
 */
button.k-text { flex-wrap: nowrap; align-content: normal; align-items: flex-start; justify-content: center; padding: 0; text-align: left; }
.k-what { display: block; font-size: var(--t-body); font-weight: 560; line-height: 1.35; color: var(--ink); overflow-wrap: anywhere; }
/* Your words as you said them, so Raai AI's wording can replace them; only the first letter is set up. */
.k-what::first-letter { text-transform: uppercase; }
/* A row closed on Work (`dim`): kept in Done, quieter and struck through, never removed (P7). */
.w-item.dim .k-what { color: var(--ink-3); text-decoration: line-through; text-decoration-thickness: 1px; }
.k-meta { font-size: var(--t-meta); line-height: 1.35; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.k-meta.is-near, .k-meta .is-near { color: var(--wk-near); font-weight: 600; }
.k-meta.is-gone, .k-meta .is-gone { color: var(--ink-3); }
.k-meta .w-dot { margin: 0 6px; color: var(--ink-3); }
.k-row .ev-said, .k-slot .ev-said { flex: 1 1 100%; margin: 6px 0 0; padding: 0; }
.k-more { margin: 6px 0 0; font-size: var(--t-meta); color: var(--ink-3); }
.k-done {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px; margin: -4px -4px 0 0;
  border: 0; border-radius: var(--r-pill); background: var(--m2-hi); color: var(--ink-2); cursor: pointer;
}
.k-done .i { width: 16px; height: 16px; }
.k-done:hover { color: var(--ink); }

/* A slot of the day: the clock in a column of its own, a bar in the kind's colour, the name. */
.k-slot {
  display: grid; grid-template-columns: 92px 3px minmax(0, 1fr); align-items: start; column-gap: 12px;
  padding: 10px 0; border-top: 1px solid var(--m2-hi);
}
.k-clock { font-size: var(--t-meta); font-weight: 600; line-height: 1.35; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-bar { align-self: stretch; min-height: 20px; border-radius: var(--r-pill); background: var(--k-hue); }
.k-slot.is-block .k-bar { background: var(--ink-faint); }
.k-slot.is-past { opacity: 0.55; }
.k-slot.is-now .k-clock { color: var(--k-hue); }
.k-slot .ev-said { grid-column: 3; }
/* Free time is open ground: a dashed bar and quieter words. A measured night or workout is the device's. */
.k-slot.is-free .k-bar { background: none; border-left: 2px dashed var(--ink-faint); }
.k-slot.is-free .k-what { color: var(--ink-2); font-weight: 500; }
.k-slot.is-sleep .k-bar, .k-slot.is-exercise .k-bar { background: var(--d-life); opacity: 0.5; }
/* A card title's second line ("5h free · longest stretch 4h 15m"), and a day heading inside a card. */
.k-sub { display: block; margin-top: 2px; font-size: var(--t-meta); font-weight: 500; letter-spacing: 0; color: var(--ink-2); }
.k-day {
  margin: 14px 0 0; padding: 0;
  font-size: var(--t-micro); font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3);
}
.k-head + .k-day { margin-top: 4px; }
.k-day + .k-row { border-top: 0; }
.ti-reminders { margin: 4px 0 12px; }

/* Life's rows (UX-026): a contact's letter, or a thing's glyph, then the name and one live line. */
.k-avatar {
  flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--r-pill);
  background: var(--ent-person-soft, var(--k-soft)); color: var(--ent-person, var(--k-hue));
  font-size: var(--t-body); font-weight: 650;
}
.k-avatar.is-thing, .k-avatar.is-door { border-radius: var(--r-sm); background: var(--m2-hi); color: var(--ink-2); }
.k-avatar .i { width: 16px; height: 16px; }
.k-row.l-erow, .k-row.k-door { align-items: center; }
.k-row > .i { flex: none; width: 16px; height: 16px; color: var(--ink-3); }
.k-door {
  width: 100%; margin: 0; border: 0; border-top: 1px solid var(--m2-hi); border-radius: 0;
  background: none; font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.k-head + .k-door { border-top: 0; }
.l-srow .k-text { cursor: default; }
.k-fold > summary { cursor: pointer; list-style: none; padding: 8px 0 2px; }
.k-fold > summary::-webkit-details-marker { display: none; }
.k-fold > summary::before { content: '+ '; }
.k-fold[open] > summary::before { content: '− '; }
.k-people, .k-things, .k-open, .k-thoughts { --k-hue: var(--d-life); --k-soft: var(--d-life-soft); }

/* Money's two figures side by side, and the next thing due under them. */
.k-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; padding: 6px 0 12px; }
.k-stat { min-width: 0; }
.k-stat-label { margin: 0; font-size: var(--t-meta); color: var(--ink-2); }
.k-stat-fig { margin: 2px 0 0; font-size: var(--t-date); font-weight: 650; letter-spacing: -0.02em; color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.k-stat .k-meta { margin: 2px 0 0; display: block; }
.k-next {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: baseline; column-gap: 10px;
  padding: 10px 0 0; border-top: 1px solid var(--m2-hi);
}
.k-next .k-meta:last-child { grid-column: 2 / -1; }
.k-amt { font-size: var(--t-body); font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-amt.is-in { color: var(--in); }

/* Each card takes its place's hue; a reminder and a question take attention's amber (UX-013 §10). */
.k-schedule, .k-week { --k-hue: var(--d-time); --k-soft: var(--d-time-soft); }
.k-todo, .k-waiting { --k-hue: var(--d-work); --k-soft: var(--d-work-soft); }
.k-money { --k-hue: var(--d-money); --k-soft: var(--d-money-soft); }
.k-amber { --k-hue: var(--attn-mark); --k-soft: var(--attn-wash); border-color: var(--attn-edge); }
.k-amber .k-title { color: var(--attn); }
.k-card .c-check { border-left: 2px solid var(--ember); padding: 4px 0 4px 11px; margin-top: 8px; }

.t-if {
  flex: 1 1 100%;
  margin: 6px 0 0;
  font-size: var(--t-meta); line-height: 1.45; color: var(--ink-2);
}

/*
 * ADR-029: a question from the model's check, built from drawn parts only (UX-015). In Needs you it
 * is a Needs You row - the ember rule on the left, which UX-005 gives to Needs You alone; in the
 * tray it is the receipt's quieter card. Your sentence as a quote, each reading as a labelled list
 * under the group label's type, the answers as lens pills (I1) with the model's carrying the pressed
 * pill's weight, because it is offered first.
 */
.c-check { display: flex; flex-direction: column; gap: 4px; }
.c-said { margin: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.c-head { margin: 0; font-size: var(--t-meta); line-height: 1.45; color: var(--ink-3); }
.c-who {
  margin: 8px 0 0; padding: 0;
  font-size: var(--t-micro); font-weight: 600; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-3);
}
.c-lines { list-style: none; margin: 0; padding: 0; }
.c-lines li {
  font-size: var(--t-body); line-height: 1.5; color: var(--ink);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.c-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; }
.c-answer.is-first { color: var(--m2); background: var(--ink); border-color: var(--ink); box-shadow: var(--m2-shadow); }
.c-answer:disabled { opacity: 0.6; cursor: default; }

/*
 * ADR-031: a figure Raai AI worked out itself, marked where it stands - the ink it sits in, a dotted
 * hairline under it and the ≈ in front, never a new hue. The note under the answer says what the
 * mark means, in the meta line's type.
 */
.turn-reasoned .est { border-bottom: 1px dotted var(--ink-3); font-variant-numeric: tabular-nums; }
.est-note { margin: 4px 0 0; font-size: var(--t-meta); line-height: 1.45; color: var(--ink-3); }

/* ───────────────────────────────────────── Time, as the Figma draws it — CAP-080 / Ti1 (1:1089)
 *
 * The H1 and this week's strip, then the day as a card of rows (the card kit, `.k-slot`), Coming
 * up by day, and a tight week only when there is one (plan 4, UX-025). The desk hosts the frame's
 * 420 column (UX-013 §12).
 */
#time {
  --place: var(--d-time);
  --place-soft: var(--d-time-soft);
}
@media (min-width: 861px) { #time { max-width: var(--desk-col); } }
@media (max-width: 860px) { #time { padding: 0 4px; } }
/* Time draws its own H1 (1:1091); the shared date header steps aside, as on the other places. */
body:has(#time:not([hidden])) .head h1, body:has(#time:not([hidden])) .head-sub { display: none; }
body:has(#time:not([hidden])) .head { margin-bottom: 0; }

.ti-head { padding: 0 0 16px; }
.ti-h1 { margin: 0; font-size: var(--t-title); font-weight: 600; line-height: 1; letter-spacing: -0.025em; color: var(--ink); }

/*
 * The week strip (1:1142). Since Ti2 a day inside the horizon is a button (F-26): the frame's
 * filled circle marks the day the card shows - today, until you pick another - and today keeps
 * Time's hue in its letter and figure when it is not the one shown. A day outside the horizon
 * is a plain span, dimmed, because a day you cannot open must not look like one.
 */
.ti-week { display: flex; justify-content: space-between; margin: 20px 0 0; padding: 0 4px; }
.ti-day {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin: 0; padding: 0; border: 0; background: none; font: inherit; color: inherit;
}
button.ti-day { cursor: pointer; border-radius: var(--r-sm); }
button.ti-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ti-day.is-out { opacity: 0.45; }
.ti-dl { font-size: var(--t-micro); font-weight: 700; line-height: 1.5; text-transform: uppercase; color: var(--ink-3); }
.ti-dn {
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border-radius: var(--r-pill); font-size: var(--t-body); font-weight: 600; color: var(--ink-head);
  font-variant-numeric: tabular-nums;
}
.ti-day.is-past .ti-dn { color: var(--ink-3); }
.ti-day.is-today .ti-dl { color: var(--ti-today-ink); }
.ti-day.is-today .ti-dn { color: var(--ti-today-ink); }
.ti-day.is-selected .ti-dn { background: var(--d-time); color: var(--ti-on-time); box-shadow: var(--m2-shadow); }
@media (hover: hover) {
  button.ti-day:not(.is-selected):hover .ti-dn { background: var(--m2-hi); }
}
/* A thumb's target: the column is already taller than 44px; this makes it 44px wide too. */
@media (hover: none) {
  button.ti-day { min-width: 44px; }
}
/* "At 10 - in the morning or the evening?" (CAP-074): the question in the uncertainty colour, the answers as pills. */
.k-row > .ti-hourq { flex: 1 1 100%; }
.ti-hourq-ask { margin: 6px 0 0; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--attn-mark); }
.ti-hourq-pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; }

/* ───────────────────────────────────────── Money overview — CAP-103 / Phase 3A
 *
 * §I asks Money to hold everything Gate 1 proved without becoming a dashboard. The overview
 * answers one question before the lenses: where you stand, the low it reaches, and its modeled
 * direction. The lowest point is the hero; available and net worth are supporting facts, and
 * the trajectory is context rather than a second headline.
 *
 * Digits are tabular throughout. A column of amounts that does not line up is a column you
 * cannot scan, and scanning is the entire reason a person opens this.
 */
#money { --place: var(--d-money); --place-soft: var(--d-money-soft); }
/*
 * UX-013 §12: there is no desktop frame yet, so the desk hosts the Figma's mobile column at its
 * own width (420) rather than stretching its cards across the pane. Replaced when the owner's
 * desktop frames exist.
 */
@media (min-width: 861px) { #money { max-width: var(--desk-col); } }
/*
 * M1 · the header as the Figma draws it (1:1679-1:1754, shared by the six Money frames).
 *
 * The reading is the page's H1, at the Figma H1 (UX-013 §1, B-03); the date header above it
 * belongs to Today and steps aside here (see .head below). Its later clauses are the subline,
 * with the date the server marked set in ink.
 */
.m-head { padding: 8px 8px 0; margin: 0 0 24px; }
.m-h1 {
  font-family: var(--sans);
  font-size: var(--t-title); font-weight: 600; line-height: 1.25; letter-spacing: -0.025em;
  color: var(--ink); margin: 0; text-wrap: balance; font-variant-numeric: tabular-nums;
}
.m-lede {
  font-size: var(--t-body); line-height: 1.5; color: var(--ink-2);
  margin: 4px 0 0; text-wrap: pretty; font-variant-numeric: tabular-nums;
}
/* How fresh the H1's figure is, now that no card repeats the figure beside it (F-18, P8). */
.m-asof { font-size: var(--t-meta); color: var(--ink-3); margin: 6px 0 0; }
/* What the server emphasised. Ink, never a hue; the one exception is the floor you named,
   in amber, when a projection goes under it (UX-013 §10). */
.m-em { font-weight: 500; color: var(--ink); }
.m-insight-text .m-em { font-weight: 600; }
.m-insight-text .m-em-attn { font-weight: 500; color: var(--attn); }

/*
 * The two figures, as two cards side by side (1:1687) - still two figures, never one: what
 * you can reach and what you own differ, and one number would have to choose which lie to
 * tell (CAP-095). They stay two-up down to the narrowest phone; a long range wraps inside its
 * card rather than truncating.
 */
.m-kpis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0 0 24px; }
/* One card left once the H1 carries the reachable figure: it takes the row, not half of it. */
.m-kpis:has(> .m-kpi:only-child) { grid-template-columns: minmax(0, 1fr); }
.m-kpi {
  display: flex; flex-direction: column; justify-content: space-between; gap: 12px;
  min-height: 130px; padding: 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.m-kpi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
/* 12px in the frame; the nearest tier is 13 (UX-013 §6). */
.m-kpi-label { font-size: var(--t-meta); font-weight: 500; line-height: 1.3; color: var(--ink-2); margin: 0; }
.m-kpi-chip {
  flex: none; width: 24px; height: 24px; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center;
}
.m-kpi-chip .i { width: 12px; height: 12px; }
.m-kpi-available .m-kpi-chip { color: var(--d-money); background: var(--d-money-soft); }
.m-kpi-worth .m-kpi-chip { color: var(--invest); background: var(--invest-soft); }
.m-kpi-figure {
  font-size: var(--t-figure); font-weight: 600; line-height: 1.5; letter-spacing: -0.025em;
  color: var(--ink); margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
/* Money's own hue on what you can reach, as drawn. It marks the place, not a verdict. */
.m-kpi-available .m-kpi-figure { color: var(--d-money); }
.m-kpi-age { font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-3); margin: 4px 0 0; }

/*
 * The lowest point and the tightest window, as the Figma's two insight cards (1:1723): a
 * glyph, a title and one sentence, then the admissions that belong to that sentence - a
 * floor distance, a caveat, the days the system filled in. Cards because prose loses which
 * admission belongs to which figure.
 *
 * Neutral by default. Amber-soft only when the server marks the card uncertain, which is a
 * projection (UX-013 §10) - never because a figure looks bad.
 */
.m-insights { display: flex; flex-direction: column; gap: 12px; margin: 0 0 24px; }
.m-insight {
  display: flex; align-items: flex-start; gap: 12px; padding: 16px;
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
}
.m-insight-uncertain { background: var(--attn-wash); border-color: var(--attn-edge); }
.m-insight-glyph { flex: none; padding-top: 2px; line-height: 0; color: var(--ink-2); }
.m-insight-glyph .i { width: 18px; height: 18px; }
.m-insight-uncertain .m-insight-glyph { color: var(--attn-mark); }
.m-insight-body { flex: 1 1 auto; min-width: 0; }
/* 14px in the frame; a card title takes the body tier (UX-013 §6). */
.m-insight-title { font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink); margin: 0; }
.m-insight-text {
  font-size: var(--t-meta); line-height: 1.625; color: var(--ink-body);
  margin: 4px 0 0; text-wrap: pretty; font-variant-numeric: tabular-nums;
}
.m-insight .m-floor { margin-top: 10px; }
.m-insight .m-caveat, .m-insight .m-note, .m-insight .m-lands { margin-top: 6px; }

.m-sec { margin-bottom: 24px; }

/*
 * M2 · Accounts, as the Figma draws them (1:1825-1:1908). Grouped by what an account can DO.
 * Each group is its uppercase label with its total (the total sits with the heading, so a
 * group never reads as a running column it is not), then a card per account, then the
 * group's note: what its money counts toward.
 */
.m-group { margin: 0 0 24px; }
.m-ghead { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 0 4px; }
/* The group tier, at the Figma's weight and tracking (bold, 0.05em). Scoped to Money until each
   screen's phase adopts it; the list rule's padding does not apply inside a card group. */
.m-ghead .m-what { margin: 0; padding: 0; font-weight: 700; letter-spacing: 0.05em; line-height: 1.5; }
/* 14px in the frame; a figure takes the body tier (UX-013 §6, ties go up). */
.m-gtotal {
  font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink);
  font-variant-numeric: tabular-nums; text-align: right;
}
.m-rows { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; }
.m-acard {
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
/* The whole card is the control: the way to the account's page, or a holding's evidence. */
.m-acct, .m-acard > .ev-text {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 16px;
  font: inherit; text-align: left; color: inherit; cursor: pointer;
  background: none; border: 0; border-radius: inherit;
}
.m-acct:hover .m-acard-name, .m-acct:focus-visible .m-acard-name { color: var(--d-money); }
.m-tile {
  flex: none; display: inline-flex; padding: 8px; border-radius: var(--r-sm);
  background: var(--m2-hi); color: var(--ink-body);
}
.m-tile .i { width: 18px; height: 18px; }
.m-acard-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.m-acard-name {
  font-size: var(--t-date); font-weight: 600; line-height: 1.5; color: var(--ink);
  overflow-wrap: anywhere;
}
/* 12px and lightly tracked in the frame; the meta tier is 13 (ties go up). */
.m-acard-meta {
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; letter-spacing: 0.02em;
  color: var(--ink-2); margin-top: 2px;
}
/*
 * The balance in ink, including a credit card's. The Figma draws that one rose; UX-013 §10
 * keeps red for money going out, and a card balance is a stock of debt, not a movement.
 */
.m-acard-bal {
  flex: none; font-size: var(--t-date); font-weight: 600; line-height: 1.5; color: var(--ink);
  text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.m-acard-bal.m-unknown { font-style: italic; font-weight: 500; color: var(--ink-3); }
/* An account's kind and freshness, in sentence case: only the first letter is raised. Every word
   raised ("About 4 Weeks Ago") read as a label pasted from a mockup (review F-18). */
.m-acct .m-acard-meta::first-letter { text-transform: uppercase; }
.m-acard > .m-note { margin: 0; padding: 0 16px 14px; }
/* Money's home Accounts card (plan 4): the same row, flat in the card, a hairline between. */
.m-hacct {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 0;
  font: inherit; text-align: left; color: inherit; cursor: pointer;
  background: none; border: 0; border-top: 1px solid var(--m2-hi);
}
.m-kcard-head + .m-hacct { border-top: 0; }
.m-hacct .m-acard-name, .m-hacct .m-acard-bal { font-size: var(--t-body); }
.m-hacct .m-acard-meta::first-letter { text-transform: uppercase; }
.m-hacct:hover .m-acard-name { color: var(--d-money); }
.m-add-acct { margin-top: 10px; }
.m-acard > .ev-said { margin: 0; padding: 0 16px 16px; }
.m-gnote { font-size: var(--t-meta); line-height: 1.4; color: var(--ink-3); margin: 0; padding: 8px 8px 0; }

/* What you hold: the same group, in the Figma's indigo tint, so a holding never reads as cash. */
.m-hcard { background: var(--invest-wash); border-color: var(--invest-edge); box-shadow: none; }
.m-hcard .m-tile { background: var(--invest-tile); color: var(--invest); }
.m-hcard .m-change {
  display: block; font-size: var(--t-meta); font-weight: 600; line-height: 1.4;
  letter-spacing: 0.02em; color: var(--invest); margin-top: 2px; font-style: normal;
}
/* "no change stated" is words, not a figure, so it is not dressed as one. */
.m-hcard .m-nochange { font-weight: 500; color: var(--ink-3); }

/*
 * M3 · Activity, as the Figma draws it (1:2182-1:2240). One card; each server-worded day an
 * uppercase header over a hairline; each movement a row - its words and amount, then its kind
 * and category, then a transfer's chip. The amount's colour is the server's `direction` and
 * nothing else: money in green, money that only changed place blue, money out in ink. Rose is
 * not used: the frame sets spending in ink, and "money spent" says it in words.
 */
.m-activity {
  padding: 8px; margin: 0 0 24px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.m-activity .m-tx-empty { margin: 0; padding: 12px 16px; }
.m-activity .m-date {
  margin: 0; padding: 12px 16px; border-bottom: 1px solid var(--m2-line);
  font-size: var(--t-meta); font-weight: 700; line-height: 1.5; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-3);
}
.m-tx + .m-tx { border-top: 1px solid var(--m2-hi); }
/* The whole row is its evidence tap (UX-013 §11): a column, not the shared inline row. */
.m-tx > .ev-text {
  display: flex; flex-direction: column; align-items: stretch; gap: 0; width: 100%;
  padding: 16px; border: 0; border-radius: var(--r-sm); color: inherit; cursor: pointer;
}
/*
 * The full width of the row, set rather than left to `stretch`: inside the button the line sized to
 * its content and sat centred, so a short label and its figure floated mid-row. Unseen while every
 * label was a whole sentence that filled the row; plain the first time one was a word ("coffee",
 * entered with a form - CAP-134).
 */
.m-tx-top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding-bottom: 4px; width: 100%; box-sizing: border-box; }
.m-tx-what {
  min-width: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink);
  overflow-wrap: anywhere;
}
.m-tx > .ev-text:hover .m-tx-what, .m-tx > .ev-text:focus-visible .m-tx-what { color: var(--d-money); }
.m-tx-amt {
  flex: none; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}
.m-tx-amt.is-in { color: var(--in); }
.m-tx-amt.is-transfer { color: var(--transfer); }
.m-tx-amt.is-uncounted { font-weight: 500; color: var(--ink-3); }
/* 12px in the frame; the meta tier is 13 (ties go up). */
.m-tx-meta { font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2); }
.m-tx-chip {
  align-self: flex-start; margin-top: 8px; padding: 4px 8px;
  font-size: var(--t-meta); font-weight: 400; line-height: 1.4; color: var(--ink-2);
  background: var(--m2); border: 1px solid var(--m3-line); border-radius: var(--r-xs);
}
.m-tx > .ev-said { margin: 0; padding: 0 16px 16px; }
/* The month's figure closes the card; it describes the month, never the day above it. */
.m-tx-foot {
  margin: 0; padding: 12px 16px; border-top: 1px solid var(--m2-line);
  font-size: var(--t-meta); font-weight: 500; line-height: 1.5; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.m-activity > .m-tx-empty + .m-tx-foot { border-top: 0; padding-top: 0; }

/*
 * M6 · People, as the Figma draws it (1:3048-1:3105). One card of what is owed either way: a
 * round person tile tinted by direction, the name, which way in the same colour, the amount in
 * ink. Below the card, outside it, every ended debt - faded, struck, with the day it ended
 * (PD-025). Direction is the server's `toYou`, never a word read here.
 */
.m-prows { display: flex; flex-direction: column; padding-top: 16px; }
.m-prow + .m-prow { border-top: 1px solid var(--m2-hi); }
.m-prows .m-prow { padding: 16px 0; }
.m-prows .m-prow:first-child { padding-top: 0; }
.m-prows .m-prow:last-child { padding-bottom: 0; }
.m-prow > .ev-text {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 0; border: 0; color: inherit; cursor: pointer; text-align: left;
}
.m-prow > .ev-said { margin: 8px 0 0; padding: 0; }
.m-ptile {
  flex: none; display: inline-flex; padding: 8px; border-radius: var(--r-pill);
  background: var(--d-money-soft); color: var(--in);
}
/* What you owe someone is a stock of debt, not money leaving, so it is never red (UX-013 §10). */
.m-ptile.is-out { background: var(--m3); color: var(--ink-2); }
.m-ptile .i { width: 18px; height: 18px; }
.m-ptext { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.m-pwho { font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.m-pdir { font-size: var(--t-meta); font-weight: 500; line-height: 1.5; color: var(--in); }
.m-ptile.is-out + .m-ptext .m-pdir { color: var(--ink-2); }
.m-pamt {
  flex: none; font-size: var(--t-date); font-weight: 600; line-height: 1.5; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.m-prow > .ev-text:hover .m-pwho, .m-prow > .ev-text:focus-visible .m-pwho { color: var(--d-money); }

/* Ended: kept, never deleted (P7), and read as finished - half strength, struck through. */
.m-pended { display: flex; flex-direction: column; margin: 0 0 16px; }
.m-prow.is-ended { opacity: 0.5; padding: 8px 16px; }
.m-prow.is-ended .m-ptile { padding: 0; background: none; color: var(--ink-2); }
.m-prow.is-ended .m-pwho { color: var(--ink-2); text-decoration: line-through; }
/* 12px in the frame; the meta tier is 13 (ties go up). */
.m-prow.is-ended .m-pdir { font-weight: 400; color: var(--ink-3); }
.m-prow.is-ended .m-pamt { font-size: var(--t-body); color: var(--ink-3); text-decoration: line-through; }
.m-prow.is-ended + .m-prow.is-ended { border-top: 0; }

/*
 * M5 · Coming, as the Figma draws it (1:2786-1:2826): the timeline. A hairline down the card's
 * left; each day a 12px dot on it over a white ring, rose for money going out and green for money
 * coming in, above its uppercase date and its row cards. A row coming in takes the frame's green
 * wash. Direction is the view model's `direction`, never an amount's sign or a word.
 */
.m-timeline {
  list-style: none; margin: 24px 0 0 12px; padding: 0 0 0 24px;
  border-left: 1px solid var(--m2-line);
  display: flex; flex-direction: column; gap: 24px;
}
.m-tl { position: relative; }
.m-tl.m-tl-same { margin-top: -16px; }
.m-tl-dot {
  position: absolute; left: -31px; top: 4px; width: 12px; height: 12px; border-radius: var(--r-pill);
  background: var(--tl-out); box-shadow: 0 0 0 4px var(--m2);
}
.m-tl.is-in .m-tl-dot { background: var(--tl-in); }
/* 12px bold uppercase in the frame: the group label, at the micro tier. */
.m-tl-day {
  margin: 0; font-size: var(--t-micro); font-weight: 700; line-height: 1.6;
  text-transform: uppercase; color: var(--ink-3);
}
.m-tl-card {
  margin-top: 4px; border-radius: var(--r-sm);
  background: var(--m2-hi); border: 1px solid var(--m2-line);
}
.m-tl.is-in .m-tl-card { background: var(--in-wash); border-color: var(--in-edge); }
.m-tl-card > .ev-text {
  display: flex; flex-direction: column; align-items: stretch; gap: 0; width: 100%;
  padding: 12px; border: 0; border-radius: inherit; color: inherit; cursor: pointer; text-align: left;
}
.m-tl-card > .ev-said { margin: 0; padding: 0 12px 12px; }
.m-tl-top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.m-tl-what { min-width: 0; font-size: var(--t-date); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.m-tl-amt {
  flex: none; font-size: var(--t-date); font-weight: 600; line-height: 1.5; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.m-tl-meta { padding-top: 4px; font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2); }
.m-tl.is-in .m-tl-what { color: var(--in-ink); }
.m-tl.is-in .m-tl-amt { color: var(--in-deep); }
.m-tl.is-in .m-tl-meta { color: var(--in-meta); }
.m-tl-card > .ev-text:hover .m-tl-what, .m-tl-card > .ev-text:focus-visible .m-tl-what { color: var(--d-money); }
.m-coming .e-empty { margin: 12px 0 0; }

/*
 * M7 · the Wishlist lens, as the Figma draws it (1:3327): one white card - the want the server
 * put first, its figure, its sentence, the floor in an inset, then the way to the full list
 * above a hairline. The frame's 14px sentence and 12px inset take the next tier up (15, 13).
 */
#money .m-wl {
  margin: 0; padding: 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.m-wl-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.m-wl-name, .m-wl-price {
  margin: 0; font-size: var(--t-prose); font-weight: 600; line-height: 24px; color: var(--ink);
}
.m-wl-price { flex: none; font-variant-numeric: tabular-nums; }
.m-wl-says { margin: 8px 0 0; font-size: var(--t-body); line-height: 1.625; color: var(--ink-body); text-wrap: pretty; }
.m-wl-says .wl-em, .m-wl-says .m-em { font-weight: 500; color: var(--ink); }
.m-wl-inset {
  display: flex; align-items: center; gap: 8px; margin: 16px 0 0; padding: 8px 12px; min-height: 52px;
  background: var(--m2-hi); border-radius: var(--r-sm);
  font-size: var(--t-meta); font-weight: 500; line-height: 18px; color: var(--ink-3);
}
.m-wl-inset .i { width: 14px; height: 14px; }
.m-wl-more { margin: 12px 0 0; font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2); }
.m-wl-open {
  display: flex; align-items: center; justify-content: center; gap: 4px; width: 100%;
  margin: 16px 0 0; padding: 12px 0 0; min-height: 33px;
  background: none; border: 0; border-top: 1px solid var(--m2-line); cursor: pointer;
  font: inherit; font-size: var(--t-meta); font-weight: 500; line-height: 19.5px; color: var(--link);
}
.m-wl-open .i { width: 14px; height: 14px; }
.m-wl-open:hover { text-decoration: underline; text-underline-offset: 3px; }
#money .m-wl .e-empty { margin: 0; }
/* Amber on the card's edge as well as in its words: the one want that takes you under your floor. */
#money .m-wl.m-breach { border-left: 2px solid var(--ember); padding-left: 19px; }
#money .m-part > .withheld { margin: 12px 4px 0; font-size: var(--t-meta); color: var(--ink-3); }

/*
 * M4 · Analysis, as the Figma draws it (1:2462-1:2563): three cards. Where it went is a ring with
 * its legend (PD-020), Unusual movement is an amber callout, What recurs is rows with a repeat
 * tile. Every row is its evidence tap.
 */
.m-an {
  margin: 0 0 16px; padding: 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.m-an-title {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-size: var(--t-date); font-weight: 600; line-height: 1.5; letter-spacing: -0.025em; color: var(--ink);
}
.m-an .e-empty { margin: 12px 0 0; }
/* Every Analysis row is a button that opens what you said; it is laid out, not inline. */
.m-leg > .ev-text, .m-urow > .ev-text, .m-rrow > .ev-text {
  display: flex; width: 100%; padding: 0; border: 0; color: inherit; cursor: pointer; text-align: left;
}
.m-leg > .ev-said, .m-urow > .ev-said, .m-rrow > .ev-said { margin: 6px 0 0; padding: 0; }

/* The chart tones (UX-013), for Where it went's split bar and its legend dots. */
.t-0 { --tone: var(--c-none); }
.t-1 { --tone: var(--c-1); }
.t-2 { --tone: var(--c-2); }
.t-3 { --tone: var(--c-3); }
.t-4 { --tone: var(--c-4); }
.t-5 { --tone: var(--c-5); }
.t-6 { --tone: var(--c-6); }
.m-split-block + .m-split-block { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--m2-line); }
/*
 * Where it went as one split bar (UX-022): segments as wide as their share, a 3px gap between, the
 * ends rounded, the total above it. The legend under it carries every figure in words.
 */
.m-split-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 12px 0 0; }
.m-split-head span { font-size: var(--t-meta); font-weight: 500; color: var(--ink-2); }
.m-split-head b { font-size: var(--t-figure); font-weight: 600; letter-spacing: -0.025em; color: var(--ink); font-variant-numeric: tabular-nums; }
.m-split { display: flex; gap: 3px; height: 14px; margin: 12px 0 0; }
.m-split i { display: block; min-width: 4px; height: 100%; border-radius: var(--r-xs); background: var(--tone); }
.m-legend-rows { display: flex; flex-direction: column; gap: 8px; padding-top: 16px; }
.m-leg > .ev-text { flex-direction: column; align-items: stretch; }
.m-leg-top { display: flex; align-items: center; gap: 8px; width: 100%; }
.m-dot { flex: none; width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--tone); }
/* A row the ring does not draw keeps its colour as a ring, not a fill: it has no segment. */
.m-dot.is-undrawn { background: none; box-shadow: inset 0 0 0 1.5px var(--tone); }
/* 14px in the frame; the body tier is 15 (ties go up). */
.m-leg-what { flex: 1 1 auto; min-width: 0; font-size: var(--t-body); line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }
.m-leg-pct { flex: none; font-size: var(--t-meta); font-weight: 500; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.m-leg-amt {
  flex: none; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.m-leg-note { padding-left: 16px; font-size: var(--t-meta); line-height: 1.4; color: var(--ink-2); }
.m-leg > .ev-text:hover .m-leg-what, .m-leg > .ev-text:focus-visible .m-leg-what { color: var(--d-money); }

/* Unusual movement: the frame's amber callout, flat and borderless of shadow. */
/* An ordinary card: "a whole card is never amber because the system disapproves" (UX-013 §10).
   Unusual is a fact about your own amounts, not a warning. */
.m-unusual .m-an-title { font-size: var(--t-body); color: var(--ink); }
.m-unusual .m-an-title .i { width: 18px; height: 18px; color: var(--ink-2); }
.m-urow { padding-top: 8px; }
/* 14px in the frame; the body tier is 15 (ties go up). */
.m-urow > .ev-text { font-size: var(--t-body); line-height: 1.6; color: var(--attn-ink); }

/* What recurs: a row per rhythm, its repeat tile, what and how often, the typical amount. */
.m-rrow { padding-top: 16px; }
/*
 * Budgets (PD-037, PD-039): a name and what is left, a 10px bar as full as the server's `fill`, and
 * "spent of limit · period" under it. The bar and the short figure take the tone's colour - green
 * under 75%, amber to the limit, red past it (PD-039, the owner's choice); the words stay PD-037's.
 */
.m-bud-row { display: flex; flex-direction: column; width: 100%; text-align: left; }
.m-bud-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.m-bud-title { font-size: var(--t-body); font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.m-bud-left { flex: none; font-size: var(--t-meta); font-weight: 600; font-variant-numeric: tabular-nums; }
.m-bar { display: block; height: 10px; margin: 8px 0 6px; overflow: hidden; border-radius: var(--r-pill); background: var(--m2-hi); }
.m-bar i { display: block; height: 100%; border-radius: var(--r-pill); }
.m-bud-meta { font-size: var(--t-meta); line-height: 1.5; color: var(--ink-3); }
[data-tone="under"] .m-bar i { background: var(--in); }
[data-tone="under"] .m-bud-left { color: var(--in); }
[data-tone="near"] .m-bar i { background: var(--attn-mark); }
[data-tone="near"] .m-bud-left { color: var(--attn-mark); }
[data-tone="over"] .m-bar i { background: var(--out); }
[data-tone="over"] .m-bud-left { color: var(--out); }
.m-bud-spent { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--m2-line); }
.m-bud-spent > .ev-text, .m-bud-spent > .ev-text span { padding: 0; min-height: 0; color: var(--ink-2); font-size: var(--t-meta); }
.m-bud-spent > .ev-said { margin: 6px 0 0; padding: 0; white-space: pre-line; }
.m-bud-note { margin: 6px 0 0; font-size: var(--t-meta); color: var(--ink-3); }
.m-bud-acts { display: flex; gap: 10px; margin-top: 12px; }
.m-bud-acts .s-save { margin: 0; }
.m-new {
  min-height: 44px; padding: 0 12px; font: inherit; font-size: var(--t-meta); font-weight: 600; color: var(--m2);
  background: var(--ink); border: 0; border-radius: var(--r-pill); cursor: pointer;
}
/* The sheet that sets or changes one: chips for what for, one field row, a segmented period. */
.m-sheet { display: flex; flex-direction: column; gap: 8px; }
.m-sheet[hidden] { display: none; }
.m-sheet-title { margin: 0 0 4px; font-size: var(--t-date); font-weight: 600; color: var(--ink); }
.m-sheet .m-what { margin: 8px 0 0; }
.m-chips, .m-seg { display: flex; flex-wrap: wrap; gap: 6px; }
.m-seg { flex-wrap: nowrap; padding: 3px; gap: 3px; background: var(--field); border-radius: var(--r-pill); }
.m-chip { position: relative; display: inline-flex; }
.m-seg .m-chip { flex: 1; }
.m-chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.m-chip span {
  flex: 1; min-height: 36px; display: inline-flex; align-items: center; justify-content: center; padding: 0 12px;
  font-size: var(--t-meta); font-weight: 500; color: var(--ink-2); background: var(--field); border-radius: var(--r-pill);
}
.m-chip input:checked + span { color: var(--m2); background: var(--ink); font-weight: 600; }
.m-chip input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.m-field-row { display: flex; gap: 8px; }
.m-field-row input, .m-bud-l input {
  min-height: 44px; padding: 8px 12px; font: inherit; font-size: var(--t-body); color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line); border-radius: var(--r-sm);
}
.m-field-row input[name="amount"] { flex: 1; min-width: 0; font-variant-numeric: tabular-nums; }
.m-bud-cur { width: 5.5rem; text-transform: uppercase; }
.m-bud-l { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; font-size: var(--t-meta); color: var(--ink-2); }
.m-bud-l[hidden] { display: none; }
.m-bud-rep { display: flex; align-items: center; gap: 8px; min-height: 44px; font-size: var(--t-meta); color: var(--ink-2); }
.m-sheet-acts { display: flex; gap: 10px; align-items: center; }
.m-sheet-acts .s-save { margin: 0; }
.m-sheet-cancel { min-height: 44px; padding: 0 12px; font: inherit; font-size: var(--t-meta); color: var(--ink-2); background: none; border: 0; cursor: pointer; }
.m-bud-said { margin: 0; font-size: var(--t-meta); color: var(--ink-2); }

/*
 * ── THE MONEY HOME, AND ITS PARTS (UX-022) ──────────────────────────────────────────────
 *
 * The home: the headline card, then short cards each with "See all", then More. Each part is a
 * layer over the home: the pane's `data-open` names it, and only it shows.
 */
#money .m-part { display: none; }
#money[data-open] .m-home { display: none; }
#money[data-open="budgets"] .m-part[data-part="budgets"],
#money[data-open="activity"] .m-part[data-part="activity"],
#money[data-open="coming"] .m-part[data-part="coming"],
#money[data-open="accounts"] .m-part[data-part="accounts"],
#money[data-open="analysis"] .m-part[data-part="analysis"],
#money[data-open="people"] .m-part[data-part="people"],
#money[data-open="wishlist"] .m-part[data-part="wishlist"] { display: block; }
.m-hero { min-height: 0; margin: 0 0 12px; }
.m-hero-fig {
  margin: 0; font-size: var(--t-title); font-weight: 700; line-height: 1.15; letter-spacing: -0.03em;
  color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.m-hero-split {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px;
  padding-top: 14px; border-top: 1px solid var(--m2-line);
}
.m-hero > .m-hero-split:first-child { padding-top: 0; border-top: 0; }
.m-hero-split p { margin: 0; display: flex; flex-direction: column; gap: 2px; }
.m-hero-two { font-size: var(--t-date); font-weight: 600; letter-spacing: -0.02em; color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.m-kcard, .m-part > .m-kcard {
  margin: 0 0 12px; padding: 16px 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg); box-shadow: var(--m2-shadow);
}
.m-kcard-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
.m-kcard-head .m-what, .m-sheet .m-what, .m-more-h { padding: 0; }
.m-kcard-head .m-what { margin: 0; }
.m-see {
  display: inline-flex; align-items: center; gap: 2px; min-height: 44px; padding: 0; margin: -12px 0;
  font: inherit; font-size: var(--t-meta); font-weight: 600; color: var(--ink-2); background: none; border: 0; cursor: pointer;
}
.m-see .i { width: 14px; height: 14px; }
.m-see:hover { color: var(--ink); }
.m-hbud { display: block; width: 100%; padding: 10px 0; font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.m-hbud + .m-hbud { border-top: 1px solid var(--m2-line); }
.m-hrow + .m-hrow { border-top: 1px solid var(--m2-line); }
.m-hrow > .ev-text { display: flex; flex-direction: column; align-items: stretch; width: 100%; padding: 10px 0; border: 0; color: inherit; cursor: pointer; text-align: left; }
.m-hrow > .ev-said { margin: 0 0 10px; padding: 0; }
/*
 * Money's laid-out rows (UX-022): the row's parts are flex items, so the template's own line breaks
 * must not become text between them. .row-text keeps pre-wrap for what a person wrote; here every
 * word sits in its own span, and the kept breaks centred the legend and stacked What recurs.
 */
.m-hrow > .ev-text, .m-leg > .ev-text, .m-rrow > .ev-text, .m-urow > .ev-text, .m-bud-spent > .ev-text,
.m-tx > .ev-text, .m-tl-card > .ev-text, .m-prow > .ev-text { white-space: normal; align-content: stretch; }
.m-hrow-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.m-hrow-what { font-size: var(--t-body); font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.m-hrow-meta { font-size: var(--t-meta); line-height: 1.5; color: var(--ink-3); }
.m-empty-act {
  min-height: 44px; padding: 0 16px; font: inherit; font-size: var(--t-meta); font-weight: 600; color: var(--ink);
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-pill); cursor: pointer;
}
.m-more-h { margin: 20px 4px 8px; }
/* The reading stays Money's H1 for a screen reader; on screen the headline is the card (UX-022). */
.m-quiet {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.m-rrow > .ev-text { flex-wrap: nowrap; align-items: center; gap: 12px; }
.m-rrow .m-tile { border-radius: var(--r-sm); color: var(--ink-2); }
.m-rrow .m-tile .i { width: 16px; height: 16px; }
.m-rrow-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.m-rrow-what { font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.m-rrow-meta { font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2); }
.m-rrow-amt {
  flex: none; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.m-rrow > .ev-text:hover .m-rrow-what, .m-rrow > .ev-text:focus-visible .m-rrow-what { color: var(--d-money); }
.m-change { display: block; font-size: var(--t-micro); color: var(--ink-3); font-weight: 400; }

/* What is deliberately not built yet, with what would unblock it (P6). */
.withheld {
  font-size: var(--t-meta); color: var(--ink-3); margin-top: 18px;
  padding-top: 12px; border-top: 1px solid var(--hairline); text-wrap: pretty;
}
/* Several standing limits are several sentences, never one run-on paragraph of them. */
.withheld p { margin: 0 0 6px; max-width: var(--measure); }
.withheld p:last-child { margin-bottom: 0; }

/* ───────────────────────────────────────── one account — CAP-109, R1 (UX-015)
 *
 * The running column is the page. Everything else on Money restates something you said; a
 * balance is arithmetic over those sentences, so this is the one screen whose job is to be
 * checked against a bank app line by line.
 *
 * No frame draws it, so it is composed from drawn pieces (UX-015): the reached-layer bar below,
 * Money's subline and KPI card (.m-lede, .m-kpi), the uppercase group label, and one Activity
 * card of rows per block (.m-activity, .m-tx). Money's green marks it as Money's page.
 */
#account { --place: var(--d-money); --place-soft: var(--d-money-soft); }
@media (min-width: 861px) { #account { max-width: var(--desk-col); } }
/* The bar is the page's title, as the Wishlist's is (17:10), so the shared date header steps aside. */
body:has(#account:not([hidden])) .head { display: none; }
/* A part of Money is a reached page: its own bar has Back and the title (UX-022). */
body:has(#money[data-open]:not([hidden])) .head { display: none; }
/* The reading under the bar's title: Money's subline, at the body tier, capped like every reading. */
.a-lede { font-family: var(--sans); font-size: var(--t-body); max-width: var(--measure); margin: 0 8px 20px; }
/* One figure, so the KPI card takes the whole row (the frame draws two side by side). */
.a-kpis { grid-template-columns: minmax(0, 1fr); }
.a-kpi .m-kpi-chip { color: var(--d-money); background: var(--d-money-soft); }
/* The label is the server's word ("savings account", "Spendable"), set up as the frame sets labels. */
.a-kpi .m-kpi-label::first-letter { text-transform: uppercase; }
.a-kpi.is-card .m-kpi-chip { color: var(--ink-2); background: var(--m2-hi); }
.a-kpi.is-holding .m-kpi-chip { color: var(--invest); background: var(--invest-soft); }
.a-block { margin: 0 0 24px; }
.a-glabel { padding: 0 8px 12px; }
/* The running figure is a column of arithmetic: ink, tabular, never wrapped. */
.a-running { font-variant-numeric: tabular-nums; white-space: nowrap; }
.a-held-note { border-top: 0; }

/*
 * ── The reached-layer bar (17:10), on the product's palette ───────────────────────────────
 * Back on the left, the title centred, and an end slot that keeps the title centred when there is
 * no action. The Wishlist draws it in stone (.wl-bar); every other reached surface uses this one
 * (UX-015). Measured from the frame: a 36px row, a 16px semibold title, a 36px round Back.
 */
.layer-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 36px; padding: 0 0 16px; }
.layer-title {
  flex: 1; min-width: 0; margin: 0; text-align: center;
  font-size: var(--t-date); font-weight: 600; line-height: 24px; letter-spacing: -0.4px; color: var(--ink);
  overflow-wrap: anywhere;
}
.layer-title::first-letter { text-transform: uppercase; }
.layer-back, .layer-end { flex: none; width: 36px; height: 36px; }
.layer-back {
  display: inline-flex; align-items: center; justify-content: center; margin: 0 0 0 -8px; padding: 0;
  border: 0; border-radius: var(--r-pill); background: none; color: var(--ink-2); cursor: pointer;
}
.layer-end { margin-right: -8px; }
.layer-back .i { width: 20px; height: 20px; }
.layer-back:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ───────────────────────────────────────── Notes — CAP-104 / phase 16, UX-011.1/.5/.7
 *
 * §P: "genuinely useful writing, still no filing". So the page is a column of what you wrote,
 * set at reading width and reading size — no cards, no grid of tiles, no sidebar of folders,
 * and nothing that looks like a place to put something.
 *
 * ── What was wrong, and it was this block claiming the opposite ───────────────────────
 *
 * The rule under `.n-body` said "reading width and reading size", and the header above said
 * the body was "the largest thing here on purpose". It was set at `--t-body` in `--ink-2`:
 * the SMALLEST and DIMMEST text on the page, the same 14px as a list row in Work, on the one
 * surface in the product that exists to be read. Both sentences were false about their own
 * rule, and neither would ever have been caught by a test.
 *
 * So the body takes `--t-prose` in `--ink`, and the note is set in the reading font — which
 * also makes `--measure` resolve in `ch` of the READING face rather than of the UI face,
 * which is what a measure means.
 *
 * ── Your writing is sans, and that is a decision, not an oversight ────────────────────
 *
 * Written under UX-006's two voices, when the system's narration was serif and your writing
 * deliberately was not. UX-013 dropped the serif, so both are the one family now; what stays
 * is that your writing is read at reading size and never styled as the system's reading.
 */
/*
 * Since R3 (UX-015) the reading is the subline under the reached-layer bar's title, at the body
 * tier, as the account's and the entity's are; it still names the family and caps its width.
 */
.n-reading {
  font-family: var(--sans);
  font-size: var(--t-body); line-height: 1.5; color: var(--ink-2);
  max-width: var(--measure); margin: 0 8px 20px; text-wrap: pretty;
  font-variant-numeric: tabular-nums;
}

/*
 * ── The note is prose with a margin (UX-011.1, UX-011.5) ──────────────────────────────
 *
 * Everything about a note used to stack UNDER it — date, connections, files, versions, a
 * pill button — so a 26-word note about a birthday present carried four blocks of furniture
 * and the writing was the quietest thing in its own article. Beside it, on a 1920px screen,
 * sat 1,230px of nothing.
 *
 * So the writing took the column and the facts about it took a margin, on a desktop. Since R3
 * the page is one 420px column and each note is a card (UX-015 supersedes UX-011.1's no
 * container here), so the facts stack under the writing again, in the order the markup gives.
 */
/*
 * PD-030: a note is a page of its own now (UX-016's title, meta line and editor, below), so R3's card
 * per note and R4's title and date lines left with it (`.n-list`, `.n-note`, `.n-title`, `.n-when`).
 * What R4 drew under the writing stays: what the page is about as the Activity row's transfer chip,
 * its files, Attach a file, and its versions as the hairline timeline Life draws for everything you
 * have said (1:319). All of it is neutral (UX-013 §10, UX-015 rule 4).
 */

/*
 * Reading size, primary ink, and a line-height that suits a paragraph rather than a row.
 * `pre-wrap` because your paragraphs are your paragraphs — this file never reflows, joins or
 * interprets a blank line you typed (P10).
 */
.n-body {
  font-size: inherit; line-height: 1.6; color: var(--ink);
  margin: 0; max-width: var(--measure);
  white-space: pre-wrap; word-break: break-word; text-wrap: pretty;
}
.n-about { min-width: 0; }

/*
 * Derived connections: a way IN to something, never a tag you applied. Drawn as the Activity
 * row's chip, so it reads as something about the note rather than a word of it, and each opens
 * that entity's page.
 */
.n-links { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; }
.n-chip {
  padding: 4px 8px; cursor: pointer;
  font: inherit; font-size: var(--t-meta); font-weight: 400; line-height: 1.4; color: var(--ink-2);
  background: var(--m2); border: 1px solid var(--m3-line); border-radius: var(--r-xs);
}
.n-chip:hover { color: var(--ink); border-color: var(--m3-line); }
.n-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Attachments are local evidence under the writing, never documents to arrange. */
.n-files { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; }
.n-file {
  margin: 0; max-width: 100%; overflow: hidden;
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-sm);
}
.n-file img { display: block; width: 100%; height: auto; }
.n-file figcaption { padding: 6px 8px; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-3); }
.n-doc {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 12px; text-decoration: none;
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
}
.n-doc:hover { color: var(--ink); }
.n-doc:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/*
 * One quiet affordance, not a button per note.
 *
 * As a filled pill repeated under all five notes it was the most salient thing on a page of
 * writing — a control that looks like a place to put things, which is the exact shape this
 * surface refuses. It is a meta-sized line, and it still does the one thing it ever did.
 */
.n-attach {
  display: block; margin: 12px 0 0; padding: 2px 0; cursor: pointer; text-align: left;
  font: inherit; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
  background: none; border: 0;
}
.n-attach:hover { color: var(--ink); }
.n-attach[disabled] { opacity: 0.55; cursor: default; }
.n-attach:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/*
 * Version history — the reason this page exists, and deliberately folded away.
 *
 * Closed it is a fact about the note; open it is WRITING - an earlier version of *The flat* is
 * 164 words of your own prose - so it sits under the writing, and an old version is read at the
 * same size and measure as the current one.
 *
 * ── Changing a note is evidence, not an editor (Phase 4C) ─────────────────────────────
 *
 * Capture remains the only way to make another version. The history is a record spine, drawn as
 * Life's timeline of what you said (1:319), not a revision picker or a comparison tool: each dot
 * opens the exact server-authored writing, and the published `current` flag alone gives the
 * present wording the stronger dot. Nothing here orders, compares or writes a version.
 */
.n-versions { margin: 16px 0 0; padding-top: 12px; border-top: 1px solid var(--m2-hi); }
.n-vsummary {
  display: inline-block; padding: 2px 0; list-style: none; cursor: pointer;
  font-size: var(--t-meta); font-weight: 600; line-height: 1.5; color: var(--ink-head);
}
.n-vsummary::-webkit-details-marker { display: none; }
.n-vsummary:hover { color: var(--ink); }
.n-vsummary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.n-vlist { position: relative; list-style: none; margin: 8px 0 0; padding: 0 0 0 4px; }
.n-vlist::before { content: ''; position: absolute; left: 7px; top: 8px; bottom: 8px; width: 1px; background: var(--m3-line); }
#notes .n-version { position: relative; padding: 10px 0 10px 22px; }
#notes .n-version::before {
  content: ''; position: absolute; left: 0; top: 16px; width: 8px; height: 8px;
  border-radius: var(--r-pill); background: var(--ink-faint); box-shadow: 0 0 0 4px var(--m2);
}
/* The server's `current` flag, and nothing inferred here, gives the present wording ink. */
#notes .n-version.is-current::before { background: var(--ink); }
.n-vtext {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0; width: 100%;
  padding: 0; border: 0; background: none; cursor: pointer; text-align: left; font: inherit;
}
.n-vwhen { font-size: var(--t-body); font-weight: 600; line-height: 1.3; color: var(--ink); }
#notes .n-version:not(.is-current) .n-vwhen { font-weight: 500; color: var(--ink-2); }
.n-vsays { margin: 4px 0 0; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-2); }
/* This is your prior writing, not the shared evidence popover's quoted system text. */
#notes .n-versions .ev-said {
  margin: 8px 0 0; padding: 0; font-size: var(--t-prose); line-height: 1.6; color: var(--ink);
  font-style: normal; max-width: var(--measure); white-space: pre-wrap;
}

/* ───────────────────────────────────────── Notes — CAP-104, PD-030, UX-016
 *
 * Organised as Notion organises it (PD-030): a tree of folders and pages beside one open page.
 * No hue of its own since R4: the bar's title says whose page it is. The new components (UX-016)
 * are drawn on the existing tokens and tiers only.
 */
/* The bar is the page's title, as on the account and entity pages, so the date header steps aside. */
body:has(#notes:not([hidden])) .head { display: none; }

/* A phone shows the tree or the open page, never both: the page is a layer over the tree. */
#notes:not([data-open]) .nt-open { display: none; }
#notes[data-open] .nt-side { display: none; }
/*
 * UX-016 6: on the desk, the tree beside the page - the first layout of its own on the desk. The
 * tree keeps the phone column's width; the page takes what is left, capped at a reading measure.
 */
@media (min-width: 861px) {
  #notes { max-width: 1120px; }
  .nt-shell { display: grid; grid-template-columns: 360px minmax(0, 1fr); gap: 0 40px; align-items: start; }
  #notes[data-open] .nt-side, #notes .nt-open { display: block; }
  .nt-open { max-width: 680px; padding-top: 4px; }
  .nt-side { position: sticky; top: 16px; }
  /* Beside the tree, the page's own Back has nothing to go back to. */
  .nt-open .nt-close { visibility: hidden; }
}
.nt-pick-note { margin-top: 56px; }

/* A round 36px button, the reached-layer bar's own (17:10), for the page's Back, "…" and "+". */
.nt-round {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0; border: 0; border-radius: var(--r-pill);
  background: none; color: var(--ink-2); cursor: pointer; font: inherit;
}
.nt-round:first-child { margin-left: -8px; }
.nt-round:last-child { margin-right: -8px; }
.nt-round .i { width: 20px; height: 20px; }
.nt-round:hover { color: var(--ink); }
.nt-round:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.nt-glabel { padding: 0 8px 8px; margin: 16px 0 0; }

/* UX-016 1 · the tree: a row per folder or page inside the Activity card, 20px of indent a level. */
.nt-tree { padding: 8px; margin: 0 0 8px; }
.nt-line {
  position: relative; display: flex; align-items: center; gap: 4px; min-height: 44px;
  padding: 0 4px 0 calc(4px + var(--d, 0) * 20px); border-radius: var(--r-sm);
}
.nt-line + .nt-line { border-top: 1px solid var(--m2-hi); }
.nt-line.is-on { background: var(--m2-hi); }
.nt-caret, .nt-caret-gap { flex: none; width: 24px; height: 24px; }
.nt-caret {
  display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0;
  border-radius: var(--r-sm); background: none; color: var(--ink-3); cursor: pointer;
}
.nt-caret .i { width: 14px; height: 14px; }
.nt-caret:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nt-row, .nt-pick {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 4px;
  border: 0; background: none; cursor: pointer; text-align: left; font: inherit; color: inherit;
}
.nt-row:focus-visible, .nt-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-sm); }
.nt-glyph {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  border-radius: var(--r-sm); background: var(--m2-hi); color: var(--ink-2);
}
.nt-glyph .i { width: 15px; height: 15px; }
.nt-name { flex: 1; min-width: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.3; color: var(--ink); overflow-wrap: anywhere; }
.nt-meta { flex: none; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-3); white-space: nowrap; }
/*
 * Where a drop will land: an accent line in front of or behind the row, starting at the row's
 * own indent, or the row lit to take it inside. The line is drawn over the hairline between
 * rows, so it sits exactly between the two places it means.
 */
.nt-line.is-drop-before::before, .nt-line.is-drop-after::after {
  content: ""; position: absolute; left: calc(4px + var(--d, 0) * 20px); right: 4px; height: 2px;
  border-radius: var(--r-pill); background: var(--accent); pointer-events: none;
}
.nt-line.is-drop-before::before { top: -1px; }
.nt-line.is-drop-after::after { bottom: -1px; }
.nt-line.is-drop-in { background: var(--accent-soft); box-shadow: inset 0 0 0 1.5px var(--accent-ring); }

/* New page, New folder: quiet lines under the tree, glyph and words. */
.nt-new:not(.nt-round) {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 40px; padding: 8px 12px;
  background: none; border: 0; cursor: pointer; text-align: left;
  font: inherit; font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink-2);
}
.nt-new:not(.nt-round) .i { width: 16px; height: 16px; }
.nt-new:not(.nt-round):hover { color: var(--ink); }
.nt-new:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Put away: a fold that says what it holds (UX-013 §9), each with its way back. */
.nt-away { margin: 8px 0 0; }
.nt-away-sum {
  display: inline-block; padding: 8px 12px; list-style: none; cursor: pointer;
  font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink-2);
}
.nt-away-sum::-webkit-details-marker { display: none; }
.nt-away-sum:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nt-bring {
  flex: none; appearance: none; cursor: pointer; margin-left: auto;
  font: inherit; font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 6px 12px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
}
.nt-bring:hover { color: var(--ink); }
.nt-bring:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* UX-016 2 · the breadcrumb: where the page is, each place one tap away. */
.nt-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin: 0 8px 8px; color: var(--ink-3); }
.nt-crumbs .i { width: 12px; height: 12px; }
.nt-crumb {
  padding: 4px 2px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-3);
}
.nt-crumb:hover { color: var(--ink); }
.nt-crumb:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: var(--r-xs); }

/* UX-016 3 · the page title, at the title tier as Money's H1; a tap edits it. */
.nt-title { margin: 0 8px; font-size: var(--t-title); font-weight: 600; line-height: 1.25; letter-spacing: -0.025em; color: var(--ink); }
.nt-edit.nt-body, .nt-title-btn {
  display: block; width: 100%; padding: 0; border: 0; background: none; cursor: text; text-align: left;
  font: inherit; color: inherit; letter-spacing: inherit;
}
.nt-title-btn { overflow-wrap: anywhere; }
.nt-title-btn:focus-visible, .nt-edit.nt-body:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--r-xs); }
.nt-pmeta { margin: 8px 8px 16px; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2); }
/* The writing: the reading size, your own line breaks, never markup (P10). */
.nt-edit.nt-body { margin: 0 8px; width: calc(100% - 16px); font-size: var(--t-prose); line-height: 1.6; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.nt-empty { color: var(--ink-3); }
.nt-open .n-about, .nt-open .n-versions { margin-left: 8px; margin-right: 8px; }

/* UX-016 4 · the editor: the title and the writing on the capture field's material and focus. */
.nt-editor-form { margin: 0 0 16px; }
.nt-editor, .nt-title-input {
  display: block; width: 100%; box-sizing: border-box; font: inherit; color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line); box-shadow: var(--m2-shadow);
  outline: none; transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.nt-title-input { padding: 10px 12px; border-radius: var(--r-lg); font-size: var(--t-date); font-weight: 600; line-height: 1.3; }
.nt-editor {
  margin-top: 8px; min-height: 220px; max-height: 60vh; padding: 12px; resize: vertical; border-radius: var(--r-lg);
  font-size: var(--t-prose); line-height: 1.6;
}
.nt-title-input:focus, .nt-editor:focus { border-color: var(--accent); box-shadow: var(--m2-shadow), 0 0 0 3px var(--accent-soft); }
.nt-title-input::placeholder, .nt-editor::placeholder { color: var(--ink-3); }
.nt-saving { margin: 8px 8px 0; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-3); }
.nt-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; position: sticky; top: 0; z-index: 45; background: var(--m2); padding: 8px 0; }
/* Done is the one primary action on the page, in ink as the frames' primary buttons are; Cancel the pill. */
.nt-done, .nt-move-here {
  appearance: none; cursor: pointer; border: 0; border-radius: var(--r-pill);
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--m2); background: var(--ink);
  padding: 10px 20px;
}
.nt-move-here { display: block; width: 100%; margin: 16px 0 0; padding: 14px; }
.nt-cancel:not(.nt-round) {
  appearance: none; cursor: pointer; font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4;
  color: var(--ink-2); padding: 9px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
}
.nt-done:focus-visible, .nt-move-here:focus-visible, .nt-cancel:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* UX-016 5 · the page sheet: a bottom sheet of the page's actions, on M3 as Talk's sheet. */
.nt-sheet {
  /* Above the tab bar and the capture tray (40-50), below search (70) and evidence (80). */
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; padding: 16px 16px calc(24px + env(safe-area-inset-bottom));
  background: var(--m3); border-top: 1px solid var(--m3-line); border-radius: var(--r-lg) var(--r-lg) 0 0; box-shadow: var(--m3-shadow);
}
@media (min-width: 861px) {
  .nt-sheet { position: static; margin: 16px 0 0; border: 1px solid var(--m3-line); border-radius: var(--r-lg); }
}
.nt-do {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 0 8px;
  border: 0; border-top: 1px solid var(--m2-hi); background: none; cursor: pointer; text-align: left;
  font: inherit; font-size: var(--t-body); font-weight: 600; color: var(--ink);
}
.nt-do .i { width: 18px; height: 18px; color: var(--ink-2); }
.nt-do .nt-meta { margin-left: auto; }
.nt-do:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-sm); }

/* Move to…: the tree with one choice per row. */
.nt-radio { flex: none; width: 18px; height: 18px; box-sizing: border-box; border-radius: 50%; border: 1.5px solid var(--m3-line); }
.nt-pick[aria-pressed="true"] .nt-radio { border: 5px solid var(--ink); }
.nt-line:has(.nt-pick[aria-pressed="true"]) { background: var(--m2-hi); }
.nt-pbar .layer-title { font-size: var(--t-date); }

/* ───────────────────────────────────────── Reminders — CAP-105 / phase 17, R5 (UX-015)
 *
 * §R: reminders and derived attention are VISIBLY different things. Needs You is amber and
 * carries an "if you do nothing" line; a reminder is neither of those — it is a time you
 * chose, so it gets no colour that means anything.
 *
 * Nothing here is styled as a failure. A reminder that has gone off and is waiting is a thing
 * that happened, not a debt, and there is no count to reduce (P4).
 *
 * No frame draws it, so since R5 it is composed from drawn pieces (UX-015): the reached-layer
 * bar, the reading as the subline, the reach sentence at reading size, Money's amber insight
 * card for what could not be set, each list as a group label over one Activity card of rows,
 * Life's "…" for the done tap, and the knows card. Time's cyan marks it as Time's page.
 */
#reminders { --place: var(--d-time); --place-soft: var(--d-time-soft); }
/* R5: the desk hosts the phone column (UX-013 §12), as it does every reached page. */
@media (min-width: 861px) { #reminders { max-width: var(--desk-col); } }
/* The bar is the page's title, as on the account, entity and Notes pages. */
body:has(#reminders:not([hidden])) .head { display: none; }

/* The reading, as the subline under the bar's title: the body tier, capped like every reading. */
.r-reading {
  font-family: var(--sans);
  font-size: var(--t-body); line-height: 1.5; color: var(--ink-2);
  max-width: var(--measure); margin: 0 8px 12px; text-wrap: pretty;
  font-variant-numeric: tabular-nums;
}
/*
 * ── The most important sentence on the page was the smallest print on it ──────────────
 *
 * §R: the reach line is "never conditional, never dismissible, and never in small print".
 * It was `--t-meta` — 12.5px, the smallest body size the system has — inside a filled,
 * bordered, rounded box, above rows set larger than it. Every property of that rule said
 * *skip me*: a box at the top of a page with quieter type than its content is the shape of a
 * cookie banner, and people are very well trained on that shape.
 *
 * No container (UX-011.1), reading size - larger than the subline above it and the rows below
 * it - and it sits in the opening block as the second sentence rather than as a notice.
 */
.r-reach {
  font-size: var(--t-prose); line-height: 1.55; color: var(--ink);
  margin: 0 8px 24px; max-width: var(--measure); text-wrap: pretty;
}

.r-sec { margin: 0 0 24px; }
.r-glabel { padding: 0 8px 12px; }
.r-sec .m-activity { margin: 0; }
.r-empty { margin: 0 0 24px; }

/* The row is its evidence tap and, when it has gone off, its "…" beside it (1:248). */
.r-row { display: flex; flex-wrap: wrap; align-items: flex-start; }
.r-row > .ev-text { flex: 1 1 0; min-width: 0; }
.r-row > .l-more { margin: 12px 8px 0 0; }
.r-row > .l-menu { padding: 0 16px 16px; }
.r-row > .ev-said { flex: 1 1 100%; }
#reminders .m-tx > .ev-text:hover .m-tx-what, #reminders .m-tx > .ev-text:focus-visible .m-tx-what { color: var(--place); }

/*
 * Something you asked for that could not be set: the one thing here that needs you, and the one
 * place on this surface where amber is earned (UX-005, UX-013 §10). Money's insight card on the
 * amber wash (1:3671). It is not a fourth reminder state, and nothing else on the page is amber.
 */
.r-questions { margin: 0 0 24px; }
/* The question's words are the insight card's text (.m-insight-text): ink, the amber is the card and its glyph. */
.r-ask + .r-ask { margin-top: 10px; }
.r-ask > .ev-text {
  display: block; width: 100%; margin: 6px 0 0; padding: 0; text-align: left; cursor: pointer;
  font: inherit; font-size: var(--t-meta); line-height: 1.625; color: var(--ink-body); background: none; border: 0;
}
/* One question per missing thing, one line each — two full sentences in a box is a shape a
 * person skips, and this is the one place on the surface that actually needs an answer. */
.r-part { display: block; text-wrap: pretty; }
.r-part + .r-part { margin-top: 5px; }

/* The arithmetic behind a computed reminder — CAP-112.
 *
 * Folded away, because a reminder you set two months ago does not need explaining every time
 * you look at the list. It needs explaining when you doubt it, and then it needs to be
 * complete: every term, its duration, your own words, and the record you said them in.
 */
/* A full line of the row, never a trailing cell of it — see the renderer for what that cost. */
.r-work { flex: 1 0 100%; margin: 0; padding: 0 16px 16px; }
.r-wsummary {
  display: inline-block; padding: 2px 0; list-style: none; cursor: pointer;
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
}
.r-wsummary::-webkit-details-marker { display: none; }
.r-wsummary:hover { color: var(--ink); }
.r-wsummary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.r-term { margin: 8px 0 0; }
.r-twhat { display: block; font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink); }

/* ───────────────────────────────────────── Settings, six groups — CAP-033 / phase 19
 *
 * §X: "six groups of sentences". So a group is a heading, one line saying what it is for, and
 * then sentences — no card, no panel, no bordered box per group. Space is the divider, as it
 * is everywhere else in this product.
 *
 * A readout is not a disabled control. A withheld thing gets a sentence saying what it would
 * take to exist, because a greyed-out switch says "later" and explains nothing (P6).
 */
/* R6: the desk hosts the phone column (UX-013 §12), as it does every reached page. */
@media (min-width: 861px) { #settings { max-width: var(--desk-col); } }
/* The bar is the page's title, as on every reached page, so the date header steps aside. */
body:has(#settings:not([hidden])) .head { display: none; }

/* Each group: its label, its purpose as the subline, one card. No domain hue - Settings is reached
 * utility, not a sixth place. */
#settings .s-group { margin: 0 0 24px; }
.s-glabel { padding: 0 8px 8px; }
.s-says {
  font-family: var(--sans);
  font-size: var(--t-prose); line-height: 1.55; color: var(--ink-2);
  margin: 0 8px 12px; max-width: var(--measure); text-wrap: pretty;
}
#settings .s-card { margin: 0; }

/* A readout: a label, an answer, and — when it is withheld — what would unblock it. */
#settings .s-read { margin: 0; padding: 16px; }
/* The micro-label, one thing: 11px, wide-tracked, uppercase - the same as .group-label. */
.s-read-label {
  font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-2); margin: 0 0 4px;
}
.s-read-says {
  font-size: var(--t-body); line-height: 1.55; color: var(--ink-2);
  margin: 0; text-wrap: pretty;
}
.s-withheld {
  font-size: var(--t-meta); line-height: 1.5; color: var(--ink-3);
  margin: 6px 0 0; padding-left: 11px;
  border-left: 1px solid var(--hairline-hi);
  text-wrap: pretty;
}
/* Held-back things recede. They are honest, not important. */
.s-held .s-read-says { color: var(--ink-3); }

/* The two product-wide read-backs belong together but are not a seventh settings group. */
/* The two product-wide read-backs belong together but are not a seventh settings group. */
#settings .s-coverage .s-block { margin: 0 0 24px; }

/* ───────────────────────────────────────── one system — phase 20
 *
 * Phase 20 is not a repaint. It is the pass that makes the accepted decisions true, because
 * every one of them had been accepted and then not applied by the surfaces built afterwards.
 */

/*
 * ── The secondary line under a row, and there is exactly one of it now ────────────────
 *
 * There were EIGHT classes doing this job — m-meta (since retired), w-meta, r-meta, n-meta, t-detail, t-fits,
 * e-since, s-note — at four different sizes, because each phase added its own beside the ones
 * it could not see. Eight names for one role is how a product stops being one product.
 *
 * Kept as a group selector rather than renamed across ten client files: these names are
 * load-bearing in `aria-controls` ids and in the trust suite's control guard, so a rename
 * would be churn with no behavioural gain. What matters is that they can no longer differ.
 *
 * `flex: 1 1 100%` is what makes `display: block` mean anything here. A view renders
 * `<span>label</span><span class="w-meta">detail</span>` inside `.ev-text`, which is an
 * inline-flex ROW — so the meta was blockified into a flex item and sat BESIDE its label on
 * every surface in the product. On Needs You, where a row has a label, a reason and an
 * outcome, that produced three columns of squeezed text.
 */
.meta, .w-meta, .r-meta, .n-meta, .t-detail, .t-fits {
  display: block;
  flex: 1 1 100%;
  font-size: var(--t-meta);
  line-height: 1.45;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}

/*
 * ── Needs You, on Today (CAP-053, rendered by CAP-108) ────────────────────────────────
 *
 * A row here has three parts: what it is, why it is here, and what happens if you ignore it.
 * Three lines, not three columns — the outcome is the part that makes this a review surface
 * rather than an inbox, and it has to be readable.
 *
 * The rules that used to do this lived under `.needs-*` selectors CAP-108 stopped rendering,
 * so they were dead while the layout was broken. Rewritten against the live class names.
 */

/*
 * ── The blur budget, enforced (UX-005 rule 2) ─────────────────────────────────────────
 *
 * "Two live blur layers on screen, maximum. A budget, not a guideline." It was written in
 * phase 6 and it had never been true. Counted in a live browser at desk width:
 *
 *     at rest, on Today          rail + capture                        2   ok
 *     at rest, on Time           rail + capture + ribbon               3   over
 *     Talk open                  rail + capture + dock                 3   over
 *     Talk + search open         rail + capture + dock + overlay       4   double
 *
 * The ribbon lost its glass outright (above) — rule 3's arithmetic condemned it and its own
 * design intent wanted the ground legible. The other two states are fixed here, and the
 * mechanism is suppression rather than removal, because in both cases the blur being paid for
 * is a blur nobody can see:
 *
 *   · Under the overlay, every layer is behind a scrim. Its blur composites and is then
 *     covered up. Suppressing it changes the pixels not at all — verified by looking.
 *   · When the dock is open, it owns the input: the conversation has its own field, and the
 *     capture field beside it is the one you are not typing in. The elevated layer takes the
 *     glass; the floating one recedes to its fill. That is UX-005's M2/M3 ordering doing what
 *     it is for, rather than two surfaces competing at the same depth.
 *
 * Both selectors read the `hidden` attribute, which is exactly how app.js opens and closes
 * these two panels — so this cannot drift out of sync with the behaviour it depends on.
 *
 * What holds after this, in every state: 2, 2, 2, 1.
 */
body:has(#overlay:not([hidden])) .rail,
body:has(#overlay:not([hidden])) #capture-form,
body:has(#overlay:not([hidden])) .dock,
body:has(#overlay:not([hidden])) .tabbar,
body:has(#dock:not([hidden])) #capture-form {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/*
 * ── Settings is ONE column ────────────────────────────────────────────────────────────
 *
 * The two read-backs once borrowed Money's `.m-block` (retired at R6) at a 780px width beside
 * groups capped at 62ch, and "You typed it" sat 580px from its figure. Since R6 every group and read-back is one
 * card in a 420px column, so the page has one edge and each figure sits in its row.
 */

/*
 * The settings index is the phone's way in (UX-010). The desk keeps the single scroll: 780px
 * of measure and a pointer make six groups a legitimate page, and the desk is where you go to
 * change several things at once.
 */
@media (min-width: 861px) {
  .s-index { display: none; }
}

/* CAP-115 - a turn that acted. What happened, and what was refused. */
.turn-said.refused { color: var(--ink-2); }
/* The disambiguation list in a refusal (CAP-117), one line under it. */
.turn-said .cands {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; color: var(--ink-2); font-size: var(--t-meta);
}
/* CAP-117 - a refusal you can resolve with a tap: each choice the pill Money draws (1:3418). */
.turn-said .pick {
  display: inline-block; min-height: 36px; padding: 8px 16px; appearance: none; cursor: pointer; text-align: left;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
}
.turn-said .pick:hover { color: var(--ink); }
.turn-said .pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.turn-said .pick:disabled { opacity: 0.5; cursor: default; }

/* ─────────────────────────────────────── Money: the floor as a distance (UX-011.4) */
/*
 * "above the 10,000 you said makes you uncomfortable" is true, and it is prose. Whether
 * 121,250 is comfortably clear of 10,000 or barely clear takes arithmetic to know, and the
 * point of a floor is that you should FEEL where you are against it.
 *
 * This is the one legitimate use of the marker-on-a-bar from the budgeting reference:
 *   a budget bar is a target you FILL      — a number to reach, which P4 refuses
 *   the floor is a line you STATED         — not a goal, not progress, nothing to complete
 *
 * Nothing counts up. The bar shrinks as things get worse, which is the honest direction: it
 * measures headroom, not achievement.
 *
 * The fill is a PROJECTION, so it is drawn as a soft band rather than a solid block and
 * never reads as a measured quantity. The marker is a hard line, because you said it.
 */
.m-floor { margin: 10px 0 2px; }
.m-floor-track {
  position: relative; height: 6px; border-radius: var(--r-xs);
  background: var(--m2); overflow: visible;
}
.m-floor-fill {
  position: absolute; inset: 0 auto 0 0; border-radius: var(--r-xs);
  background: linear-gradient(90deg, var(--place-soft), var(--place));
}
.m-floor-mark {
  position: absolute; top: -4px; bottom: -4px; width: 2px; border-radius: var(--r-xs);
  background: var(--ink-2);
}
/* Below the line you named is exactly "attention was earned" (UX-005 law 5). */
.m-floor-under .m-floor-fill { background: var(--attn-soft, var(--m2-hi)); }
.m-floor-under .m-floor-mark { background: var(--attn, var(--ink)); }

/* ─────────────────────────── Money: where this is going (UX-011.4, Figma 1:1754) */
/*
 * No gridlines and no ticks. The number above is the data and this is its context. The legend
 * is the Figma's two items (B-08), and a third only when a band is drawn.
 *
 * SOLID IS RECORDED, DASHED IS PROJECTED. That is a P8 distinction rather than an ornament -
 * a chart that draws a forecast exactly like a fact states the forecast with the confidence
 * of the fact. `vector-effect` keeps each stroke its drawn width under the non-uniform scale.
 */
.m-trajectory {
  margin: 0 0 24px; padding: 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.m-traj-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.m-traj-title { font-size: var(--t-date); font-weight: 600; line-height: 1.5; letter-spacing: -0.025em; color: var(--ink); margin: 0; }
.m-legend {
  display: flex; gap: 12px; margin: 0; padding: 0; list-style: none;
  font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-2);
}
.m-legend li { display: inline-flex; align-items: center; gap: 6px; }
.m-legend i { display: block; width: 8px; height: 2px; border-radius: var(--r-pill); }
.m-key-was { background: var(--c-recorded); }
.m-key-will { background: var(--ink-faint); border-top: 1px dashed var(--c-projected); }
.m-key-band { height: 6px !important; background: var(--c-projected); opacity: 0.25; }
.m-traj-plot { position: relative; margin-top: 24px; }
.m-traj { display: block; width: 100%; height: 180px; overflow: visible; }
.m-traj path, .m-traj line { vector-effect: non-scaling-stroke; }
.m-traj-was { fill: none; stroke: var(--c-recorded); stroke-width: 3; stroke-linejoin: round; }
.m-traj-will { fill: none; stroke: var(--c-projected); stroke-width: 2; stroke-dasharray: 4 4; stroke-linejoin: round; }
.m-traj-was-area { fill: url(#m-traj-was-fill); stroke: none; }
.m-traj-will-area { fill: url(#m-traj-will-fill); stroke: none; }
.m-stop-was { stop-color: var(--c-recorded); stop-opacity: 0.2; }
.m-stop-will { stop-color: var(--c-projected); stop-opacity: 0.1; }
.m-stop-end { stop-opacity: 0; }
/* The optimistic band: the range you gave, soft, so it never reads as a measured quantity. */
.m-traj .m-traj-band { fill: var(--c-projected); fill-opacity: 0.18; stroke: none; }
/* The line you named, so "does it ever go under" is answered by looking. */
.m-traj-floor { stroke: var(--c-floor); stroke-width: 1; stroke-dasharray: 4 4; }
.m-traj-floor-label {
  position: absolute; left: 4px; transform: translateY(calc(-100% - 3px));
  font-size: var(--t-micro); line-height: 1.2; color: var(--c-floor-ink);
  font-variant-numeric: tabular-nums; pointer-events: none;
}

/*
 * What Raai knows (B-15, UX-013 §11), as the Figma draws it on Time (1:1370): every disclosure
 * line a screen has, in one card. Named for no one screen because every screen gets one.
 */
.knows {
  margin: 24px 0 0; padding: 16px;
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
}
.knows-h {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-size: var(--t-meta); font-weight: 600; line-height: 1.5; color: var(--ink-head);
}
.knows-h .i { width: 14px; height: 14px; }
.knows-line { font-size: var(--t-meta); font-weight: 500; line-height: 1.625; color: var(--ink-2); margin: 6px 0 0; text-wrap: pretty; }

/* ─────────────────────────────── Money: lenses (UX-011.2, §8) */
/*
 * Nine equal bands were the flat page one tier up. Overview stays always visible — it is what
 * a person opens Money for, and putting it behind a tab would make the most important thing a
 * click away. Everything else becomes a lens.
 *
 * Pills, as the Figma draws them (1:1804, M2): white with a faint rim, and the current lens
 * filled in ink (UX-013 §2 - active is ink, never a hue). This replaces the quiet underline
 * strip, which was a choice made in a comment rather than a decision. The focus ring stays
 * `--accent`, so a focused pill and the current one never look alike.
 */
.m-lens {
  flex: 0 0 auto; appearance: none; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 8px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.m-lens:hover { color: var(--ink); }
.m-lens[aria-current="true"] {
  color: var(--m2); background: var(--ink); border-color: var(--ink); box-shadow: var(--m2-shadow);
}
.m-lens:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The first band inside a lens sits under the pills, not 56px below them. */
.m-part > .band:first-of-type { margin-top: 8px; }

/* ─────────────────────────────── Life, as the Figma draws it — CAP-076 / L1 (1:9) */
/*
 * One column of the frame's parts on the warm ground Today shares: the H1 and inventory, the
 * active rows, the card grid, the doors, the small-things list, the timeline of what you said,
 * the went-quiet row and the knows card. The desk hosts the frame's 420 column until desktop
 * frames exist (UX-013 §12), so UX-011.5's about/said columns are gone.
 *
 * Sizes between tiers take the nearer one, and ties go up (UX-013 §6): the frame's 14 sets at
 * 15, its 12 at 13; the 11 of a kind label and a meta line is the micro tier.
 */
#life { --place: var(--d-life); --place-soft: var(--d-life-soft); }
@media (min-width: 861px) { #life { max-width: var(--desk-col); } }
@media (max-width: 860px) { #life { padding: 0 4px; } }
body:has(#life:not([hidden])) {
  --ground: var(--today-ground);
  background: var(--today-ground);
}
/* Life draws its own H1 (1:12); the shared date header steps aside, as on Today and Money. */
body:has(#life:not([hidden])) .head h1, body:has(#life:not([hidden])) .head-sub { display: none; }
body:has(#life:not([hidden])) .head { margin-bottom: 0; }

.l-head { margin: 0 0 20px; }
.l-h1 {
  margin: 0; font-size: var(--t-title); font-weight: 600; line-height: 1;
  letter-spacing: -0.025em; color: var(--ink);
}
.l-note { margin: 8px 0 0; font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2); }

/* A kind's colours, one set per kind. Unknown has none of its own (PD-023). */
.l-k-person { --kind: var(--ent-person); --kind-soft: var(--ent-person-soft); --kind-line: var(--ent-person-line); --kind-wash: var(--ent-person-wash); }
.l-k-thing { --kind: var(--ent-thing); --kind-soft: var(--ent-thing-soft); --kind-line: var(--ent-thing-line); --kind-wash: var(--ent-thing-wash); }
.l-k-place { --kind: var(--ent-place); --kind-soft: var(--ent-place-soft); --kind-line: var(--ent-place-line); --kind-wash: var(--ent-place-wash); }
.l-k-project { --kind: var(--ent-project); --kind-soft: var(--ent-project-soft); --kind-line: var(--ent-project-line); --kind-wash: var(--ent-project-wash); }
.l-k-none { --kind: var(--ink-3); --kind-soft: var(--m2-hi); --kind-line: var(--m2-line); --kind-wash: var(--m2-hi); }

/* Active in your world (1:41). */
.l-active { display: flex; flex-direction: column; gap: 8px; }
.l-arow {
  display: flex; flex-wrap: wrap; align-items: center; column-gap: 12px; padding: 10px 12px;
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-sm);
}
.l-atile { display: inline-flex; padding: 6px; border-radius: var(--r-sm); background: var(--kind-wash); color: var(--kind); }
.l-atile .i { width: 14px; height: 14px; }
.l-atext {
  flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 6px;
  padding: 0; border: 0; background: none; text-align: left; cursor: pointer; font: inherit;
  font-size: var(--t-meta); line-height: 1.5;
}
.l-aname { font-weight: 600; color: var(--ink); }
/* The frame draws the dot in the faint ink; that ink is for glyphs only, so text takes ink-3. */
.l-sep { color: var(--ink-3); }
.l-aphrase { font-weight: 500; color: var(--ink-body); }
.l-arow .ev-said { flex: 1 1 100%; margin: 6px 0 0; }

/* A loose thought (1:247, as a kit row since plan 4): "…" for its two actions. */
.l-srow { align-items: center; }
.l-more {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--r-xs); background: none;
  color: var(--ink-2); cursor: pointer;
}
.l-more .i { width: 16px; height: 16px; }
.l-more[aria-expanded="true"] { background: var(--m2-hi); color: var(--ink-2); }
.l-menu { flex: 1 1 100%; display: flex; gap: 8px; padding: 10px 0 0; }
.l-menu .act {
  width: auto; height: auto; padding: 6px 12px; border-radius: var(--r-pill);
  font: inherit; font-size: var(--t-meta); font-weight: 500; color: var(--ink-body);
  background: var(--m2-hi); border: 1px solid var(--m2-line);
}

/* Everything you have said (1:319): a hairline timeline of your own words. */
.l-feed { list-style: none; margin: 16px 0 0; padding: 0 0 0 4px; position: relative; }
.l-feed::before { content: ''; position: absolute; left: 7px; top: 8px; bottom: 8px; width: 1px; background: var(--m3-line); }
.l-fitem { position: relative; padding: 10px 0 10px 22px; }
.l-fitem::before {
  content: ''; position: absolute; left: 0; top: 16px; width: 8px; height: 8px;
  border-radius: var(--r-pill); background: var(--ink-faint); box-shadow: 0 0 0 4px var(--ground);
}
.l-fquote { margin: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.3; color: var(--ink); overflow-wrap: anywhere; }
/* The frame quotes your words; the marks are drawn here, the words are exactly yours. */
.l-fquote::before { content: '“'; }
.l-fquote::after { content: '”'; }
.l-fmeta { margin: 4px 0 0; font-size: var(--t-micro); font-weight: 500; line-height: 1.5; color: var(--ink-2); }
.l-find {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  margin: 12px 0 0; padding: 12px; cursor: pointer; font: inherit; text-align: left;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-sm); 
  font-size: var(--t-meta); font-weight: 600; color: var(--ink-head);
}

/* ───────────────────────────────────────── All people & things — P-19a (frame 22:185)
 *
 * A reached layer on Life's own ground (the frame's #fdfbf9 is Life's). Under the bar a centred
 * count; then one group per kind, 32px apart: a heading of its tile, its name and how many, and
 * 12px below it one card of rows - a name and one line. Sizes take the scale's nearer tier, ties
 * up (UX-013 §6): the frame's 14px heading sets at 15. Kind colours are UX-014 §1's, not the
 * frame's rose, amber and indigo: amber is reserved for uncertainty (UX-013 §10).
 */
/* Life's three destinations share Life's column, ground and bar (P-19). */
@media (min-width: 861px) { #world, #said, #quiet { max-width: var(--desk-col); } }
@media (max-width: 860px) { #world, #said, #quiet { padding: 0 4px; } }
body:has(#world:not([hidden])), body:has(#said:not([hidden])), body:has(#quiet:not([hidden])) {
  --ground: var(--today-ground);
  background: var(--today-ground);
}
body:has(#world:not([hidden])) .head, body:has(#said:not([hidden])) .head,
body:has(#quiet:not([hidden])) .head { display: none; }
.lw-sub {
  margin: 8px 0 16px; text-align: center;
  font-size: var(--t-meta); font-weight: 500; line-height: 1.5; color: var(--ink-2);
}
.lw-sec { margin: 0 0 32px; }
.lw-h {
  display: flex; align-items: center; gap: 8px; margin: 0 0 12px; padding: 0 4px;
  font-size: var(--t-date); font-weight: 600; line-height: 1.5; letter-spacing: -0.025em; color: var(--ink);
}
.lw-tile { display: inline-flex; padding: 6px; border-radius: var(--r-sm); background: var(--kind-wash); color: var(--kind); }
.lw-tile .i { width: 16px; height: 16px; }
.lw-n { padding-left: 4px; font-weight: 500; color: var(--ink-3); }
.lw-card {
  overflow: hidden; background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
#surface .lw-row {
  display: flex; flex-direction: column; align-items: flex-start; width: 100%;
  margin: 0; padding: 16px; border: 0; border-bottom: 1px solid var(--m2-hi); border-radius: 0;
  background: none; cursor: pointer; font: inherit; text-align: left;
}
#surface .lw-row:last-child { border-bottom: 0; }
.lw-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.lw-name { font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.lw-line { padding-top: 2px; font-size: var(--t-meta); font-weight: 400; line-height: 1.5; color: var(--ink-2); overflow-wrap: anywhere; }

/* ───────────────────────────────────────── Everything you said — P-19b (frame 22:1029)
 *
 * One card per line, 16px apart: your words quoted at the date tier (the frame's 16px medium),
 * then a hairline and a row of when - the history glyph and the time - and what it became as a
 * chip. The frame's 12px meta sets at 13 (UX-013 §6, ties up).
 */
.ls-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.ls-card {
  display: flex; flex-direction: column; gap: 12px; padding: 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.ls-quote {
  margin: 0; font-size: var(--t-date); font-weight: 500; line-height: 1.375; color: var(--ink);
  overflow-wrap: anywhere;
}
/* The frame quotes your words; the marks are drawn here, the words are exactly yours. */
.ls-quote::before { content: '“'; }
.ls-quote::after { content: '”'; }
.ls-meta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px;
  margin: 4px 0 0; padding: 12px 0 0; border-top: 1px solid var(--m2-hi);
}
.ls-when { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-3); }
.ls-when .i { width: 14px; height: 14px; }
.ls-became {
  padding: 4px 8px; border-radius: var(--r-xs); background: var(--m2-hi);
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
}
.ls-became::first-letter { text-transform: uppercase; }
#surface .ls-more {
  display: flex; align-items: center; justify-content: center; width: 100%;
  margin: 16px 0 0; padding: 10px; cursor: pointer; font: inherit;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-sm); 
  font-size: var(--t-meta); font-weight: 600; line-height: 1.5; color: var(--ink-body);
}
.ls-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#said .knows { margin-top: 24px; }

/* ───────────────────────────────────────── Went quiet — P-19c (frame 22:1271)
 *
 * The rule in a soft callout with the moon (a 12px radius, the frame's half-strength slate wash
 * and line), then 24px below it one card per thing, 16px apart: your words, when you last
 * mentioned it, and two equal buttons - Keep this in ink, Done on the soft wash.
 */
.lq-note {
  display: flex; align-items: flex-start; gap: 12px; margin: 8px 0 0; padding: 16px;
  background: color-mix(in srgb, var(--m2-line) 50%, transparent);
  border: 1px solid color-mix(in srgb, var(--pill-line) 83%, transparent); border-radius: var(--r-sm);
  font-size: var(--t-meta); font-weight: 400; line-height: 1.625; color: var(--ink-body);
}
.lq-note .i { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--ink-3); }
.lq-list { list-style: none; margin: 24px 0 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.lq-card {
  display: flex; flex-direction: column; gap: 16px; padding: 20px;
  background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.lq-text { margin: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.lq-said { margin: 0; padding-top: 4px; font-size: var(--t-meta); font-weight: 400; line-height: 1.5; color: var(--ink-3); }
.lq-acts { display: flex; gap: 8px; }
#surface .lq-acts .act {
  flex: 1 1 0; width: auto; height: auto; min-height: 40px; margin: 0; padding: 10px;
  border: 0; border-radius: var(--r-sm); cursor: pointer;
  font: inherit; font-size: var(--t-meta); font-weight: 600; line-height: 1.5;
}
#surface .lq-acts .lq-keep { background: var(--ink); color: var(--m2); }
#surface .lq-acts .lq-done { background: var(--m2-line); color: var(--ink-body); }
.lq-acts .act:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.l-find:focus-visible, .l-more:focus-visible, .l-atext:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ───────────────────────────────────────── one entity — CAP-101, R2 (UX-015)
 *
 * A person or a thing is a READING page - a paragraph about them, then sentences you said.
 *
 * No frame draws it, so it is composed from drawn pieces (UX-015): the reached-layer bar with the
 * name as its title (.layer-bar), the top of Life's card - the kind's glyph in its kind colour,
 * the kind and since when (.l-ctile, 1:98) - the paragraph as a subline, each section with lines
 * as an uppercase group label over one Activity card (.m-activity, .m-tx), the "…" Life draws for
 * a row's actions (.l-more, .l-menu), the capture pill for the one field (#capture-form, D0c) and
 * the "What Raai knows" card. The kind's colour (UX-014 §1) marks it as that entity's page; an
 * entity whose kind is not known takes none (.l-k-none).
 */
@media (min-width: 861px) { #entity { max-width: var(--desk-col); } }
/* The bar is the page's title, as on the account page, so the shared date header steps aside. */
body:has(#entity:not([hidden])) .head { display: none; }
/*
 * ── Rebuilt to the owner's frames, 27 September (22:1782 a person, 22:2057 a project) ──────
 *
 * On Life's ground, like the other Life layers. Under the bar: a 72px round tile with the kind's
 * glyph (the frame's photo placeholder - nothing here keeps a photo), the name at the title tier
 * and since when; the paragraph at the prose tier in the heading ink; then each section, 32px
 * apart, titled over a card of rows (radius 16, the row shadow). A row is its title, a meta line
 * with the Evidence tap, and its one action on the right. Sizes take the nearer tier, ties up
 * (UX-013 §6): the frame's 14px "since" sets at 15, its 12px meta and buttons at 13.
 */
body:has(#entity:not([hidden])) { --ground: var(--today-ground); background: var(--today-ground); }
.e-hero { display: flex; align-items: center; gap: 16px; margin: 8px 0 16px; min-width: 0; }
.e-avatar {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 72px; height: 72px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--pill-line) 83%, transparent);
  border: 1px solid var(--m2); box-shadow: var(--m2-shadow);
}
/* The kind's glyph in its kind colour, as on the Life card that opened the page (UX-014 §1). */
#entity .e-avatar { color: var(--kind); }
.e-avatar .i { width: 28px; height: 28px; }
.e-hid { min-width: 0; }
.e-name {
  margin: 0 0 4px; font-size: var(--t-title); font-weight: 600; line-height: 1; letter-spacing: -0.025em;
  color: var(--ink); overflow-wrap: anywhere;
}
.e-since { margin: 0; font-size: var(--t-body); font-weight: 500; line-height: 1.4; color: var(--ink-2); }
.e-para {
  margin: 0 0 24px; max-width: var(--measure); font-family: var(--sans);
  font-size: var(--t-prose); font-weight: 500; line-height: 1.625; color: var(--ink-head); text-wrap: pretty;
}
.e-block { margin: 0 0 32px; }
.e-h2 {
  margin: 0 0 8px; padding: 0 0 0 4px;
  font-size: var(--t-date); font-weight: 600; line-height: 1.5; letter-spacing: -0.025em; color: var(--ink);
}
.e-card { background: var(--m2); border: 1px solid var(--m2-line); border-radius: var(--r-lg); box-shadow: var(--m2-shadow); }
.e-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px; padding: 14px;
  border-bottom: 1px solid var(--m2-hi);
}
.e-row:last-child { border-bottom: 0; }
.e-rtext { flex: 1 1 0; min-width: 0; }
.e-what { margin: 0; font-size: var(--t-body); font-weight: 500; line-height: 1.375; color: var(--ink); overflow-wrap: anywhere; }
.e-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; margin: 0; padding-top: 4px;
  font-size: var(--t-meta); font-weight: 500; line-height: 1.4; color: var(--ink-2);
}
.e-dot { color: var(--ink-3); }
#surface .e-ev {
  display: inline-flex; align-items: center; gap: 4px; width: auto; min-height: 0; margin: 0; padding: 0;
  border: 0; background: none; cursor: pointer; font: inherit;
  /* A quiet link in the meta line, in ink: it was an uppercase blue "EVIDENCE", internal vocabulary
     in the one hue reserved for focus (UX-013 §2; review, 30 September). */
  font-size: var(--t-meta); font-weight: 500; line-height: 1.5;
  color: var(--ink-2); text-decoration: underline; text-decoration-color: var(--hairline); text-underline-offset: 3px;
}
#surface .e-ev .i { width: 10px; height: 10px; }
.e-ev:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#surface .e-row > .e-act {
  flex: none; display: inline-flex; align-items: center; gap: 6px; width: auto; height: auto; margin: 0;
  padding: 6px 12px; border-radius: var(--r-sm); cursor: pointer; font: inherit;
  background: var(--m2); border: 1px solid var(--m2-line);
  font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink-head);
}
#surface .e-row > .e-act .i { width: 14px; height: 14px; }
#surface .e-row > .e-act.is-reopen { background: var(--m2-line); border-color: transparent; color: var(--ink-2); }
.e-row > .ev-said { flex: 1 1 100%; }
/* A settled or closed line stays, dimmed and struck through, and keeps its way back (CAP-101, P7). */
.e-row.is-settled .e-rtext { opacity: 0.6; }
.e-row.is-settled .e-what { text-decoration: line-through; text-decoration-thickness: 1px; }
/* Every sentence that names them: Life's timeline (1:319), at the frame's lighter weight. */
.e-feed { margin: 4px 0 0 4px; }
#entity .e-feed .l-fquote { font-weight: 500; }
#entity .e-feed .l-fmeta { font-size: var(--t-meta); color: var(--ink-3); }
/*
 * One field, and it is not a form (UX-009). It writes an ordinary record that happens to
 * mention them - there is no phone field, no role, no tag, and none of those is a gap. It is
 * drawn as the capture pill (D0c), because it is capture.
 */
.e-say {
  margin: 0; background: var(--field); border: 1px solid var(--field-line);
  box-shadow: var(--m2-shadow); border-radius: var(--r-lg);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.e-say:focus-within { border-color: var(--accent); box-shadow: var(--m2-shadow), 0 0 0 3px var(--accent-soft); }
.e-field {
  display: block; width: 100%; min-height: 48px; padding: 13.5px 12px;
  font: inherit; font-size: var(--t-body); line-height: 1.375; color: var(--ink);
  background: none; border: 0; outline: none;
}
.e-field::placeholder { color: var(--ink-3); }

/* ─────────────────────────────── Wishlist layers (PD-021; 17:10, 18:388, 18:264) */
/*
 * A reached screen with its own bar and Back in place of the header date, on the stone ground
 * the owner chose (audit §9.4 Q4). The frames draw these layers full-screen; the capture row,
 * the tab bar it stands on and the coverage line stay anyway, as on every reached surface -
 * capture is a field at the head of every surface (UX-008) and the coverage line is the one
 * thing P8 requires on every screen. On the desk the rail stays too.
 *
 * Sizes the scale has no tier for take the nearest one (system.spec caps it at eight): the
 * card name's 17 and the section heading's 18 set at 16, the add heading's 32 and the want's
 * 40 price at the 28 title tier. Uppercase labels are the micro tier, as everywhere.
 */
/* The ground token itself, so every surface that paints the ground paints stone here. */
body:has(#wishlist:not([hidden])), body:has(#want:not([hidden])), body:has(#wishadd:not([hidden])) {
  --ground: var(--w-ground);
  --ground-2: var(--w-ground);
  /*
   * And the shell with it (owner ruling, 24 September): the capture row and the tab bar took
   * the product's slate and navy over the stone ground, a visible seam in dark. While a Wishlist
   * layer is open they read stone tokens; the layer's own cards use --w-* and are unaffected.
   */
  --tray: var(--w-tray);
  --field: var(--w-field);
  --field-line: var(--w-field-line);
  --m2-line: var(--w-sheet-line);
  background: var(--w-ground);
}
body:has(#wishlist:not([hidden])) .head, body:has(#want:not([hidden])) .head, body:has(#wishadd:not([hidden])) .head {
  display: none;
}
#wishlist, #want, #wishadd { color: var(--w-ink); max-width: var(--desk-col); }
.wl-nav .i, .wl-go .i, .wl-new-mark .i { width: 20px; height: 20px; }
/* The frame capitalises a want's name; the words stay yours, only the first letter is set up. */
.wl-name::first-letter, .wl-h1::first-letter, .m-wl-name::first-letter { text-transform: uppercase; }

.wl-bar { display: flex; align-items: center; justify-content: space-between; min-height: 36px; padding: 0 0 16px; }
.wl-bar-rule { padding: 0 0 16px; margin: 0 -16px; padding-inline: 16px; border-bottom: 1px solid var(--w-sheet-line); }
.wl-title { margin: 0; font-size: var(--t-date); font-weight: 600; line-height: 24px; letter-spacing: -0.4px; color: var(--w-ink); }
.wl-title-start { flex: 1; }
.wl-nav {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 36px; height: 36px; margin: 0 -8px; padding: 0; border: 0; border-radius: var(--r-pill);
  background: none; color: var(--w-ink-3); cursor: pointer;
}
.wl-plus { width: 34px; height: 34px; margin: 0; background: var(--w-soft); color: var(--w-ink); }
.wl-plus .i { width: 18px; height: 18px; }
.wl-nav:focus-visible, .wl-card:focus-visible, .wl-new:focus-visible, .wl-remove:focus-visible, .wl-go:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.wl-page { display: flex; flex-direction: column; gap: 16px; padding-top: 8px; }
.wl-label {
  margin: 0; font-size: var(--t-meta); font-weight: 700; line-height: 19.5px; letter-spacing: 0.65px;
  text-transform: uppercase; color: var(--w-ink-3);
}
.wl-count { padding: 8px; }
.wl-empty { margin: 8px 0 0; font-size: var(--t-body); line-height: 1.6; color: var(--w-ink-2); text-wrap: pretty; }
.wl-cards { display: flex; flex-direction: column; gap: 16px; }

/* A want's card (17:22): the tile, then its name and price, what you said about it, its pill. */
.wl-card {
  display: flex; align-items: flex-start; gap: 16px; width: 100%; padding: 16px; text-align: left;
  background: var(--w-card); border: 1px solid var(--w-card-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow); color: inherit; font: inherit; cursor: pointer;
}
.wl-tile {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 80px; height: 80px; border-radius: var(--r-lg);
  border: 1px solid rgba(255, 255, 255, 0.5); box-shadow: var(--m2-shadow);
  background: linear-gradient(135deg, var(--wa), var(--wb)); color: var(--wm);
}
/* The frame draws the tile glyph finer than the Lucide weight: 1.75 at 28px is 1.5 on the grid. */
#wishlist .wl-tile .i { width: 28px; height: 28px; stroke-width: 1.5; }
.is-laptop { --wa: var(--w-laptop-a); --wb: var(--w-laptop-b); --wm: var(--w-laptop); }
.is-headphones { --wa: var(--w-headphones-a); --wb: var(--w-headphones-b); --wm: var(--w-headphones); }
.is-armchair { --wa: var(--w-armchair-a); --wb: var(--w-armchair-b); --wm: var(--w-armchair); }
.is-camera, .is-package { --wa: var(--w-camera-a); --wb: var(--w-camera-b); --wm: var(--w-camera); }
.is-plane { --wa: var(--w-plane-a); --wb: var(--w-plane-b); --wm: var(--w-plane); }

.wl-body { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 80px; justify-content: center; padding: 4px 0; }
.wl-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; padding-bottom: 4px; }
.wl-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--t-prose); font-weight: 600; line-height: 21.25px; letter-spacing: -0.425px; color: var(--w-ink);
}
.wl-fig { display: flex; flex-direction: column; align-items: flex-end; flex: none; }
.wl-price { font-size: var(--t-prose); font-weight: 700; line-height: 16px; color: var(--w-ink); font-variant-numeric: tabular-nums; }
.wl-noprice { font-size: var(--t-body); font-weight: 500; font-style: italic; line-height: 22.5px; color: var(--w-ink-3); }
.wl-was { display: inline-flex; align-items: center; gap: 2px; padding-top: 4px; font-size: var(--t-micro); font-weight: 500; line-height: 11px; color: var(--w-ink-2); font-variant-numeric: tabular-nums; }
.wl-was.is-down { color: var(--w-down); }
#wishlist .wl-was .i { width: 10px; height: 10px; }
.wl-sub { padding-bottom: 8px; font-size: var(--t-meta); line-height: 19.5px; color: var(--w-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-top + .wl-pill { margin-top: 4px; }

/* The pill (17:49): one fact, in the tone the server set - amber, green, or plain stone. */
.wl-pill {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; padding: 4px 8px; border-radius: var(--r-sm);
  white-space: nowrap; max-width: 100%;
  font-size: var(--t-micro); font-weight: 700; line-height: 16.5px; letter-spacing: 0.55px; text-transform: uppercase;
}
#wishlist .wl-pill .i { width: 12px; height: 12px; }
.wl-pill.is-attention { background: var(--attn-soft); color: var(--attn); }
.wl-pill.is-fine { background: var(--in-soft); color: var(--in-deep); }
.wl-pill.is-neutral { background: var(--w-soft-2); color: var(--w-ink-body); }

/* "Track something new" (17:172): a dashed, washed row with a white plus. */
.wl-new {
  display: flex; align-items: center; gap: 12px; width: 100%; margin-top: 16px; padding: 20px;
  background: linear-gradient(90deg, var(--w-soft), var(--w-soft-2));
  border: 1px dashed var(--w-rim); border-radius: var(--r-lg);
  font: inherit; font-size: var(--t-prose); font-weight: 500; line-height: 24px; color: var(--w-ink-body); cursor: pointer;
}
.wl-new-mark {
  display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: var(--r-pill);
  background: var(--w-card); box-shadow: var(--m2-shadow); color: var(--w-ink-3);
}

/* What you took off: dimmed, with the way back (P7). Not in the frame; shown only when there is one. */
.wl-removed { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.wl-removed .wl-label { padding: 0 8px; }
.wl-gone { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border-radius: var(--r-lg); background: var(--w-soft-2); }
.wl-gone-text { display: flex; flex-direction: column; min-width: 0; }
.wl-gone-name { font-size: var(--t-body); color: var(--w-ink-2); text-decoration: line-through; text-decoration-color: var(--w-ink-3); }
.wl-gone-meta { font-size: var(--t-meta); color: var(--w-ink-3); }
.wl-back-in {
  flex: none; min-height: 36px; padding: 0 12px; border: 1px solid var(--w-rim); border-radius: var(--r-pill);
  background: var(--w-card); color: var(--w-ink-body); font: inherit; font-size: var(--t-meta); font-weight: 600; cursor: pointer;
}
.wl-knows { margin-top: 8px; background: var(--w-soft-2); border-color: var(--w-sheet-line); }
.wl-knows .knows-h { color: var(--w-ink-deep); }
.wl-knows .knows-line { color: var(--w-ink-2); }

/* ── One want (18:388): the washed hero, then two sheets and Remove. */
.wl-hero {
  position: relative; display: flex; align-items: center; justify-content: center; height: 280px; margin: 0 -16px;
  background: linear-gradient(146deg, var(--wa), var(--wb)); border-bottom: 1px solid rgba(231, 229, 228, 0.5); color: var(--wm);
}
#want .wl-hero-mark .i { width: 80px; height: 80px; stroke-width: 1; }
.wl-float {
  position: absolute; top: 16px; left: 16px; width: 40px; height: 40px; margin: 0;
  background: var(--w-float); box-shadow: var(--m2-shadow); color: var(--w-ink-deep);
}
.wl-detail { padding-top: 16px; }
.wl-sheet {
  padding: 24px; background: var(--w-card); border: 1px solid var(--w-sheet-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
}
.wl-h1 { margin: 0; font-size: var(--t-title); font-weight: 600; line-height: 35px; letter-spacing: -0.7px; color: var(--w-ink); }
.wl-h1-sub { margin: 4px 0 0; font-size: var(--t-prose); line-height: 24px; color: var(--w-ink-2); }
.wl-pricebox {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-top: 24px; padding: 16px 0;
  border-top: 1px solid var(--w-soft-2); border-bottom: 1px solid var(--w-soft-2);
}
/* The price box's label is the frame's 12px caps: the micro tier, as every uppercase label below 13. */
.wl-pb-main .wl-label { font-size: var(--t-micro); line-height: 18px; letter-spacing: 0.6px; }
.wl-trend .wl-label { line-height: 21px; letter-spacing: 0.7px; }
.wl-pb-fig { margin: 4px 0 0; font-size: var(--t-title); font-weight: 600; line-height: 40px; letter-spacing: -1px; color: var(--w-ink); font-variant-numeric: tabular-nums; }
.wl-pb-fig.is-none { font-style: italic; font-weight: 500; color: var(--w-ink-3); }
.wl-pb-was { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; padding-bottom: 4px; }
.wl-pb-dir {
  display: inline-flex; align-items: center; gap: 4px; margin: 0;
  font-size: var(--t-micro); font-weight: 700; line-height: 18px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--w-ink-2);
}
.wl-pb-was.is-down .wl-pb-dir { color: var(--w-down); }
#want .wl-pb-dir .i { width: 12px; height: 12px; }
.wl-pb-old { margin: 0; font-size: var(--t-date); font-weight: 500; line-height: 27px; color: var(--w-ink-3); font-variant-numeric: tabular-nums; }
.wl-dates {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 24px 0 0; padding: 12px 16px;
  background: var(--w-soft-2); border-radius: var(--r-lg);
  font-size: var(--t-meta); font-weight: 500; line-height: 19.5px; color: var(--w-ink-2);
}
.wl-dates span { display: inline-flex; align-items: center; gap: 8px; }
#want .wl-dates .i { width: 16px; height: 16px; }
.wl-h2 { margin: 0; font-size: var(--t-date); font-weight: 600; line-height: 1.5; letter-spacing: -0.025em; color: var(--w-ink); }

/* The callout (18:459), in the pill's tone. Amber is the frame's; green and stone are authored to match. */
.wl-callout { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; padding: 24px; border-radius: var(--r-lg); border: 1px solid var(--w-sheet-line); background: var(--w-soft-2); }
.wl-callout.is-attention { background: var(--w-attn-wash); border-color: var(--w-attn-edge); }
.wl-callout.is-fine { background: var(--in-wash); border-color: var(--in-edge); }
.wl-co-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: var(--t-prose); font-weight: 600; line-height: 24px; color: var(--w-ink); }
.wl-co-mark { display: inline-flex; padding: 6px; border-radius: var(--r-pill); background: var(--w-soft); color: var(--w-ink-2); }
#want .wl-co-mark .i { width: 16px; height: 16px; }
.wl-co-body { margin: 0; font-size: var(--t-body); line-height: 24.375px; color: var(--w-ink-body); text-wrap: pretty; }
.wl-co-body .wl-em { font-weight: 600; }
.is-attention .wl-co-title { color: var(--w-attn-title); }
.is-attention .wl-co-mark { background: var(--attn-line); color: var(--attn-mark); }
.is-attention .wl-co-body { color: var(--w-attn-body); }
.is-fine .wl-co-title { color: var(--in-ink); }
.is-fine .wl-co-mark { background: var(--in-soft); color: var(--in-deep); }
.is-fine .wl-co-body { color: var(--in-ink); }

/* Prices you said (18:471): your own figures as a line, a wash under it, and the sentence. */
.wl-trend { padding: 24px 0 8px; }
.wl-chart { display: block; width: 100%; height: 180px; margin-top: 24px; overflow: visible; color: var(--ink); }
.wl-area { stroke: none; }
.wl-line { fill: none; stroke: currentColor; stroke-width: 3; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.wl-trend-label { margin: 8px 0 0; font-size: var(--t-meta); line-height: 1.5; color: var(--w-ink-2); text-wrap: pretty; }

.wl-remove {
  width: 100%; min-height: 55px; margin-top: 16px; padding: 16px; border: 0; border-radius: var(--r-lg);
  background: var(--w-soft); color: var(--w-ink-body); font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 22.5px; cursor: pointer;
}

/*
 * ── The price check (PD-028) ──────────────────────────────────────────────────────────────
 * The frame's external-link button (18:407) mirrors Back on the right, and its site chip (18:395)
 * sits centred at the foot of the hero. Both are links to the page you pasted. The frame blurs the
 * chip behind it; like the floating Back, it takes no blur here - the blur budget is two layers
 * (UX-005). What a check read sits under the price you said, never in its place; the frame
 * draws no slot for it, so it takes the sheet's own quiet type, and its buttons are the Remove
 * button's stone, smaller.
 */
.wl-float.wl-out { left: auto; right: 16px; }
#want .wl-out .i { width: 18px; height: 18px; }
.wl-site {
  position: absolute; left: 50%; bottom: 37px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 16px; box-sizing: border-box;
  border: 1px solid rgba(255, 255, 255, 0.5); border-radius: var(--r-pill);
  background: var(--w-chip); box-shadow: var(--m3-shadow);
  font-size: var(--t-micro); font-weight: 700; line-height: 18px; letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--w-ink-body); text-decoration: none; white-space: nowrap; max-width: calc(100% - 32px);
}
#want .wl-site .i { width: 14px; height: 14px; flex: none; }
.wl-check { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.wl-check-said {
  display: flex; align-items: flex-start; gap: 8px; margin: 0;
  font-size: var(--t-body); font-weight: 500; line-height: 22px; color: var(--w-ink-body); font-variant-numeric: tabular-nums;
}
#want .wl-check-said .i { width: 16px; height: 16px; flex: none; margin-top: 3px; color: var(--w-ink-3); }
.wl-check-note { margin: 0; font-size: var(--t-meta); line-height: 19.5px; color: var(--w-ink-2); text-wrap: pretty; }
.wl-check-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.wl-use, .wl-check-go, .wl-settings {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 16px; border: 0; border-radius: var(--r-pill);
  background: var(--w-soft); color: var(--w-ink-body); font: inherit; font-size: var(--t-meta); font-weight: 600; cursor: pointer;
}
.wl-use { background: var(--w-ink); color: var(--w-card); }
#want .wl-check-go .i { width: 16px; height: 16px; }
.wl-use:disabled, .wl-check-go:disabled { opacity: 0.6; cursor: default; }
.wl-out:focus-visible, .wl-site:focus-visible, .wl-use:focus-visible, .wl-check-go:focus-visible, .wl-settings:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (hover: none) {
  .wl-use, .wl-check-go, .wl-settings { min-height: 44px; }
}

/* ── Adding one (18:264): a bar with a rule, then the question and a capture field. */
/* The frame centres the question in the space under its bar; at a phone's height that is ~160px down. */
.wl-add-page { display: flex; flex-direction: column; align-items: flex-start; padding: 160px 8px 48px; }
.wl-add-mark {
  display: inline-flex; align-items: center; justify-content: center; width: 64px; height: 64px; margin-bottom: 24px;
  border-radius: var(--r-lg); border: 1px solid rgba(255, 255, 255, 0.5); box-shadow: var(--m2-shadow);
  background: linear-gradient(135deg, var(--w-camera-a), var(--w-camera-b)); color: var(--w-ink-3);
}
#wishadd .wl-add-mark .i { width: 28px; height: 28px; }
.wl-add-h { margin: 0 0 12px; font-size: var(--t-title); font-weight: 600; line-height: 40px; letter-spacing: -0.8px; color: var(--w-ink); }
.wl-add-lede { margin: 0 0 40px; font-size: var(--t-prose); line-height: 26px; color: var(--w-ink-2); text-wrap: pretty; }
.wl-field {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px 12px 8px 24px; box-sizing: border-box;
  background: var(--w-card); border: 1px solid var(--w-rim); border-radius: var(--r-lg); box-shadow: var(--m3-shadow);
}
.wl-input {
  flex: 1; min-width: 0; height: 56px; padding: 0; border: 0; background: none; outline: none;
  font: inherit; font-size: var(--t-prose); font-weight: 500; color: var(--w-ink);
}
.wl-input::placeholder { color: var(--w-ink-3); }
.wl-field:focus-within { border-color: var(--accent); }
.wl-go {
  display: inline-flex; align-items: center; justify-content: center; flex: none; width: 48px; height: 48px;
  border: 0; border-radius: var(--r-lg); background: var(--w-soft); color: var(--w-ink-3); cursor: pointer;
}
.wl-add-note { min-height: 1.5em; margin: 16px 4px 0; font-size: var(--t-meta); line-height: 1.5; color: var(--w-ink-2); }
/* What a pasted link's page said, straight under the field (PD-028); gone until a paste finds a link. */
.wl-add-check { margin: 16px 4px 0; font-size: var(--t-meta); line-height: 1.5; color: var(--w-ink-body); font-variant-numeric: tabular-nums; }
.wl-add-check:empty { display: none; }
/* The frame's link glyph at the head of the field (18:290). */
.wl-field-mark { display: inline-flex; flex: none; color: var(--w-ink-3); }
#wishadd .wl-field-mark .i { width: 20px; height: 20px; }

@media (max-width: 860px) {
  /* The want's hero runs to the top edge, as drawn (18:390); its Back floats over it. */
  body:has(#want:not([hidden])) .surface { padding-top: 0; }
  body:has(#wishadd:not([hidden])) .surface { padding-top: 16px; }
}
@media (hover: none) {
  .wl-nav { min-width: 44px; min-height: 44px; }
  .wl-plus { min-width: 44px; min-height: 44px; }
}

/* Owner's manual testing: editing handles, grouped context and readable chart controls. */
/*
 * ── Notes: writing, blocks and dragging (ADR-039) ─────────────────────────────────────────
 *
 * The handles: quiet grips, 44px to a finger. `touch-action: none` hands the gesture to the drag
 * rather than to scrolling, which is why only the handle - never the row - has it.
 */
.nt-drag, .nt-block-drag {
  flex: none; display: inline-flex; align-items: center; justify-content: center; touch-action: none;
  cursor: grab; min-width: 44px; min-height: 44px; padding: 0; background: transparent; color: var(--ink-3);
  border: 0; border-radius: var(--r-sm); opacity: 0.55; transition: opacity var(--dur) var(--ease);
}
.nt-drag .i, .nt-block-drag .i { width: 16px; height: 16px; }
.nt-drag:hover, .nt-block-drag:hover, .nt-drag:focus-visible, .nt-block-drag:focus-visible { opacity: 1; color: var(--ink-2); }
.nt-drag:focus-visible, .nt-block-drag:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (hover: hover) {
  /* With a mouse the grip shows on the row being pointed at, and the row itself can be picked up. */
  .nt-line .nt-drag, .nt-block .nt-block-drag { opacity: 0; }
  .nt-line:hover .nt-drag, .nt-block:hover .nt-block-drag, .nt-block.is-here .nt-block-drag { opacity: 0.55; }
}
/* While something is held: the grabbing hand everywhere, and no text selected by the sweep. */
html.nt-dragging, html.nt-dragging * { cursor: grabbing !important; user-select: none; -webkit-user-select: none; }
/* What is being dragged stays in its place, faded, as the gap it will fill. */
.is-lifted { opacity: 0.3; }
/* The lifted copy that follows the pointer. */
.nt-ghost {
  position: fixed; z-index: 90; margin: 0; box-sizing: border-box; pointer-events: none;
  background: var(--m2); border-radius: var(--r-sm); opacity: 0.85;
  box-shadow: var(--m3-shadow);
  will-change: transform;
}
.nt-ghost .nt-drag, .nt-ghost .nt-block-drag { opacity: 1; }

/* The editor's pinned strip: Done and its companions, then the toolbar, above the writing. */
/* On the ground itself, so the strip reads as part of the page with the writing sliding under it. */
.nt-pin { position: sticky; top: 0; z-index: 45; background: var(--ground); padding: 4px 0 8px; margin: 8px 0 0; }
.nt-pin .nt-acts { position: static; margin: 4px 0 0; padding: 4px 0; background: none; }
.nt-tools { display: flex; align-items: center; gap: 4px; margin: 4px 0 0; }
.nt-tools-gap { flex: 1; }
.nt-style, .nt-fmt {
  min-height: 44px; min-width: 44px; padding: 0 10px; font: inherit; font-size: var(--t-body); color: var(--ink);
  background: var(--m2); border: 1px solid var(--m3-line); border-radius: var(--r-sm); cursor: pointer;
}
.nt-style { padding-right: 6px; }
.nt-fmt:hover, .nt-style:hover { background: var(--m2-hi); }
.nt-fmt:focus-visible, .nt-style:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nt-emeta { margin: 8px 8px 0; }

/*
 * The writing: one column of blocks on the field's material, read as one page - no box per
 * block. The block the caret is in is lit faintly, so the toolbar's target is always visible.
 * A list block shows its bullet or its number (set beside it by the editor, counted exactly as
 * note-writing.ts numbers the saved page).
 */
.nt-blocks {
  position: relative; margin: 12px 0 0; padding: 6px 4px;
  background: var(--field); border: 1px solid var(--field-line); border-radius: var(--r-lg);
}
.nt-block { position: relative; display: flex; align-items: flex-start; border-radius: var(--r-sm); }
.nt-block.is-here { background: var(--m2-hi); }
.nt-block .nt-block-drag { order: 0; }
.nt-block::before { order: 1; flex: none; width: 0; padding-top: 8px; color: var(--ink-2); font-size: var(--t-prose); line-height: 1.6; text-align: right; }
.nt-block[data-mark="- "]::before { content: "•"; width: 16px; }
.nt-block[data-mark="1. "]::before { content: attr(data-n) "."; width: 24px; font-variant-numeric: tabular-nums; }
.nt-block .nt-editor {
  order: 2; flex: 1; min-width: 0; min-height: 0; max-height: none; margin: 0; padding: 8px 8px 8px 6px;
  field-sizing: content; resize: none; overflow: hidden; border: 0; border-radius: 0; background: none; box-shadow: none;
}
.nt-block .nt-editor:focus { box-shadow: none; }
.nt-block[data-mark="# "] .nt-editor { font-size: 1.25em; font-weight: 600; line-height: 1.35; }
.nt-add-block {
  display: flex; align-items: center; gap: 8px; min-height: 44px; margin: 4px 0 0; padding: 8px 12px;
  background: none; border: 0; cursor: pointer; font: inherit; font-size: var(--t-meta); font-weight: 600; color: var(--ink-2);
}
.nt-add-block .i { width: 16px; height: 16px; }
.nt-add-block:hover { color: var(--ink); }
.nt-add-block:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nt-resume { display: block; width: 100%; min-height: 44px; margin: 8px 0; padding: 8px 12px; text-align: left; font: inherit; font-size: var(--t-meta); color: var(--ink); border: 1px solid var(--hairline); border-radius: var(--r-sm); background: var(--m2); cursor: pointer; }

/*
 * A saved page, read: paragraphs a line apart, a heading with room above it, list items close
 * together with the marker hanging in the margin so a wrapped line lines up under the words.
 */
.nt-written { display: block; margin: 0; white-space: pre-wrap; }
.nt-written + .nt-written { margin-top: 12px; }
.nt-written-heading { font-size: 1.25em; font-weight: 600; line-height: 1.35; letter-spacing: -0.01em; }
.nt-written + .nt-written-heading { margin-top: 20px; }
.nt-written-bullet, .nt-written-number { position: relative; padding-left: 26px; }
.nt-written-bullet + .nt-written-bullet, .nt-written-number + .nt-written-number { margin-top: 4px; }
.nt-mark { position: absolute; left: 0; width: 20px; text-align: right; color: var(--ink-2); font-variant-numeric: tabular-nums; }
/* As Today's: the group's label over its list card, with no box around the pair (review F-19). */

.m-chart-axis, .m-chart-dates { display: flex; justify-content: space-between; gap: 12px; font-size: var(--t-meta); color: var(--ink-3); }
.m-chart-axis { position: absolute; left: -64px; top: 16%; bottom: 5%; width: 58px; flex-direction: column; text-align: right; }
body:has(#notes:not([hidden]) .nt-editor-form) .capture { display: none; }
@media (max-width: 860px) {
  /* Keep the writing and its Save/Keep draft actions in the resized Android viewport.
     Keep draft returns to reading, where the normal navigation and Talk return. */
  body:has(#notes:not([hidden]) .nt-editor-form) .ai-action,
  body:has(#notes:not([hidden]) .nt-editor-form) .tabbar { display: none; }
}
.nt-discard { min-height: 44px; border: 1px solid var(--hairline); border-radius: var(--r-pill); padding: 8px 12px; background: var(--m2); color: var(--ink-2); }
.m-traj-plot:has(.m-chart-axis) { margin-left: 64px; }

/*
 * CAP-130 - the assistant tray (PD-036, UX-018). Settings' rows and buttons, Activity cards and
 * Notes' own writing; what is added is only what a proposal needs to be read whole: the exact
 * characters of a capture, a proposed page set as a page, and two buttons of one size.
 */
/* The desk hosts the phone column (UX-013 §12), as it does every reached page; the bar is its title. */
@media (min-width: 861px) { #assistant { max-width: var(--desk-col); } }
body:has(#assistant:not([hidden])) .head { display: none; }
#settings .as-entry-block, #assistant .as-block { margin: 0 0 24px; }
#assistant .group-label { padding: 0 8px 8px; }
#assistant .m-activity { margin: 0; }
#assistant .s-says, #assistant .as-reach { margin-left: 8px; margin-right: 8px; }
.as-entry {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: 52px; padding: 16px; cursor: pointer; text-align: left;
  font: inherit; color: inherit; background: none; border: 0;
}
.as-entry .i { flex: none; width: 16px; height: 16px; color: var(--ink-3); }
.as-entry:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (max-width: 860px) {
  /* On a phone the entry sits under the index, and goes with it when a group is open. */
  #settings[data-open] .as-entry-block { display: none; }
}
.as-reading { margin: 0 0 8px; }
.as-told { margin: 0 0 8px; color: var(--ink); }
.as-reach { margin-top: 0; margin-bottom: 24px; }
.as-said {
  margin: 12px 0 0; padding: 12px 16px; white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: var(--t-body); line-height: 1.5; color: var(--ink);
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-sm);
}
.as-page {
  margin: 12px 0 0; padding: 12px 16px;
  background: var(--m2-hi); border: 1px solid var(--m2-line); border-radius: var(--r-sm);
}
.as-page-title { margin: 0 0 8px; font-size: var(--t-body); font-weight: 600; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.as-page-body { font-size: var(--t-body); line-height: 1.6; color: var(--ink); overflow-wrap: anywhere; }
.as-page-body .nt-written { display: block; white-space: pre-wrap; }
.as-label { margin: 12px 0 0; font-size: var(--t-meta); font-weight: 600; color: var(--ink-2); }
.as-choices { margin: 12px 0 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 8px; }
.as-choices legend { padding: 0; margin-bottom: 4px; }
.as-choice { display: flex; align-items: flex-start; gap: 8px; min-height: 32px; font-size: var(--t-body); line-height: 1.4; color: var(--ink); }
.as-choice input { flex: none; margin-top: 3px; width: 18px; height: 18px; accent-color: var(--accent); }
.as-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; }
/* The same size, neither chosen for you (UX-018 point 3): each takes half the row. */
.as-acts .s-save { margin: 0; flex: 1 1 0; min-width: 8rem; }
.as-setup .s-control { margin: 12px 0 0; }
.as-setup .s-control input.s-text { flex: 1 1 auto; min-width: 0; }

/*
 * DR-04 (owner, 30 September 2026): a place's link to what it cannot see, which lives on Settings.
 * The quietest thing on the page - a line of ink under everything else, never a card.
 */
.limits-row { margin: 24px 0 0; }
.limits-link {
  font: inherit; font-size: var(--t-meta); color: var(--ink-2); background: none; border: 0; padding: 0;
  cursor: pointer; text-decoration: underline; text-decoration-color: var(--hairline); text-underline-offset: 3px;
}
.limits-link:hover { color: var(--ink); }
.s-limit .m-tx-meta + .m-tx-meta { margin-top: 4px; }
@media (hover: none) { .limits-link { min-height: 44px; } }
/* A reached page's own limits (DR-04): footnote lines at its foot, no card and no fold. */
.page-limits { margin: 24px 0 0; display: grid; gap: 4px; }
.page-limit { margin: 0; font-size: var(--t-meta); line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }

/*
 * Desktop keeps the 600px column (owner, DR-10, 30 September 2026) and only its spacing changes: the
 * column sat flush left beside the rail with about 600px of empty ground to its right. It is centred
 * in the space the rail leaves, so the page reads as placed rather than dropped at one edge.
 */
@media (min-width: 861px) {
  .surface > * { width: 100%; max-width: var(--desk-col); margin-inline: auto; }
}

/* An answer pill that is also an .act (ADR-049) keeps its words: .act's square is for icons. */
.act.c-answer { width: auto; height: auto; min-width: 44px; padding: 0 14px; white-space: nowrap; }

/* ───────────────────────────────────────── Adding by hand — CAP-134 (ADR-050, PD-040)
 *
 * No frame draws a form, so it is composed from what the frames do draw (UX-015): the reached-layer
 * bar, the lens pills for choosing what to add, the capture field's own material for every control
 * (the Settings number field already took it, 26 September), and the ink pill for the one action.
 * A problem is in the attention colour, never red: red means direction (UX-012).
 */
/*
 * A place's head with an Add door (Money, Time): beside the title on the desk; under the reading on
 * a phone, where the title's right edge belongs to the floating search and settings buttons. A grid
 * rather than a float, so the door comes after the reading in the document and in reading order.
 */
.has-door { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; align-items: start; }
.has-door > * { grid-column: 1 / -1; }
.has-door > :first-child { grid-column: 1; }
.has-door > .add-door { grid-column: 2; grid-row: 1; }
@media (max-width: 860px) {
  .has-door > :first-child { grid-column: 1 / -1; }
  .has-door > .add-door { grid-column: 1 / -1; grid-row: auto; justify-self: start; margin: 4px 0 16px; }
}
.add-door {
  display: inline-flex; align-items: center; gap: 6px; margin: 0;
  min-height: 36px; padding: 0 14px; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--m2);
  background: var(--ink); border: 1px solid var(--ink); border-radius: var(--r-pill); box-shadow: var(--m2-shadow);
}
.add-door .i { width: 16px; height: 16px; }
.add-door:focus-visible, .en-kind:focus-visible, .en-save:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.empty .add-door { margin: 16px 0 0; }
/* A door under a field (your categories, under a category) is a quiet text link, not the ink pill. */
.en-field .en-link {
  align-self: flex-start; min-height: 32px; padding: 4px 0; margin: 0;
  background: none; border: 0; box-shadow: none; color: var(--ink-2);
  font-size: var(--t-meta); font-weight: 600; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--ink-faint);
}
.en-field .en-link:hover { color: var(--ink); }
@media (hover: none) { .en-field .en-link { min-height: 44px; } }
/* Under the Wishlist's own capture field, the way to the detailed form. */
.wl-add-page .add-door { margin: 24px 4px 0; }
/* In a reached layer's bar the door is the end slot: a round ink button, its words in its label. */
.layer-bar .add-door { width: 36px; height: 36px; min-height: 0; padding: 0; justify-content: center; }
@media (hover: none) { .layer-bar .add-door { width: 44px; height: 44px; } }

/* A reached layer: its bar is the page's head, as on an account (.head hidden there too). */
body:has(#entry:not([hidden])) .head { display: none; }
/* One column at the desk's width, like the Wishlist, so the bar's title centres over the form. */
#entry { max-width: var(--desk-col); }
.en-form { display: flex; flex-direction: column; gap: 18px; padding: 8px 0 48px; }
.en-kinds { display: flex; flex-wrap: wrap; gap: 8px; }
.en-kind {
  appearance: none; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--ink-2);
  padding: 8px 16px; background: var(--m2); border: 1px solid var(--pill-line); border-radius: var(--r-pill);
}
.en-kind[aria-pressed="true"] { color: var(--m2); background: var(--ink); border-color: var(--ink); box-shadow: var(--m2-shadow); }
.en-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.en-field-flag { flex-direction: row-reverse; justify-content: flex-end; align-items: center; gap: 10px; }
.en-label { font-size: var(--t-meta); font-weight: 600; line-height: 1.4; color: var(--ink-2); }
.en-optional { font-weight: 400; color: var(--ink-3); }
.en-input {
  width: 100%; min-height: 44px; box-sizing: border-box; padding: 10px 12px;
  font: inherit; font-size: var(--t-body); color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line); border-radius: var(--r-lg);
  box-shadow: var(--m2-shadow);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.en-input:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--m2-shadow), 0 0 0 3px var(--accent-soft); }
.en-input[aria-invalid="true"] { border-color: var(--attn); }
.en-figure { font-variant-numeric: tabular-nums; }
.en-check { width: 20px; height: 20px; margin: 0; accent-color: var(--ink); }
.en-more { display: flex; flex-direction: column; gap: 2px; margin: 0; font-size: var(--t-meta); line-height: 1.5; }
.en-hint { color: var(--ink-2); }
.en-problem, .en-note { color: var(--attn); font-weight: 600; }
.en-note { margin: 0; font-size: var(--t-body); line-height: 1.5; }
.en-lede { margin: 0; font-size: var(--t-body); line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
/* On Your categories, each category's name and its tick box read as one pair. */
.en-field-flag + .en-field:not(.en-field-flag) { margin-top: 8px; }
.en-actions { display: flex; justify-content: flex-end; padding-top: 4px; }
.en-save {
  min-height: 44px; padding: 0 28px; cursor: pointer;
  font: inherit; font-size: var(--t-body); font-weight: 600; line-height: 1.4; color: var(--m2);
  background: var(--ink); border: 1px solid var(--ink); border-radius: var(--r-pill); box-shadow: var(--m2-shadow);
}
.en-save:disabled { opacity: 0.6; cursor: default; }
@media (max-width: 860px) {
  .en-actions { justify-content: stretch; }
  .en-save { width: 100%; }
}

/*
 * CAP-134 - a correction shows the words it corrects, as the evidence popover quotes them; and
 * Correct / Remove / Put it back under a record's words are quiet text buttons, the row's own ink.
 */
.en-said { padding: 12px 14px; border-radius: var(--r-lg); background: var(--field); border: 1px solid var(--field-line); }
.en-said-text { margin: 0; font-size: var(--t-body); line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.en-said-text::before { content: '“'; }
.en-said-text::after { content: '”'; }
.en-said-when { margin: 4px 0 0; font-size: var(--t-meta); color: var(--ink-3); }
.ev-acts { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 8px; }
.ev-edit, .ev-remove, .ev-restore {
  appearance: none; cursor: pointer; padding: 6px 0; min-height: 32px; background: none; border: 0;
  font: inherit; font-size: var(--t-meta); font-weight: 600; font-style: normal; color: var(--ink-2);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--ink-faint);
}
.ev-edit:hover, .ev-remove:hover, .ev-restore:hover { color: var(--ink); }
.ev-edit:focus-visible, .ev-remove:focus-visible, .ev-restore:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: none) { .ev-edit, .ev-remove, .ev-restore { min-height: 44px; } }
