/* Pear web app: foundations for the login page and the signed-in product ("lab calm" v2 → "body + lists" v3 → "one brand" v4).
 *
 * The landing pages' brand system (../../css/tokens.css), reduced to three
 * brand colours (forest, teal, warm), four neutrals (pearl, sage, white, ink)
 * and the iOS app's text and state roles (--text-primary / -secondary / -muted,
 * --state-optimal). Every other shade is one of these at a lower opacity. Text on
 * dark is #f2f4f6 or #e5eeea. Warm is only for "needs attention". The only dark brand
 * field is the FOREST DIFFUSE (.forest-field): forest, luminous teal blooms, a deep shade.
 *
 * Type (v4): calm and light. Inter / Chiron 400 for text, 500 for titles, labels and
 * the selected state; IBM Plex Mono 400 (var(--font-num)) for every number, value and
 * unit; nothing heavier than 500 in the product, and TeX Gyre Adventor only on the landing.
 *
 * Signed-in layout: a glass top bar whose five destinations sit in ONE centred
 * glass capsule, a fluid content width (min(100% - 2 × --page-pad, --page-max): the
 * bar sits on the same edges), a 12-column lab grid with a gap of clamp(24px, 2vw, 40px)
 * and 56-72px between major modules on a desktop. Content is LISTS (.list / .list__row:
 * Apple-style, no fill, hairlines inset after the icon); a LIQUID GLASS card (.lg) is for
 * key positions only (the hero number, a callout, an entry card). Drawers, modals,
 * menus and toasts use the same liquid-glass language (translucent, blurred,
 * lit from above, no border line). Materials: the landing's diffuse light (four
 * soft blooms over pearl, body::before) under a very fine grain; "jelly glass"
 * buttons (translucent, glossy, no outline line); .segmented glass controls.
 * Structure follows the iOS app: Home · Data · Protocol · Market · Discover,
 * plus Upload and the account routes (Profile, Care Circle, Membership,
 * Settings). Data is grouped by nine health areas (P.areas() in core.js).
 *
 * File map: this file (foundations: tokens, type, buttons, glass cards, lists,
 * segmented control, lab grid primitives, charts, forms, shell, drawer / modal /
 * toast) · css/body.css (the body model) · css/login.css (login) ·
 * css/screens/overview.css · data.css · more.css (the screens). url() inside a
 * custom property resolves against the stylesheet that USES var(): keep every
 * var(--grain*) rule in this file. */

/* ---------- Palette and roles (light is the brand default) ---------- */
:root {
  --forest: var(--brand-ink);
  --teal: #4fa59a;
  --warm: var(--brand-attention);
  --pearl: var(--brand-canvas);
  --sage: #e5eeea;
  --white: #ffffff;
  --ink: var(--brand-text);
  --cream: #f4f3e8;                   /* sparingly: display headlines and the wordmark on dark / photo */
  --on-dark: var(--pearl);
  --on-dark-2: var(--sage);

  --bg: var(--pearl);
  --bar-h: 56px;                      /* the top bar's height (52px on phones): offset sticky things by it */
  /* Text follows the iOS app: primary #14161a · secondary #545a63 (6.3:1 on pearl) · muted #686f79 (4.6:1 on pearl; inside glass
   * and panels --text-3 is re-pointed at the secondary colour so muted text keeps AA over the colour blooms) */
  --text: var(--text-primary);
  --text-2: var(--text-secondary);
  --text-3: var(--text-muted);
  /* Hairlines: module rules, row separators, the bar's bottom edge */
  --rule: rgba(20, 22, 26, 0.08);
  --rule-2: rgba(20, 22, 26, 0.14);
  --hair: var(--rule);
  --hair-2: var(--rule-2);
  --accent: var(--forest);
  --on-accent: var(--pearl);
  --accent-ink: var(--forest);
  --tint: rgba(79, 165, 154, 0.14);
  --tint-2: rgba(23, 60, 50, 0.08);
  --card: var(--material-card);
  --card-2: rgba(20, 22, 26, 0.035);
  --field: var(--brand-field);
  --field-line: rgba(20, 22, 26, 0.18);
  --hover: rgba(20, 22, 26, 0.045);   /* wash under a hovered menu item / row */
  --panel: rgba(250, 251, 252, 0.7);  /* liquid panels: drawers, modals, the account menu, toasts (blurred, see through to the page) */
  --panel-solid: #fafbfc;             /* the same panel opaque: only for strokes drawn on a panel (chart dots inside a drawer) */
  --bar-bg: rgba(242, 244, 246, 0.5); /* the glass top bar */
  --glass-fill: rgba(255, 255, 255, 0.55); /* floating glass that content scrolls under: the bottom tabs, .glass */
  --ok: var(--ok-ink);                 /* steady: text (6.3:1 on white); the dot / icon colour is --state-optimal */
  --ok-bg: rgba(59, 120, 100, 0.12);   /* the soft fill behind a steady icon or tag */
  --rev: var(--ink);
  --rev-bg: rgba(224, 138, 98, 0.2);
  --rev-dot: var(--warm);
  --none: var(--text-2);
  --none-bg: rgba(20, 22, 26, 0.05);
  --teal-1: rgba(79, 165, 154, 0.5);  /* gradients run from teal at half strength */
  --teal-2: var(--teal);
  --teal-3: var(--forest);            /* … to forest */
  --mint: var(--sage);
  --paper: var(--white);
  --scrim: rgba(20, 22, 26, 0.34);
  /* Chart series: you · family 1 · family 2 (attention is --warm, only for the flagged point). --series-you / -fam1 / -fam2
   * (tokens.css) are the names; --series-1 / -2 / -3 stay as the index aliases the charts use by default. Dark values below. */
  --series-1: var(--series-you);
  --series-2: var(--series-fam1);
  --series-3: var(--series-fam2);
  --band-lab: rgba(23, 60, 50, 0.055);       /* chart bands: the lab's reference range … */
  --band-research: rgba(79, 165, 154, 0.14); /* … and the research range */
  /* Diffuse charts (P.chart.spectrum / P.chart.gauge): soft blurred colour under hairline ticks */
  --dif-ok-a: rgba(79, 165, 154, 0.5);         /* steady: teal … */
  --dif-ok-b: rgba(143, 199, 168, 0.62);       /* … to mint */
  --dif-warm: rgba(224, 138, 98, 0.8);         /* worth a look */
  --dif-none: rgba(104, 111, 121, 0.34);       /* tested, no range */
  --dif-rest: rgba(104, 111, 121, 0.2);        /* not tested / the unreached part of a gauge */
  --dif-tick: rgba(20, 22, 26, 0.3);           /* hairline ticks */
  --dif-tick-ok: rgba(44, 107, 82, 0.42);
  --dif-hand: rgba(20, 22, 26, 0.72);          /* the marker line and the gauge needle */
  --dif-low: rgba(224, 138, 98, 0.7);          /* the gauge's low end (the "worth a look" side of the scale) … */
  --dif-mid: rgba(226, 222, 176, 0.72);        /* … a pale middle … */
  /* Glass: the bar, the tabs, popovers */
  --glass: rgba(255, 255, 255, 0.3);
  --glass-strong: rgba(255, 255, 255, 0.64);
  --glass-edge: var(--material-stroke);
  --glass-hi: var(--material-highlight);
  --glass-line: var(--material-line);
  --glass-blur: var(--material-blur);
  --glass-shadow: var(--material-shadow);
  --btn-primary: linear-gradient(180deg, rgba(23, 60, 50, 0.66), rgba(23, 60, 50, 0.82));
  --seg-on: rgba(255, 255, 255, 0.92);                 /* the active pill of a segmented control / the top capsule / the bottom tabs */
  --seg-track: rgba(255, 255, 255, 0.35);              /* the glass track of a segmented control */
  --seg-pill-shadow: 0 1px 2px rgba(13, 31, 25, 0.1), 0 4px 12px -4px rgba(13, 31, 25, 0.22);
  /* The page's light (v3): the landing's diffuse light, four soft blooms over pearl, under the grain (body::before) */
  --bloom-1: var(--brand-bloom-1);
  --bloom-2: var(--brand-bloom-2);
  --bloom-3: var(--brand-bloom-3);
  --bloom-4: var(--brand-bloom-4);
  /* Liquid glass: .lg cards, the segmented tracks, drawers / modals / menus. Transparent, blurred, lit from above, no border line */
  --lg-bg: var(--material-card);
  --lg-bg-hover: rgba(255, 255, 255, 0.38);
  --lg-blur: var(--material-blur);
  --lg-hi: var(--material-highlight);
  --lg-edge: var(--material-stroke);
  --lg-glow: rgba(23, 60, 50, 0.18);                   /* the soft inner glow along the bottom */
  --lg-shadow: rgba(13, 31, 25, 0.35);                 /* the soft outer shadow */
  --lg-bloom-score: rgba(79, 165, 154, 0.36);          /* the colour bloom inside a card: teal … */
  --lg-bloom-score-2: rgba(23, 60, 50, 0.16);          /* … and forest (score) */
  --lg-bloom-warm: rgba(224, 138, 98, 0.32);           /* warm (needs attention) */
  --lg-bloom-warm-2: rgba(224, 138, 98, 0.12);
  --lg-bloom-sage: rgba(229, 238, 234, 0.95);          /* sage and forest (neutral) */
  --lg-bloom-sage-2: rgba(23, 60, 50, 0.1);
  --text-3-glass: var(--text-secondary);               /* muted text inside glass keeps AA over the colour blooms */
  /* Button materials are inherited from the shared brand tokens. */
  --jelly-soft-shadow: inset 0 1px 0 var(--material-highlight);
  /* … on photos and forest fields */
  --disc: rgba(255, 255, 255, 0.5);
  --grain-soft: url("../../assets/texture/grain-soft.png");
  --grain: url("../../assets/texture/grain.png");
  --shadow-1: 0 1px 2px rgba(20, 22, 26, 0.04), 0 0 0 1px var(--rule);
  --shadow-2: 0 8px 24px -10px rgba(13, 31, 25, 0.22), 0 0 0 1px var(--rule-2);
  --shadow-pop: 0 0 0 1px var(--rule-2), 0 18px 44px -14px rgba(13, 31, 25, 0.3);
  color-scheme: light;
}
/* Dark: chosen in Settings → Appearance (or "match system"): ink-dark with the same four blooms, in forest and teal */
:root[data-theme="dark"] {
  --bg: #121417;
  --text-primary: #f2f4f6; --text-secondary: #b9bec6; --text-muted: #9097a0;   /* the app's three text roles on ink-dark */
  --state-optimal: #62b59a;
  --series-you: #e5eeea; --series-fam1: #4fa59a; --series-fam2: #939fdb;
  --rule: rgba(242, 244, 246, 0.1); --rule-2: rgba(242, 244, 246, 0.18);
  --accent: var(--sage); --on-accent: var(--forest); --accent-ink: var(--sage);
  --tint: rgba(79, 165, 154, 0.22); --tint-2: rgba(242, 244, 246, 0.1);
  --card: rgba(255, 255, 255, 0.04); --card-2: rgba(255, 255, 255, 0.05);
  --field: rgba(255, 255, 255, 0.06); --field-line: rgba(242, 244, 246, 0.22);
  --hover: rgba(242, 244, 246, 0.06); --panel: rgba(27, 30, 35, 0.62); --panel-solid: #1b1e23; --bar-bg: rgba(18, 20, 23, 0.5); --glass-fill: rgba(30, 33, 38, 0.55);
  --ok: var(--sage); --ok-bg: rgba(98, 181, 154, 0.2); --rev: var(--pearl); --rev-bg: rgba(224, 138, 98, 0.26);
  --none: var(--sage); --none-bg: rgba(242, 244, 246, 0.08);
  --teal-3: var(--teal); --teal-1: rgba(79, 165, 154, 0.45);
  --scrim: rgba(0, 0, 0, 0.55);
  --band-lab: rgba(242, 244, 246, 0.06); --band-research: rgba(79, 165, 154, 0.2);
  --dif-ok-a: rgba(79, 165, 154, 0.62); --dif-ok-b: rgba(120, 190, 150, 0.5); --dif-warm: rgba(224, 138, 98, 0.74);
  --dif-none: rgba(242, 244, 246, 0.24); --dif-rest: rgba(242, 244, 246, 0.12); --dif-tick: rgba(242, 244, 246, 0.36); --dif-tick-ok: rgba(143, 199, 168, 0.62); --dif-hand: rgba(242, 244, 246, 0.82);
  --dif-low: rgba(236, 152, 112, 0.74); --dif-mid: rgba(214, 224, 180, 0.58);
  --glass: rgba(255, 255, 255, 0.05); --glass-strong: rgba(27, 30, 35, 0.9); --glass-edge: rgba(242, 244, 246, 0.1); --glass-hi: rgba(242, 244, 246, 0.14); --glass-line: rgba(242, 244, 246, 0.08);
  --glass-shadow: 0 14px 34px -18px rgba(0, 0, 0, 0.6);
  --btn-primary: linear-gradient(180deg, rgba(229, 238, 234, 0.94), rgba(229, 238, 234, 0.82));
  --seg-on: rgba(242, 244, 246, 0.16); --seg-track: rgba(255, 255, 255, 0.07); --seg-pill-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 12px -4px rgba(0, 0, 0, 0.5);
  --bloom-1: rgba(143, 199, 168, 0.11); --bloom-2: rgba(31, 75, 62, 0.42); --bloom-3: rgba(79, 165, 154, 0.14); --bloom-4: rgba(23, 60, 50, 0.5);
  --lg-bg: rgba(255, 255, 255, 0.06); --lg-bg-hover: rgba(255, 255, 255, 0.1); --lg-hi: rgba(255, 255, 255, 0.17); --lg-edge: rgba(255, 255, 255, 0.09);
  --lg-glow: rgba(0, 0, 0, 0.45); --lg-shadow: rgba(0, 0, 0, 0.7);
  --lg-bloom-score: rgba(79, 165, 154, 0.3); --lg-bloom-score-2: rgba(23, 60, 50, 0.5); --lg-bloom-warm: rgba(224, 138, 98, 0.26); --lg-bloom-warm-2: rgba(224, 138, 98, 0.1);
  --lg-bloom-sage: rgba(229, 238, 234, 0.1); --lg-bloom-sage-2: rgba(23, 60, 50, 0.5); --text-3-glass: var(--text-secondary);
  --jelly-bg: rgba(242, 244, 246, 0.08); --jelly-bg-hover: rgba(242, 244, 246, 0.14); --jelly-tint: rgba(229, 238, 234, 0.12); --jelly-ink: var(--sage);
  --jelly-gloss: radial-gradient(120% 95% at 50% -18%, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 60%);
  --jelly-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 -8px 14px rgba(0, 0, 0, 0.14), 0 10px 24px -14px rgba(0, 0, 0, 0.6);
  --jelly-soft-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -6px 12px rgba(0, 0, 0, 0.14);
  --disc: rgba(18, 20, 23, 0.5);
  --focus-on-light: var(--sage);
  --grain-soft: url("../../assets/texture/grain-night.png");
  --shadow-1: 0 0 0 1px var(--rule);
  --shadow-2: 0 14px 34px -14px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--rule-2);
  --shadow-pop: 0 0 0 1px var(--rule-2), 0 22px 48px -14px rgba(0, 0, 0, 0.7);
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --bg: #121417;
    --text-primary: #f2f4f6; --text-secondary: #b9bec6; --text-muted: #9097a0;   /* the app's three text roles on ink-dark */
    --state-optimal: #62b59a;
    --series-you: #e5eeea; --series-fam1: #4fa59a; --series-fam2: #939fdb;
    --rule: rgba(242, 244, 246, 0.1); --rule-2: rgba(242, 244, 246, 0.18);
    --accent: var(--sage); --on-accent: var(--forest); --accent-ink: var(--sage);
    --tint: rgba(79, 165, 154, 0.22); --tint-2: rgba(242, 244, 246, 0.1);
    --card: rgba(255, 255, 255, 0.04); --card-2: rgba(255, 255, 255, 0.05);
    --field: rgba(255, 255, 255, 0.06); --field-line: rgba(242, 244, 246, 0.22);
    --hover: rgba(242, 244, 246, 0.06); --panel: rgba(27, 30, 35, 0.62); --panel-solid: #1b1e23; --bar-bg: rgba(18, 20, 23, 0.5); --glass-fill: rgba(30, 33, 38, 0.55);
    --ok: var(--sage); --ok-bg: rgba(98, 181, 154, 0.2); --rev: var(--pearl); --rev-bg: rgba(224, 138, 98, 0.26);
    --none: var(--sage); --none-bg: rgba(242, 244, 246, 0.08);
    --teal-3: var(--teal); --teal-1: rgba(79, 165, 154, 0.45);
    --scrim: rgba(0, 0, 0, 0.55);
    --band-lab: rgba(242, 244, 246, 0.06); --band-research: rgba(79, 165, 154, 0.2);
    --dif-ok-a: rgba(79, 165, 154, 0.62); --dif-ok-b: rgba(120, 190, 150, 0.5); --dif-warm: rgba(224, 138, 98, 0.74);
    --dif-none: rgba(242, 244, 246, 0.24); --dif-rest: rgba(242, 244, 246, 0.12); --dif-tick: rgba(242, 244, 246, 0.36); --dif-tick-ok: rgba(143, 199, 168, 0.62); --dif-hand: rgba(242, 244, 246, 0.82);
    --dif-low: rgba(236, 152, 112, 0.74); --dif-mid: rgba(214, 224, 180, 0.58);
    --glass: rgba(255, 255, 255, 0.05); --glass-strong: rgba(27, 30, 35, 0.9); --glass-edge: rgba(242, 244, 246, 0.1); --glass-hi: rgba(242, 244, 246, 0.14); --glass-line: rgba(242, 244, 246, 0.08);
    --glass-shadow: 0 14px 34px -18px rgba(0, 0, 0, 0.6);
    --btn-primary: linear-gradient(180deg, rgba(229, 238, 234, 0.94), rgba(229, 238, 234, 0.82));
    --seg-on: rgba(242, 244, 246, 0.16); --seg-track: rgba(255, 255, 255, 0.07); --seg-pill-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 12px -4px rgba(0, 0, 0, 0.5);
    --bloom-1: rgba(143, 199, 168, 0.11); --bloom-2: rgba(31, 75, 62, 0.42); --bloom-3: rgba(79, 165, 154, 0.14); --bloom-4: rgba(23, 60, 50, 0.5);
    --lg-bg: rgba(255, 255, 255, 0.06); --lg-bg-hover: rgba(255, 255, 255, 0.1); --lg-hi: rgba(255, 255, 255, 0.17); --lg-edge: rgba(255, 255, 255, 0.09);
    --lg-glow: rgba(0, 0, 0, 0.45); --lg-shadow: rgba(0, 0, 0, 0.7);
    --lg-bloom-score: rgba(79, 165, 154, 0.3); --lg-bloom-score-2: rgba(23, 60, 50, 0.5); --lg-bloom-warm: rgba(224, 138, 98, 0.26); --lg-bloom-warm-2: rgba(224, 138, 98, 0.1);
    --lg-bloom-sage: rgba(229, 238, 234, 0.1); --lg-bloom-sage-2: rgba(23, 60, 50, 0.5); --text-3-glass: var(--text-secondary);
    --jelly-bg: rgba(242, 244, 246, 0.08); --jelly-bg-hover: rgba(242, 244, 246, 0.14); --jelly-tint: rgba(229, 238, 234, 0.12); --jelly-ink: var(--sage);
    --jelly-gloss: radial-gradient(120% 95% at 50% -18%, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 60%);
    --jelly-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 -8px 14px rgba(0, 0, 0, 0.14), 0 10px 24px -14px rgba(0, 0, 0, 0.6);
    --jelly-soft-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -6px 12px rgba(0, 0, 0, 0.14);
    --disc: rgba(18, 20, 23, 0.5);
    --focus-on-light: var(--sage);
    --grain-soft: url("../../assets/texture/grain-night.png");
    --shadow-1: 0 0 0 1px var(--rule);
    --shadow-2: 0 14px 34px -14px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--rule-2);
    --shadow-pop: 0 0 0 1px var(--rule-2), 0 22px 48px -14px rgba(0, 0, 0, 0.7);
    color-scheme: dark;
  }
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); scroll-padding-top: calc(var(--bar-h) + 16px); }
body {
  margin: 0; min-height: 100svh; color: var(--text);
  background: var(--grain-soft) 0 0 / 128px 128px;
  font: 400 15px/22px var(--font-sans); font-synthesis: none; font-kerning: normal;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
html:lang(zh) body { line-height: 26px; }
/* The page's light: the landing's diffuse light. Pearl (html) with four soft blooms (sage top left, forest-teal right, teal lower
 * left, forest along the bottom), fixed to the viewport so glass glides over it; the very fine grain (body) sits on top of them. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(64% 56% at 2% 0%, var(--bloom-1), transparent 72%),
    radial-gradient(50% 66% at 104% 34%, var(--bloom-2), transparent 74%),
    radial-gradient(58% 54% at -2% 100%, var(--bloom-3), transparent 74%),
    radial-gradient(76% 42% at 62% 110%, var(--bloom-4), transparent 70%);
}
img, svg, picture { display: block; max-width: 100%; }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
h1, h2, h3, h4, b, strong { font-weight: 500; }   /* nothing heavier than 500 in the product */
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; }
a { color: inherit; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--focus-on-light); outline-offset: 2px; }
.on-dark :focus-visible, .forest-field :focus-visible { outline-color: var(--sage); }
::selection { background: rgba(79, 165, 154, 0.25); }
.vh { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.wseg { white-space: nowrap; }
html:lang(zh) [data-wrap="clause"] { word-break: keep-all; overflow-wrap: anywhere; }
.skip { position: absolute; left: 8px; top: -64px; z-index: 100; padding: 10px 18px; border-radius: 999px; background: var(--forest); color: var(--pearl); text-decoration: none; font: 500 14px/1 var(--font-sans); }
.skip:focus { top: 8px; }
.ico { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- Type roles (v4: calm) ----------
 * Inter (zh: Chiron Hei HK) 400 for text, 500 for titles, labels and the selected state; IBM Plex Mono 400 for every number, value and
 * unit (var(--font-num)). Nothing heavier than 500; TeX Gyre Adventor is landing-only. Line heights are generous; no tracking tighter
 * than -0.02em on text.
 *   page title   28/1.25 500 (zh 26/1.35)         large greeting  32/1.2 500 (zh 28/1.3)   (.t-display--lg)
 *   section label 12/16 500 uppercase +0.08em (zh 13/18, no caps, +0.02em)
 *   body / list title 15/22 400 --text            secondary 13/20 400 --text-2            meta / fine 12/18 400 --text-3
 *   values: Plex Mono 15/18 -0.01em + unit 11/14 --text-2 (lists) · 28 (metrics) · 40/1 -0.02em (key numbers in glass; one hero 52) ·
 *   chart labels Plex Mono 11 --text-3. Spacing is a 4px grid: 56-72px between major modules on a desktop, 24px inside a module. */
.t-display { font: 500 28px/1.25 var(--font-sans); letter-spacing: -0.015em; color: var(--text); }
html:lang(zh) .t-display { font-size: 26px; line-height: 1.35; letter-spacing: 0.01em; }
.t-display--lg { font-size: 32px; line-height: 1.2; }
html:lang(zh) .t-display--lg { font-size: 28px; line-height: 1.3; }
.t-h2 { font: 500 18px/26px var(--font-sans); letter-spacing: -0.005em; color: var(--text); }
html:lang(zh) .t-h2 { line-height: 28px; letter-spacing: 0.01em; }
.t-h3 { font: 500 15px/22px var(--font-sans); color: var(--text); }
.t-eyebrow { font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
html:lang(zh) .t-eyebrow { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.t-body { font-size: 15px; line-height: 22px; color: var(--text); }
html:lang(zh) .t-body { line-height: 26px; }
.t-small { font-size: 13px; line-height: 20px; color: var(--text-2); }
html:lang(zh) .t-small { line-height: 22px; }
.t-fine { font-size: 12px; line-height: 18px; color: var(--text-3); }
html:lang(zh) .t-fine { line-height: 20px; }
.t-value { font: 400 32px/1 var(--font-num); letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.t-value--hero { font-size: 40px; }
.t-value--xl { font-size: 52px; letter-spacing: -0.02em; }  /* the one big number of a page, in a glass card */
.t-unit { margin-left: 4px; font: 400 12px/1 var(--font-num); color: var(--text-2); letter-spacing: 0; }
.num { font-family: var(--font-num); font-weight: 400; font-variant-numeric: tabular-nums; }
.adv { font-family: var(--font-num); font-weight: 400; letter-spacing: -0.01em; }   /* v3 name, kept: it is now the number font */

/* ---------- Materials ---------- */
/* Forest diffuse (.forest-field): the one dark brand field (the login photo's ground, the foundations' brand block; the landing builds
 * the same recipe in site.css). Base --forest; luminous soft blooms of teal (top right, bottom left) and a breath of sage light in the
 * middle; a deep shade toward the lower right corner and a lighter one top left; the (lighter) grain on top. It sits around the
 * forest-graded photos. Text on it is #f2f4f6 / #e5eeea; buttons on it are .btn--light (dark jelly). */
.forest-field {
  color: var(--pearl);
  background-color: var(--forest);
  background-image:
    var(--grain),
    radial-gradient(62% 56% at 90% 4%, var(--forest-bloom-teal), transparent 70%),
    radial-gradient(64% 60% at 2% 98%, var(--forest-bloom-teal), transparent 72%),
    radial-gradient(52% 46% at 48% 42%, var(--forest-bloom-sage), transparent 72%),
    radial-gradient(72% 62% at 100% 100%, var(--forest-shade), transparent 70%),
    radial-gradient(56% 46% at 0% 0%, rgba(9, 26, 20, 0.3), transparent 70%);
  background-size: 128px 128px, auto, auto, auto, auto, auto;
}
/* Glass: floating bars and capsules that content scrolls under (the bottom tabs): translucent, blurred, lit from above, no outline */
.glass {
  background: var(--glass-fill);
  -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), inset 0 -10px 20px -14px var(--lg-glow), 0 18px 40px -22px var(--lg-shadow);
}
/* Cream, only on photo / forest: the wordmark and display type */
.auth__brand .wordmark, .forest-field .wordmark { color: var(--wordmark-on-dark); }
/* Photography: real product and editorial photos fill their frames */
.product__art > img, .article-card__art > img, .article__art > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.media-icon { display: grid; place-items: center; width: 100%; height: 100%; min-height: 64px; background: var(--tint); color: var(--accent-ink); }
.media-icon .ico { width: 40%; height: 40%; max-width: 44px; max-height: 44px; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topbar::before, .glass, .lg, .segmented, .menu, .modal, .drawer, .toast, .tabs { background: var(--bg) !important; }
}

/* ---------- Liquid glass card (.lg): key positions only ----------
 * The hero number, the selected-area callout, entry cards. Everything else on a page is a list. Transparent (26% white over the
 * page's light), blurred and saturated, radius 24, lit from above: a bright top edge, a liquid .5px rim, a soft inner glow along
 * the bottom, a diffuse colour bloom INSIDE (the ::before: 60% radial) and a soft outer shadow. No border line.
 *   .lg--score  teal / forest bloom (the score, steady things)      .lg--warm  warm bloom (needs attention)
 *   .lg--sage   sage / forest bloom (neutral; also the default)     .lg--link  hover lifts, press settles (a.lg / button.lg)
 * Content padding 20px 22px. Muted text inside a card (--text-3) is a touch darker so it keeps AA over the colour blooms.
 * Pieces for the usual key card (P.glass.kpi): .lg__label · .lg__value (Plex Mono 40px; --xl 52px, one per page) · .lg__unit · .lg__sub · .lg__spark. */
.lg {
  --text-3: var(--text-3-glass);
  --lg-fill:
    radial-gradient(60% 64% at 14% 0%, var(--lg-bloom-sage), transparent 72%),
    radial-gradient(60% 60% at 100% 100%, var(--lg-bloom-sage-2), transparent 72%);
  position: relative; isolation: isolate; min-width: 0; padding: 20px 22px; border-radius: 24px;
  color: var(--text); background: var(--lg-bg);
  -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), var(--glass-shadow);
}
.lg::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; background: var(--lg-fill); }
.lg--sage { --lg-fill: radial-gradient(60% 64% at 14% 0%, var(--lg-bloom-sage), transparent 72%), radial-gradient(60% 60% at 100% 100%, var(--lg-bloom-sage-2), transparent 72%); }
.lg--score { --lg-fill: radial-gradient(60% 64% at 14% 0%, var(--lg-bloom-score), transparent 72%), radial-gradient(60% 60% at 100% 100%, var(--lg-bloom-score-2), transparent 72%); }
.lg--warm { --lg-fill: radial-gradient(60% 64% at 14% 0%, var(--lg-bloom-warm), transparent 72%), radial-gradient(60% 60% at 100% 100%, var(--lg-bloom-warm-2), transparent 72%); }
a.lg, button.lg { display: block; width: 100%; border: 0; color: inherit; font: inherit; text-align: left; text-decoration: none; }
.lg--link {
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.lg--link:hover {
  background: var(--lg-bg-hover); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), inset 0 -18px 36px -24px var(--lg-glow), 0 30px 54px -30px var(--lg-shadow);
}
.lg--link:active { transform: translateY(0) scale(0.992); transition-duration: var(--dur-1); }
.lg--link:focus-visible { outline-offset: 3px; }
.lg__label { display: block; font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
html:lang(zh) .lg__label { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.lg__value { display: block; margin-top: 14px; font: 400 40px/1 var(--font-num); letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.lg__value--xl { font-size: 52px; }
.lg__unit { margin-left: 6px; font: 400 13px/1 var(--font-num); letter-spacing: 0; color: var(--text-2); }
.lg__sub { display: block; margin-top: 12px; font-size: 13px; line-height: 20px; color: var(--text-2); }
html:lang(zh) .lg__sub { line-height: 22px; }
.lg__spark { display: block; margin-top: 16px; }
.lab-grid > .lg { margin-bottom: 24px; }           /* glass cards that wrap onto a second row in a .lab-grid keep a gap */

/* ---------- Buttons: jelly glass ----------
 * Transparent, thick and glossy, no outline line: gloss + body + inner light, over a blur.
 * .btn--primary (tinted, forest 500) · .btn--secondary (ink 500) · .btn--soft (quieter) · .btn--light / .btn--cream
 * (on photo or forest: the dark jelly, #f2f4f6 text) · .btn--ghost (text) · .btn--danger (warm). Sizes 36 · --sm 32 · --lg 44. All 500. */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 36px; padding: 8px 18px; border-radius: var(--r-pill); border: 0;
  font: 500 14px/20px var(--font-sans); text-decoration: none; white-space: nowrap; cursor: pointer; user-select: none;
  color: var(--text);
  background: var(--jelly-gloss), var(--jelly-bg);
  -webkit-backdrop-filter: var(--jelly-blur); backdrop-filter: var(--jelly-blur);
  box-shadow: var(--jelly-shadow);
  transition: background-color var(--dur-1), color var(--dur-1), box-shadow var(--dur-1), transform var(--dur-1) var(--ease-out), opacity var(--dur-1);
}
.btn:hover { background: var(--jelly-gloss), var(--jelly-bg-hover); }
.btn:active { transform: scale(0.98); }
.btn .ico { width: 16px; height: 16px; }
.btn--primary { color: var(--pearl); font-weight: 500; background: var(--forest); box-shadow: none; }
.btn--primary:hover { background: color-mix(in srgb, var(--forest), black 10%); }
.btn--secondary { color: var(--text); font-weight: 500; }
.btn--soft { color: var(--text); box-shadow: var(--jelly-soft-shadow); }
.btn--ghost, .btn--ghost:hover { background: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.btn--ghost { color: var(--accent-ink); padding-inline: 14px; }
.btn--ghost:hover { background: var(--hover); }
.btn--light, .btn--cream { color: #f2f4f6; background: var(--jelly-dark-gloss), var(--jelly-dark-bg); box-shadow: var(--jelly-dark-shadow); text-shadow: 0 1px 2px rgba(13, 31, 25, 0.3); } /* the shadow keeps the label readable over the gloss */
.btn--light:hover, .btn--cream:hover { background: var(--jelly-dark-gloss), var(--jelly-dark-bg-hover); }
.btn--danger, .btn--danger:hover {
  color: var(--ink);
  background: radial-gradient(120% 95% at 50% -18%, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 58%), linear-gradient(rgba(224, 138, 98, 0.94), rgba(224, 138, 98, 0.94));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), inset 0 -8px 14px rgba(150, 60, 20, 0.14), 0 10px 22px -14px rgba(150, 60, 20, 0.55);
}
.btn--danger:hover { filter: brightness(1.04); }
.btn--lg { min-height: 44px; padding: 11px 24px; font-size: 15px; }
.btn--lg .ico { width: 18px; height: 18px; }
.btn--sm { min-height: 32px; padding: 6px 14px; font-size: 13px; }
.btn--sm .ico { width: 15px; height: 15px; }
.btn--icon { width: 36px; padding: 0; }
.btn--icon.btn--sm { width: 32px; }
/* On touch screens every button keeps a 44px hit area: an invisible ::before, not a taller pill */
@media (pointer: coarse) {
  .btn::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 100%; min-height: 44px; transform: translateY(-50%); }
}
.btn--block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
.btn.is-busy, .provider.is-busy { color: transparent !important; pointer-events: none; }
.btn.is-busy .ico, .provider.is-busy .ico { opacity: 0; }
.btn.is-busy::after, .provider.is-busy::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 16px; height: 16px; margin: -8px 0 0 -8px; border-radius: 50%;
  border: 2px solid var(--spin, var(--accent-ink)); border-right-color: transparent; animation: spin 0.7s linear infinite;
}
.btn--primary.is-busy::after { --spin: var(--pearl); }
.btn--light.is-busy::after, .btn--cream.is-busy::after { --spin: #f2f4f6; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (forced-colors: active) { .btn { border: 1px solid ButtonText; } }
.icon-btn {
  position: relative; display: inline-grid; place-items: center; flex: none; width: 36px; height: 36px; border: 0; border-radius: 50%;
  background: transparent; color: inherit; transition: background-color var(--dur-1), color var(--dur-1);
}
.icon-btn::before { content: ""; position: absolute; inset: -4px; } /* 44px hit area */
.icon-btn:hover { background: var(--hover); }
.on-dark .icon-btn:hover, .forest-field .icon-btn:hover { background: rgba(242, 244, 246, 0.12); }
.icon-btn--soft { background: var(--card-2); }
.icon-btn .ico { width: 18px; height: 18px; }
.link {
  display: inline; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--accent-ink); font-weight: 500; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.link--quiet { display: inline-flex; align-items: center; gap: 4px; min-height: 32px; text-decoration: none; }
.link--quiet:hover { text-decoration: underline; }
.link--quiet .ico { width: 16px; height: 16px; }

/* ---------- Surfaces: a quiet panel (drawers, modals and menus carry the fill; screens use modules) ---------- */
.card {
  position: relative; min-width: 0; padding: 20px; border-radius: 16px;
  background: var(--card); box-shadow: 0 0 0 1px var(--rule);
}
.card--tint { background: var(--tint); box-shadow: none; }
.card--line { background: transparent; box-shadow: 0 0 0 1px var(--rule-2); }
.card--link { display: block; color: inherit; text-decoration: none; transition: box-shadow var(--dur-2) var(--ease-out); }
.card--link:hover { box-shadow: 0 0 0 1px var(--rule-2), 0 8px 24px -14px rgba(13, 31, 25, 0.25); }
.card__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 24px; margin-bottom: 14px; }
.card__head .t-h2 { display: flex; align-items: center; gap: 10px; }
.card__more { display: inline-flex; align-items: center; gap: 2px; min-height: 28px; padding: 2px 0; border: 0; background: none; color: var(--text-2); font: 500 12px/20px var(--font-sans); text-decoration: none; white-space: nowrap; }
.card__more:hover { color: var(--accent-ink); }
.card__more .ico { width: 14px; height: 14px; }
.card__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 18px; }
.divider { height: 1px; border: 0; margin: 0; background: var(--rule); }
.bubble { display: inline-grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 50%; background: var(--tint); color: var(--accent-ink); }
.bubble .ico { width: 18px; height: 18px; }
.bubble--sm { width: 32px; height: 32px; }
.bubble--sm .ico { width: 16px; height: 16px; }
.bubble--rev { background: var(--rev-bg); color: var(--rev); }
.bubble--none { background: var(--none-bg); color: var(--none); }
.bubble--white { background: var(--card); box-shadow: 0 0 0 1px var(--rule); }

/* ---------- Lab grid primitives ----------
 * Everything on a signed-in page is built from these. Hairlines, not cards: one idea per module.
 *   .lab          the content column: width min(100% - 2 × --page-pad, --page-max) (about 1172px at 1280, 1320 at 1440, 1680 from ~1900);
 *                 the top bar sits on the same edges (the router's view has it). Phones: --page-pad 20px
 *   .lab-grid     12 columns, column gap --grid-gap (clamp(24px, 2vw, 40px)); no row gap: every .mod / .list carries its own space below
 *                 (--module-gap, 56-72px on a desktop) so modules stack the same way inside or outside a grid. Children are
 *                 .mod / .list (or anything) with a span class: .span-3 / .span-4 / .span-5 / .span-6 / .span-7 / .span-8 / .span-12 (default 12).
 *                 ≤1023px: spans ≥5 become 12, 3 and 4 become 6; ≤767px: everything is 12.
 *   .mod          a module: a 1px hairline top rule (--rule), 24px to the head; the space below is what makes --module-gap between modules
 *     .mod__head    idx "01" (Plex Mono, muted) · .mod__label (section label) · .mod__links (quiet, right)
 *   .cells/.cell  equal columns separated by vertical hairlines (stacked, with horizontal ones, on phones)
 *   .metric       .metric__label 13px secondary · .metric__value Plex Mono 28px 400 + .metric__unit 12px ·
 *                 .metric__delta 13px (--up forest/sage, --down ink, --flat muted, --warn ink with a warm dot) · .metric__spark
 *   .rows/.row    hairline-separated rows; the caller sets grid-template-columns (default: text · end); .row--head = a column-label row
 *   .tabs-text    a text tab row, 14px 500; the active tab is ink with a 1.5px underline (aria-selected / aria-current / aria-pressed / .is-active)
 * JS: P.mod(), P.metric(), P.cells() build these (core.js). */
.lab { width: min(100% - 2 * var(--page-pad), var(--page-max)); margin-inline: auto; }
.lab-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--grid-gap); }
.lab-grid > * { grid-column: span 12; min-width: 0; }
.lab-grid > .span-3 { grid-column: span 3; } .lab-grid > .span-4 { grid-column: span 4; } .lab-grid > .span-5 { grid-column: span 5; }
.lab-grid > .span-6 { grid-column: span 6; } .lab-grid > .span-7 { grid-column: span 7; } .lab-grid > .span-8 { grid-column: span 8; }
.lab-grid > .span-9 { grid-column: span 9; } .lab-grid > .span-12 { grid-column: span 12; }
@media (max-width: 1023.98px) {
  .lab-grid > .span-5, .lab-grid > .span-6, .lab-grid > .span-7, .lab-grid > .span-8, .lab-grid > .span-9 { grid-column: span 12; }
  .lab-grid > .span-3, .lab-grid > .span-4 { grid-column: span 6; }
}
/* Phones: one track and no gutters (12 tracks + 11 gutters alone are wider than a small phone) */
@media (max-width: 767.98px) { :root { --page-pad: 20px; } .lab-grid { grid-template-columns: minmax(0, 1fr); column-gap: 0; } .lab-grid > * { grid-column: 1 / -1; } }
.mod { position: relative; min-width: 0; padding-block: var(--module-inner) calc(var(--module-gap) - var(--module-inner)); border-top: 1px solid var(--rule); }
.mod__head { display: flex; align-items: center; gap: 12px; min-height: 20px; margin-bottom: var(--module-inner); }
.mod__idx { flex: none; font: 400 12px/1 var(--font-num); letter-spacing: 0; color: var(--text-3); font-variant-numeric: tabular-nums; }
.mod__label { min-width: 0; font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
html:lang(zh) .mod__label { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.mod__links { display: flex; align-items: center; gap: 16px; margin-left: auto; }
.mod__link, .list__link {
  position: relative; display: inline-flex; align-items: center; gap: 2px; min-height: 24px; padding: 0; border: 0; background: none;
  color: var(--text-2); font: 500 13px/20px var(--font-sans); text-decoration: none; white-space: nowrap; cursor: pointer; transition: color var(--dur-1);
}
.mod__link:hover, .list__link:hover { color: var(--accent-ink); }
.mod__link .ico, .list__link .ico { width: 14px; height: 14px; }
.mod__link::before, .list__link::before { content: ""; position: absolute; inset: -10px -6px; }
.cells { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.cell { min-width: 0; padding: 2px clamp(20px, 2vw, 40px); }
.cell:first-child { padding-left: 0; }
.cell:last-child { padding-right: 0; }
.cell + .cell { border-left: 1px solid var(--rule); }
a.cell, button.cell { display: block; border: 0; background: none; color: inherit; text-align: left; text-decoration: none; font: inherit; cursor: pointer; }
a.cell:focus-visible, button.cell:focus-visible { outline-offset: 4px; border-radius: 8px; }
@media (max-width: 767.98px) {
  .cells { grid-auto-flow: row; }
  .cell, .cell:first-child, .cell:last-child { padding: 14px 0; }
  .cell + .cell { border-left: 0; border-top: 1px solid var(--rule); }
  .cell:first-child { padding-top: 0; }
  .cell:last-child { padding-bottom: 0; }
}
.metric { display: grid; gap: 8px; align-content: start; min-width: 0; }
.metric__label { font-size: 13px; line-height: 20px; color: var(--text-2); }
.metric__value { font: 400 28px/1 var(--font-num); letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.metric__unit { margin-left: 6px; font: 400 12px/1 var(--font-num); letter-spacing: 0; color: var(--text-2); }
.metric--hero .metric__value { font-size: 40px; }
.metric__delta { font: 400 13px/20px var(--font-sans); color: var(--text-2); font-variant-numeric: tabular-nums; }
.metric__delta--up { color: var(--ok); }
.metric__delta--down { color: var(--text); }
.metric__delta--warn { color: var(--text); }
.metric__delta--warn::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 6px 1px 0; border-radius: 50%; background: var(--warm); }
.metric__spark { margin-top: 8px; }
.rows { display: grid; }
.row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 16px; width: 100%; min-height: 52px; padding: 12px 0; margin: 0;
  border: 0; border-top: 1px solid var(--rule); background: none; color: inherit; text-align: left; text-decoration: none; font: inherit;
}
.rows > .row:first-child { border-top: 0; }
a.row, button.row { cursor: pointer; }
a.row:hover .row__title, button.row:hover .row__title { color: var(--accent-ink); }
.row--head { min-height: 28px; padding-block: 0 8px; font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); border-top: 0; }
html:lang(zh) .row--head { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.row__main { display: grid; gap: 2px; min-width: 0; }
.row__title { font: 400 15px/22px var(--font-sans); color: var(--text); transition: color var(--dur-1); }
.row__sub { font-size: 13px; line-height: 20px; color: var(--text-2); }
.row__end { display: flex; align-items: center; gap: 12px; font: 400 15px/18px var(--font-num); letter-spacing: -0.01em; }
.chev { width: 16px; height: 16px; color: var(--text-3); }
.tabs-text { display: flex; gap: 24px; overflow-x: auto; scrollbar-width: none; }
.tabs-text::-webkit-scrollbar { display: none; }
.tabs-text > * {
  position: relative; flex: none; min-height: 36px; padding: 8px 0; border: 0; background: none; color: var(--text-2);
  font: 500 14px/20px var(--font-sans); text-decoration: none; white-space: nowrap; cursor: pointer; transition: color var(--dur-1);
}
.tabs-text > *::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; border-radius: 1px; background: transparent; }
.tabs-text > *:hover { color: var(--text); }
.tabs-text > [aria-selected="true"], .tabs-text > [aria-current], .tabs-text > [aria-pressed="true"], .tabs-text > .is-active { color: var(--text); }
.tabs-text > [aria-selected="true"]::after, .tabs-text > [aria-current]::after, .tabs-text > [aria-pressed="true"]::after, .tabs-text > .is-active::after { background: var(--text); }
.tabs-text > *:focus-visible { outline-offset: -2px; border-radius: 6px; }

/* ---------- Apple-style lists (v3, calm in v4): the default way to show content ----------
 * P.list() / P.row() build these. No fill, no card: 52px rows (dense 44px, compact 32px), a hairline between rows that starts after the
 * icon, an optional 28px tinted icon circle (or the app's 20px status mark), the title (15/22 400) over a 13px secondary line, and at the
 * right a value (Plex Mono 15/18 + an 11px unit), a sparkline and a chevron. Link rows (a / button) get a soft wash on hover; the selected
 * row is washed.
 *   .list            section · .list__head: .list__label (section label) + .list__links (quiet, right)
 *   .list__rows      ul > li > .list__row   (rows reach 10px past the text edge so the hover wash does not touch the text)
 *   .list__row       --dense 44px · --compact 32px (the app's live list: no hairlines, 12px apart) · .has-icon / .has-mark / .has-thumb set the hairline inset
 *   .list__icon      28px circle: --ok steady · --review warm · --none grey · --neutral forest (the default) · .list__thumb 44px photo
 *   .list__mark      the app's 20px status mark: --ok an outlined check-circle (--state-optimal) · --review warm · --none grey · --untested a dotted ring
 *   .list__main      .list__title 15/22 · .list__sub 13/20 secondary
 *   .list__end       .list__value (+ .list__unit) · .list__text · .list__spark · .chev
 * A list adds --module-gap (56-72px) below itself so lists stack in a grid; inside a glass card, drawer or modal that padding is off (.list--flush). */
.list { --list-pad: 10px; min-width: 0; padding-bottom: var(--module-gap); }
.list--flush, .lg .list, .drawer .list, .modal .list { padding-bottom: 0; }
.list__head { display: flex; align-items: center; gap: 12px; min-height: 20px; margin-bottom: 12px; }
.list__label { min-width: 0; font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
html:lang(zh) .list__label { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.list__links { display: flex; align-items: center; gap: 16px; margin-left: auto; }
.list__rows { display: grid; margin-inline: calc(var(--list-pad) * -1); }
.list__rows > li { min-width: 0; }
.list__row {
  --inset: 0px;
  position: relative; display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; margin: 0; padding: 8px var(--list-pad);
  border: 0; border-radius: 12px; background: none; color: inherit; font: inherit; text-align: left; text-decoration: none;
  transition: background-color var(--dur-1);
}
.list__row.has-icon { --inset: 40px; }
:where(.list__row:has(> .list__icon)) { --inset: 40px; } /* :where keeps it easy to override */
.list__row.has-mark { --inset: 32px; }
.list__row.has-thumb { --inset: 56px; }
.list__rows > li + li > .list__row::before, .list__rows > .list__row + .list__row::before {
  content: ""; position: absolute; top: 0; left: calc(var(--list-pad) + var(--inset)); right: var(--list-pad); height: 1px; background: var(--rule); pointer-events: none;
}
a.list__row, button.list__row { cursor: pointer; }
a.list__row:hover, button.list__row:hover { background: var(--hover); }
a.list__row:active, button.list__row:active { background: var(--tint-2); }
a.list__row:hover::before, button.list__row:hover::before { opacity: 0; }
.list__rows > li:has(> a.list__row:hover) + li > .list__row::before, .list__rows > li:has(> button.list__row:hover) + li > .list__row::before { opacity: 0; }
.list__row:focus-visible { outline-offset: -2px; }
.list__row[aria-current="true"] { background: var(--tint-2); }
.list__row[aria-current="true"] .list__title { font-weight: 500; }
.list__icon { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--tint-2); color: var(--accent-ink); }
.list__icon .ico { width: 15px; height: 15px; }
.list__icon--ok { background: var(--ok-bg); color: var(--state-optimal); }
.list__icon--review { background: var(--rev-bg); color: var(--rev); }
.list__icon--none { background: var(--none-bg); color: var(--none); }
.list__mark { display: block; flex: none; width: 20px; height: 20px; overflow: visible; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.list__mark--ok { color: var(--state-optimal); }
.list__mark--review { color: var(--warm); }
.list__mark--none, .list__mark--untested { color: var(--text-3); }
.list__mark--untested circle { stroke-dasharray: 1.6 3.2; }
.list__thumb { display: block; flex: none; width: 44px; height: 44px; border-radius: 10px; overflow: hidden; background: var(--card-2); }
.list__thumb > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.list__thumb > .media-icon { min-height: 0; }
.list__main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; flex: 1 1 auto; min-width: 0; }
.list__title { font: 400 15px/22px var(--font-sans); color: var(--text); overflow-wrap: anywhere; }
.list__sub { font-size: 13px; line-height: 20px; color: var(--text-2); overflow-wrap: anywhere; }
html:lang(zh) .list__sub { line-height: 21px; }
.list__end { display: flex; align-items: center; flex: none; gap: 12px; margin-left: auto; }
.list__value { font: 400 15px/18px var(--font-num); letter-spacing: -0.01em; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.list__unit { margin-left: 4px; font: 400 11px/14px var(--font-num); letter-spacing: 0; color: var(--text-2); }
.list__text { font: 400 13px/20px var(--font-sans); color: var(--text-2); white-space: nowrap; }
.list__spark { display: block; flex: none; line-height: 0; }
.list__extra { display: flex; align-items: center; flex: none; gap: 12px; }
.list__extra .range { width: 120px; min-width: 0; }
.list__end .chev { flex: none; margin-right: -2px; }
.list__empty { padding: 12px 0 4px; font-size: 14px; line-height: 22px; color: var(--text-2); }
.list--dense .list__row, .list__row--dense { min-height: 44px; padding-block: 6px; }
.list--compact .list__rows { gap: 12px; }
.list--compact .list__row, .list__row--compact { min-height: 32px; padding-block: 5px; }
.list--compact .list__rows > li + li > .list__row::before, .list--compact .list__rows > .list__row + .list__row::before { display: none; }
@media (max-width: 639.98px) { .list__extra .range { display: none; } }
@media (max-width: 479.98px) { .list__spark { display: none; } }

/* ---------- Segmented control (v3) ----------
 * P.segmented() builds it. A glass track (blurred, lit from above, no outline), 32px tall (--sm 28 · --lg 36), 13px 500 labels; the
 * active segment is a white pill with a soft shadow that glides to the new item (.segmented__thumb, positioned by JS; without it
 * the active item draws its own pill). Active = aria-selected / aria-checked / aria-current / .is-active. The top bar's capsule is
 * one of these (.topnav). The older flat .seg control keeps working. */
.segmented {
  --seg-h: 32px;
  position: relative; display: inline-flex; align-items: center; flex: none; gap: 2px; max-width: 100%; height: var(--seg-h); padding: 2px;
  border-radius: var(--r-pill); background: var(--seg-track); overflow-x: auto; scrollbar-width: none;
  -webkit-backdrop-filter: blur(18px) saturate(1.8); backdrop-filter: blur(18px) saturate(1.8);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), inset 0 -6px 10px -8px var(--lg-glow), 0 10px 22px -16px var(--lg-shadow);
}
.segmented::-webkit-scrollbar { display: none; }
.segmented--sm { --seg-h: 28px; }
.segmented--lg { --seg-h: 36px; }
.segmented__item {
  position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; flex: none; gap: 6px;
  height: calc(var(--seg-h) - 4px); padding: 0 14px; border: 0; border-radius: var(--r-pill); background: transparent;
  color: var(--text-2); font: 500 13px/1 var(--font-sans); letter-spacing: 0.005em; text-decoration: none; white-space: nowrap; cursor: pointer; user-select: none;
  transition: color var(--dur-1), background-color var(--dur-1), box-shadow var(--dur-1);
}
.segmented--sm .segmented__item { padding: 0 11px; font-size: 12px; }
.segmented--lg .segmented__item { padding: 0 18px; font-size: 14px; }
.segmented__item .ico { width: 15px; height: 15px; }
.segmented__item:hover { color: var(--text); }
.segmented__item:focus-visible { outline-offset: -2px; }
.segmented__item[aria-selected="true"], .segmented__item[aria-checked="true"], .segmented__item[aria-current="page"], .segmented__item[aria-current="true"], .segmented__item.is-active {
  color: var(--text); background: var(--seg-on); box-shadow: var(--seg-pill-shadow);
}
.segmented.has-thumb > .segmented__item[aria-selected="true"], .segmented.has-thumb > .segmented__item[aria-checked="true"], .segmented.has-thumb > .segmented__item[aria-current="page"],
.segmented.has-thumb > .segmented__item[aria-current="true"], .segmented.has-thumb > .segmented__item.is-active { background: transparent; box-shadow: none; }
.segmented__thumb {
  position: absolute; left: 0; top: 0; z-index: 0; width: 0; height: 0; border-radius: var(--r-pill); background: var(--seg-on); box-shadow: var(--seg-pill-shadow);
  opacity: 0; pointer-events: none; transition: transform var(--dur-2) var(--ease-out), width var(--dur-2) var(--ease-out), height var(--dur-2) var(--ease-out);
}
.segmented.has-thumb > .segmented__thumb { opacity: 1; }

/* ---------- Small lab pieces: index numbers, status dots, quiet links ---------- */
.stat { display: grid; gap: 4px; align-content: start; }
.stat__num { font: 400 32px/1 var(--font-num); letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.stat__num small { margin-left: 4px; font: 400 12px/1 var(--font-num); letter-spacing: 0; color: var(--text-2); }
.stat__label { font-size: 13px; line-height: 20px; color: var(--text-2); }
.idx { font: 400 12px/1 var(--font-num); letter-spacing: 0; color: var(--text-3); font-variant-numeric: tabular-nums; }
.dotlabel { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; line-height: 20px; color: var(--text-2); white-space: nowrap; }
.dotlabel.is-review { color: var(--text); }
.hairlist > * + * { box-shadow: 0 -1px 0 var(--rule); }
.quiet-link { display: inline-flex; align-items: center; gap: 2px; color: var(--text-2); font: 500 13px/20px var(--font-sans); text-decoration: none; }
.quiet-link:hover { color: var(--accent-ink); }
.quiet-link .ico { width: 14px; height: 14px; }
button.quiet-link { padding: 0; border: 0; background: none; cursor: pointer; font-family: inherit; }
.card__head .quiet-link, .dsec .quiet-link { min-height: 28px; }

/* ---------- Status: one vocabulary everywhere (dots; warm only for "review") ---------- */
.tag {
  display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 2px 10px; border-radius: var(--r-pill);
  font: 500 12px/18px var(--font-sans); white-space: nowrap;
}
.tag i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.tag .ico { width: 12px; height: 12px; stroke-width: 2.2; }
.tag--ok { background: var(--ok-bg); color: var(--ok); }
.tag--ok i { background: var(--state-optimal); }
.tag--review { background: var(--rev-bg); color: var(--rev); }
.tag--review i { background: var(--warm); }
.tag--none { background: var(--none-bg); color: var(--none); }
.tag--untested { background: transparent; color: var(--none); box-shadow: inset 0 0 0 1px var(--rule-2); }
.tag--flag { background: transparent; color: var(--rev); padding-inline: 8px; box-shadow: inset 0 0 0 1px var(--warm); }
.tag--plain { background: var(--none-bg); color: var(--text-2); }
.tag--accent { background: var(--forest); color: var(--pearl); }
:root[data-theme="dark"] .tag--accent { background: var(--sage); color: var(--forest); }
.dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--state-optimal); }   /* steady */
.dot--review { background: var(--warm); }
.dot--none { background: var(--rule-2); }
.dot--empty { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-3); }

/* ---------- Range bar: the lab range and the research range on one scale ---------- */
.range { position: relative; height: 20px; min-width: 110px; }
.range__track { position: absolute; left: 0; right: 0; top: 8px; height: 4px; border-radius: 4px; background: var(--none-bg); }
.range__lab { position: absolute; top: 8px; height: 4px; border-radius: 4px; background: var(--tint-2); }
.range__opt { position: absolute; top: 8px; height: 4px; border-radius: 4px; background: linear-gradient(90deg, var(--teal-1), var(--teal-2)); }
.range__mark { position: absolute; top: 4px; width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; background: var(--text); box-shadow: 0 0 0 3px var(--bg); }
.range__mark--review { background: var(--rev-dot); }
.range__mark--none { background: var(--none); }
.range--lg { height: 28px; }
.range--lg .range__track, .range--lg .range__lab, .range--lg .range__opt { top: 11px; height: 6px; border-radius: 6px; }
.range--lg .range__mark { top: 6px; width: 16px; height: 16px; margin-left: -8px; }
.range-key { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; font: 400 12px/16px var(--font-sans); color: var(--text-2); }
.range-key > span { display: inline-flex; align-items: center; gap: 6px; }
.range-key i { width: 16px; height: 6px; border-radius: 6px; }
.range-key .k-lab { background: var(--tint-2); }
.range-key .k-opt { background: linear-gradient(90deg, var(--teal-1), var(--teal-2)); }
.range-key .k-you { width: 10px; height: 10px; border-radius: 50%; background: var(--text); }

/* ---------- Charts ----------
 * Line charts first: P.chart.line (.lc), P.chart.spark (.spark), P.chart.month (.cal); the diffuse ones: P.chart.spectrum (.spec) and
 * P.chart.gauge (.gauge). The ring, dots, bars, hist and stack charts of the first version keep working. Every number on a chart (axis
 * labels, end values, day numbers) is Plex Mono 400; the labels are muted (--text-3), the end values ink. */
.lc { display: block; width: 100%; min-width: 0; }
.lc__plot { position: relative; width: 100%; }
.lc__svg { display: block; width: 100%; overflow: visible; }
.lc__grid { stroke: var(--rule); stroke-width: 1; shape-rendering: crispEdges; }
.lc__y, .lc__x { font: 400 11px/1 var(--font-num); fill: var(--text-3); font-variant-numeric: tabular-nums; }
.lc__band-label { font: 400 11px/1 var(--font-sans); fill: var(--text-3); }
.lc__y { dominant-baseline: central; }
html:lang(zh) .lc__y, html:lang(zh) .lc__x, html:lang(zh) .lc__band-label { font-size: 12px; }
.lc__band { stroke: none; }
.lc__band--lab { fill: var(--band-lab); }
.lc__band--research { fill: var(--band-research); }
.lc__band-label { paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round; }
.lc__line { fill: none; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.lc__dot { stroke: var(--bg); stroke-width: 1; }
.lc__end { stroke: var(--bg); stroke-width: 2; }
.lc__flag { fill: var(--warm); stroke: var(--bg); stroke-width: 2; }
.lc__val { font: 400 12px/1 var(--font-num); fill: var(--text); font-variant-numeric: tabular-nums; dominant-baseline: central; }
.lc__legend { display: flex; flex-wrap: wrap; gap: 6px 20px; margin-top: 12px; }
.lc__legend li { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; line-height: 20px; color: var(--text-2); }
.lc__legend i { width: 8px; height: 8px; border-radius: 50%; }
.spark { display: block; flex: none; overflow: visible; }
.spark__line { fill: none; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.spark__end { stroke: var(--bg); stroke-width: 1.5; }
.spark__end.is-flag { fill: var(--warm); }
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); row-gap: 2px; width: 100%; }
.cal__dow { padding-bottom: 8px; text-align: center; font: 500 12px/1 var(--font-sans); color: var(--text-3); }
.cal__day, .cal__blank { display: grid; justify-items: center; align-content: start; gap: 4px; min-height: 40px; padding: 2px 0; }
button.cal__day { border: 0; border-radius: 10px; background: none; color: inherit; font: inherit; cursor: pointer; transition: background-color var(--dur-1); }
button.cal__day:hover { background: var(--hover); }
button.cal__day[aria-pressed="true"] .cal__n { background: var(--hover); }
.cal__n { display: grid; place-items: center; min-width: 26px; height: 26px; padding: 0 4px; border-radius: 13px; font: 400 13px/1 var(--font-num); letter-spacing: -0.01em; color: var(--text); font-variant-numeric: tabular-nums; }
.cal__day.is-future .cal__n { color: var(--text-2); }
.cal__day.is-before .cal__n { color: var(--text-3); opacity: 0.7; }
.cal__day.is-today .cal__n { box-shadow: inset 0 0 0 1px var(--text); }
.cal__mark { width: 6px; height: 6px; margin: 1px 0; border-radius: 50%; }
.cal__mark--full { background: var(--series-1); }
.cal__mark--part { box-shadow: inset 0 0 0 1.5px var(--series-1); }
.cal__mark--miss { width: 8px; height: 1.5px; margin: 3px 0; border-radius: 1px; background: var(--text-3); opacity: 0.5; }
.ring { position: relative; width: var(--ring, 224px); max-width: 100%; aspect-ratio: 1; flex: none; }
.ring > svg { width: 100%; height: 100%; overflow: visible; }
.ring__seg { fill: none; stroke-width: 9; stroke-linecap: round; transition: stroke-dashoffset 1100ms var(--ease-out); }
.ring__seg--ok { stroke: url(#pearTeal); }
.ring__seg--review { stroke: var(--disc); }
.ring__seg--none { stroke: var(--disc); }
.ring__seg--empty { stroke: var(--text-3); stroke-dasharray: 1 7; stroke-width: 3; opacity: 0.6; }
.ring__pin { fill: var(--text); }
.ring__pin--review { fill: var(--rev-dot); }
.ring__disc {
  position: absolute; inset: 14.5%; display: grid; place-content: center; justify-items: center; gap: 8px; border-radius: 50%; text-align: center;
  background: var(--disc); -webkit-backdrop-filter: blur(14px) saturate(1.4); backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: inset 0 0 0 1px var(--glass-hi), 0 18px 36px -22px rgba(16, 41, 31, 0.5);
}
.ring__num { font: 400 52px/0.95 var(--font-num); letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.ring__label { font: 400 13px/18px var(--font-sans); color: var(--text-2); }
.ring--sm { --ring: 132px; }
.ring--sm .ring__num { font-size: 36px; }
.ring--sm .ring__label { font-size: 12px; }
.dotsline { display: block; width: 100%; height: 56px; overflow: visible; }
.dotsline circle { fill: var(--text); }
.dotsline .is-review { fill: var(--rev-dot); }
.bars { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); align-items: end; gap: 10px; height: 136px; }
.bars__col { display: grid; grid-template-rows: 1fr auto; justify-items: center; gap: 10px; height: 100%; }
.bars__bar { align-self: end; width: min(24px, 100%); min-height: 8px; border-radius: 99px; background: linear-gradient(180deg, var(--teal-2), var(--teal-3)); transform-origin: bottom; animation: grow 700ms var(--ease-out) both; }
.bars__col.is-today .bars__bar { background: linear-gradient(180deg, var(--teal-1), var(--teal-2)); }
.bars__label { font: 400 12px/16px var(--font-sans); color: var(--text-2); }
.bars__col.is-today .bars__label { color: var(--text); font-weight: 500; }
@keyframes grow { from { transform: scaleY(0.2); opacity: 0; } }
.hist { display: block; width: 100%; height: auto; overflow: visible; }
.hist .band-lab { fill: var(--band-lab); }
.hist .band-opt { fill: var(--teal-1); opacity: 0.3; }
.hist .grid { stroke: var(--rule); stroke-width: 1; }
.hist .line { fill: none; stroke: var(--text-3); stroke-width: 1.5; }
.hist .pt { fill: var(--bg); stroke: var(--text); stroke-width: 2; }
.hist .pt.is-last { fill: var(--text); }
.hist .pt.is-review { stroke: var(--rev-dot); }
.hist .pt.is-review.is-last { fill: var(--rev-dot); }
.hist text { font: 400 11px/1 var(--font-num); fill: var(--text-3); }
.hist .val { fill: var(--text); }
.stack { display: flex; gap: 3px; height: 8px; border-radius: 8px; overflow: hidden; }
.stack > span { min-width: 6px; border-radius: 3px; }
.stack .s-ok { background: linear-gradient(90deg, var(--teal-3), var(--teal-2)); }
.stack .s-review { background: var(--rev-dot); }
.stack .s-none { background: var(--rule-2); }
.stack .s-untested { background: repeating-linear-gradient(135deg, var(--rule-2) 0 3px, transparent 3px 6px); }
.legend { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 14px; }
.legend li { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-2); }
.legend b { font: 400 15px/1 var(--font-num); color: var(--text); }
.progress { height: 4px; border-radius: 4px; background: var(--none-bg); overflow: hidden; }
.progress > span { display: block; height: 100%; width: var(--p, 0%); border-radius: inherit; background: linear-gradient(90deg, var(--teal-3), var(--teal-2)); transition: width var(--dur-3) var(--ease-out); }
.progress--low > span { background: var(--text); }

/* Diffuse charts (v4): a soft blurred colour field with crisp hairline ticks and a light Plex Mono number (P.chart.spectrum / P.chart.gauge) */
@keyframes dif-in { from { opacity: 0; } }
@keyframes spec-tick { from { transform: scaleY(0); opacity: 0; } }
@keyframes gauge-sweep { from { transform: rotate(calc(var(--v, 0) * -180deg)); } }
.spec { display: block; width: 100%; min-width: 0; }
.spec__label { margin-bottom: 8px; font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
html:lang(zh) .spec__label { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.spec__plot { position: relative; width: 100%; }
.spec__svg { display: block; width: 100%; overflow: visible; }
.spec__num { position: absolute; top: 0; z-index: 1; display: flex; align-items: baseline; gap: 3px; transform: translateX(-50%); white-space: nowrap; color: var(--text); opacity: 1; font-family: var(--font-num); font-weight: 400; pointer-events: none; }
.spec__n { font-size: 40px; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.spec__pct { font-size: 18px; line-height: 1; color: var(--text-2); }
.spec--sm .spec__n { font-size: 28px; }
.spec--sm .spec__pct { font-size: 14px; }
.spec__cap { margin-top: 16px; text-align: center; font-size: 13px; line-height: 20px; color: var(--text-2); text-wrap: balance; }
html:lang(zh) .spec__cap { line-height: 22px; }
.spec__base { stroke: var(--rule); stroke-width: 1; shape-rendering: crispEdges; }
.spec__tick { stroke-width: 1; shape-rendering: crispEdges; }
.spec__tick--ok { stroke: var(--dif-tick-ok); }
.spec__tick--review { stroke: var(--warm); }
.spec__tick--none { stroke: var(--dif-tick); }
.spec__tick--untested { stroke: var(--dif-tick); stroke-dasharray: 2 3; opacity: 0.7; }
.spec__mark { stroke: var(--dif-hand); stroke-width: 1; stroke-dasharray: 2 3; shape-rendering: crispEdges; }
.spec__dot { fill: var(--dif-hand); }
.spec__mass.is-in { animation: dif-in 900ms var(--ease-out) both; }
.spec__tick.is-in { transform-box: fill-box; transform-origin: 50% 100%; animation: spec-tick 700ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 14ms + 120ms); }
/* Numeric labels remain fully readable from the first frame; only the decorative field and ticks animate. */
.gauge { display: block; width: 100%; max-width: 420px; min-width: 0; margin-inline: auto; }
.gauge__plot { position: relative; width: 100%; }
.gauge__svg { display: block; width: 100%; height: auto; overflow: visible; }
.gauge__rest { opacity: 0.34; }
.gauge__fill { opacity: 0.66; }
.gauge__tick { stroke: var(--dif-tick); stroke-width: 1; opacity: 0.5; }
.gauge__tick.is-major { opacity: 0.75; }
.gauge__tick.is-reached { stroke: var(--dif-tick-ok); opacity: 0.9; }
.gauge__needle { stroke: var(--dif-hand); stroke-width: 1; stroke-linecap: round; opacity: 0.8; }
.gauge__pin { fill: var(--dif-hand); opacity: 0.8; }
.gauge__num { position: absolute; left: 0; right: 0; bottom: 14px; display: grid; justify-items: center; gap: 8px; text-align: center; pointer-events: none; }
.gauge__label { font: 500 12px/16px var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
html:lang(zh) .gauge__label { font-size: 13px; line-height: 18px; letter-spacing: 0.02em; text-transform: none; }
.gauge__big { display: flex; align-items: baseline; gap: 3px; font-family: var(--font-num); font-weight: 400; color: var(--text); opacity: 1; }
.gauge__n { font-size: 40px; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.gauge__pct { font-size: 18px; line-height: 1; color: var(--text-2); }
.gauge__cap { margin-top: 16px; text-align: center; font-size: 13px; line-height: 20px; color: var(--text-2); text-wrap: balance; }
html:lang(zh) .gauge__cap { line-height: 22px; }
.gauge__field.is-in { animation: dif-in 900ms var(--ease-out) both; }
.gauge__hand.is-in { animation: gauge-sweep 1100ms var(--ease-out) 150ms both; }
@media (prefers-reduced-motion: reduce) { .spec *, .gauge * { animation: none !important; } }

/* ---------- Forms ---------- */
.form { display: grid; gap: 14px; }
.form__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.field { display: grid; gap: 6px; min-width: 0; }
.field__label { font: 500 13px/20px var(--font-sans); color: var(--text-2); }
.field > .seg { justify-self: start; }
.input, .select, .textarea {
  width: 100%; min-height: 40px; padding: 9px 12px; border-radius: 10px; border: 1px solid var(--field-line); background: var(--field);
  font: 400 15px/22px var(--font-sans); color: var(--text); transition: border-color var(--dur-1), box-shadow var(--dur-1);
}
.textarea { min-height: 88px; resize: vertical; }
.select {
  appearance: none; padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237c848b' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 16px;
}
.input::placeholder, .textarea::placeholder { color: var(--text-3); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--text-3); }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--accent-ink); box-shadow: 0 0 0 3px rgba(79, 165, 154, 0.22); }
.input[aria-invalid="true"] { border-color: var(--warm); box-shadow: 0 0 0 3px rgba(224, 138, 98, 0.2); }
.field__hint { font-size: 13px; line-height: 20px; color: var(--text-2); }
.field__error { display: flex; align-items: flex-start; gap: 6px; font-size: 13px; line-height: 20px; color: var(--text); }
.field__error .ico { width: 14px; height: 14px; margin-top: 3px; color: var(--warm); }
.pw { position: relative; }
.pw .input { padding-right: 46px; }
.pw .icon-btn { position: absolute; right: 2px; top: 2px; color: var(--text-2); }
.search { position: relative; }
.search > .ico { position: absolute; left: 12px; top: 50%; margin-top: -9px; width: 18px; height: 18px; color: var(--text-3); pointer-events: none; }
.search .input { padding-left: 38px; }
@media (pointer: coarse), (max-width: 767.98px) {
  .input, .select, .textarea { font-size: 16px; } /* keeps iOS from zooming into a field */
}
.seg { display: inline-flex; max-width: 100%; padding: 3px; border-radius: var(--r-pill); background: var(--none-bg); overflow-x: auto; }
.seg button, .seg a {
  display: inline-flex; align-items: center; gap: 6px; flex: none; min-height: 30px; padding: 4px 14px; border: 0; border-radius: var(--r-pill); background: transparent;
  font: 500 13px/20px var(--font-sans); color: var(--text-2); text-decoration: none; white-space: nowrap;
}
.seg [aria-pressed="true"], .seg [aria-current="page"] { background: var(--seg-on); color: var(--accent-ink); box-shadow: 0 0 0 1px var(--rule), 0 2px 6px -2px rgba(13, 31, 25, 0.14); }
.seg--sm button { min-height: 26px; padding: 2px 11px; font-size: 12px; }
.on-dark .seg, .forest-field .seg { background: rgba(242, 244, 246, 0.1); }
.on-dark .seg button, .forest-field .seg button { color: var(--sage); }
.on-dark .seg [aria-pressed="true"], .forest-field .seg [aria-pressed="true"] { background: var(--pearl); color: var(--forest); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: 32px; padding: 5px 13px; border: 1px solid var(--rule-2); border-radius: var(--r-pill);
  background: transparent; color: var(--text); font: 500 13px/20px var(--font-sans); text-decoration: none; transition: background-color var(--dur-1), border-color var(--dur-1), color var(--dur-1);
}
.chip:hover { border-color: var(--accent-ink); }
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.chip .ico { width: 15px; height: 15px; }
.chip .count { font: 400 12px/1 var(--font-num); opacity: 0.7; }
.switch { position: relative; flex: none; width: 40px; height: 24px; border: 0; padding: 0; border-radius: 99px; background: var(--rule-2); transition: background-color var(--dur-2) var(--ease-out); }
.switch::before { content: ""; position: absolute; inset: -10px -6px; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22); transition: transform var(--dur-2) var(--ease-out); }
.switch[aria-checked="true"] { background: var(--teal-3); }
.switch[aria-checked="true"]::after { transform: translateX(16px); }
.qty { display: inline-flex; align-items: center; gap: 4px; padding: 3px; border-radius: 99px; background: var(--none-bg); }
.qty output { min-width: 28px; text-align: center; font: 400 15px/1 var(--font-num); font-variant-numeric: tabular-nums; }
.qty .icon-btn { width: 30px; height: 30px; background: var(--card); }
.qty .icon-btn .ico { width: 14px; height: 14px; }
.radio-cards { display: grid; gap: 8px; }
.radio-card {
  display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 10px 14px; border-radius: 12px; border: 1px solid var(--rule-2); background: transparent; cursor: pointer;
  text-align: left; color: inherit; font: inherit; transition: border-color var(--dur-1), background-color var(--dur-1);
}
.radio-card:hover { border-color: var(--text-3); }
.radio-card[aria-checked="true"], .radio-card[aria-pressed="true"] { border-color: var(--accent-ink); background: var(--tint); }
.scale { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.scale button { display: grid; justify-items: center; gap: 4px; min-height: 58px; padding: 8px 2px; border: 1px solid var(--rule-2); border-radius: 12px; background: transparent; color: var(--text-2); font: 400 12px/1.3 var(--font-sans); }
.scale button b { font: 400 16px/1 var(--font-num); color: var(--text); }
.scale button[aria-pressed="true"] { background: var(--tint); border-color: var(--accent-ink); color: var(--accent-ink); }

/* ---------- Shell: a floating glass top bar with ONE centred capsule; phones get a slim bar and the five bottom tabs ----------
 * Left the wordmark, centre the five destinations in a glass capsule (.topnav is a .segmented: the active one is a white pill, the
 * others muted), right the upload button, the member chip and the avatar. The bar's content sits on the same edges as the page
 * (.topbar__in is the same width as .lab). At the top of a page the bar is just the page's light
 * (nothing under it, so no band); once the page has scrolled (.is-stuck) a frosted layer fades in under it (the ::before, a
 * sibling of the capsule and the menu, so those can blur the page too) with a hairline along its foot. */
.shell { min-height: 100svh; }
.topbar { position: sticky; top: 0; z-index: 40; isolation: isolate; }
.topbar::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: var(--bar-bg); opacity: 0;
  -webkit-backdrop-filter: blur(22px); backdrop-filter: blur(22px); transition: opacity var(--dur-2) var(--ease-out);
}
.topbar.is-stuck::before { opacity: 1; box-shadow: 0 1px 0 var(--rule); }
.topbar__in {
  display: grid; grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr); align-items: center; column-gap: 24px;
  height: var(--bar-h); width: calc(100% - 2 * var(--brand-gutter)); margin-inline: auto;
}
.brand { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; justify-self: start; color: var(--accent-ink); text-decoration: none; border-radius: 8px; }
.wordmark { font: var(--wordmark-weight) var(--wordmark-size)/var(--wordmark-leading) var(--wordmark-family); letter-spacing: var(--wordmark-tracking); color: var(--wordmark-on-light); }
:root[data-theme="dark"] .topbar .wordmark { color: var(--wordmark-on-dark); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .topbar .wordmark { color: var(--wordmark-on-dark); }
}
.topnav { --seg-h: 36px; justify-self: center; overflow: visible; }
.topnav .segmented__item { padding: 0 16px; font-size: 14px; }
.topbar__end { display: flex; align-items: center; justify-self: end; gap: 14px; }
.topbar__upload { flex: none; }
.memchip { position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 2px; color: var(--text-2); font: 500 13px/1 var(--font-sans); text-decoration: none; white-space: nowrap; transition: color var(--dur-1); }
.memchip:hover, .memchip[aria-current="page"] { color: var(--text); }
.memchip .dot { width: 6px; height: 6px; background: var(--teal); }
.memchip .ico { width: 14px; height: 14px; }
.memchip__short { display: none; }
.memchip::before { content: ""; position: absolute; inset: -6px -4px; }
.acct { position: relative; }
.acct__btn {
  position: relative; display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%;
  background: var(--jelly-gloss), var(--seg-on); color: var(--accent-ink); font: 500 12px/1 var(--font-sans); cursor: pointer;
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), inset 0 -4px 8px -4px var(--lg-glow), 0 6px 14px -8px var(--lg-shadow);
}
.acct__btn::before { content: ""; position: absolute; inset: -8px; border-radius: 50%; } /* 44px hit area */
.acct__btn[aria-current="true"] { box-shadow: 0 0 0 2px var(--bg), 0 0 0 3.5px var(--accent-ink); }
.avatar { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--sage); color: var(--forest); font: 500 13px/1 var(--font-sans); text-decoration: none; }
.avatar--lg { width: 56px; height: 56px; font-size: 22px; }
.avatar--glass { background: var(--card); color: var(--accent-ink); box-shadow: 0 0 0 1px var(--rule); }
/* The account menu: a liquid-glass popover (the sample-data tag lives in its header). Concentric radii: 20 outside, 14 for the items */
.menu {
  position: absolute; z-index: 60; top: calc(100% + 12px); right: -4px; width: min(252px, calc(100vw - 24px)); padding: 6px; border-radius: 20px;
  background: var(--panel); -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), 0 28px 60px -24px var(--lg-shadow);
  animation: menu-in var(--dur-1) var(--ease-out);
}
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
.menu__head { display: grid; gap: 2px; padding: 10px 12px 12px; margin-bottom: 6px; border-bottom: 1px solid var(--rule); }
.menu__name { font: 500 15px/22px var(--font-sans); color: var(--text); }
.menu__sub { font-size: 13px; line-height: 20px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu__sample { justify-self: start; margin-top: 6px; }
.menu__item {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 36px; padding: 8px 12px; border: 0; border-radius: 14px; background: none;
  color: var(--text); font: 400 15px/22px var(--font-sans); text-align: left; text-decoration: none; cursor: pointer;
}
.menu__item .ico { width: 16px; height: 16px; color: var(--text-2); }
.menu__item:hover, .menu__item:focus-visible { background: var(--hover); }
.menu__item:focus-visible { outline-offset: -2px; }
.menu__item[aria-current="page"] { color: var(--accent-ink); font-weight: 500; }
.menu__sep { height: 1px; margin: 6px 4px; background: var(--rule); }
/* The bottom tabs (phones): the same five destinations as a floating glass capsule; the active one is the white pill */
.tabs {
  display: none; grid-template-columns: repeat(5, 1fr); gap: 2px; padding: 5px; border-radius: 30px;
  background: var(--glass-fill); -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), inset 0 -10px 20px -14px var(--lg-glow), 0 18px 40px -22px var(--lg-shadow);
}
.tabs__item {
  display: grid; justify-items: center; align-content: center; gap: 3px; min-height: 52px; padding: 6px 2px 5px; border-radius: 25px;
  color: var(--text-2); text-decoration: none; font: 500 11px/14px var(--font-sans); transition: color var(--dur-1), background-color var(--dur-1), box-shadow var(--dur-1);
}
html:lang(zh) .tabs__item { font-size: 12px; }
.tabs__item .ico { width: 22px; height: 22px; }
.tabs__item[aria-current="page"] { color: var(--text); background: var(--seg-on); box-shadow: var(--seg-pill-shadow); }
.view { animation: view-in var(--dur-2) var(--ease-out); }
@keyframes view-in { from { opacity: 0; transform: translateY(6px); } }
.page { padding-block: clamp(32px, 3.4vw, 56px) 128px; }
.page__head { display: flex; align-items: flex-end; justify-content: space-between; flex-wrap: wrap; gap: 16px 32px; margin-bottom: clamp(32px, 3.4vw, 56px); }
.page__titles { min-width: 0; }
.page__eyebrow { margin-bottom: 12px; }
.page__sub { margin-top: 8px; font-size: 15px; line-height: 22px; color: var(--text-2); }
html:lang(zh) .page__sub { line-height: 26px; }
.page__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* The first version's grid, until every screen is rebuilt on the lab grid */
.g { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 24px; align-items: stretch; }
.g > * { grid-column: span 12; }
.g > .span-3 { grid-column: span 3 !important; } .g > .span-4 { grid-column: span 4 !important; } .g > .span-5 { grid-column: span 5 !important; }
.g > .span-6 { grid-column: span 6 !important; } .g > .span-7 { grid-column: span 7 !important; } .g > .span-8 { grid-column: span 8 !important; }
.stack-y { display: grid; gap: 24px; align-content: start; min-width: 0; }
.g > * > .card { height: 100%; } /* cards in a row share one bottom edge */
.section { margin-top: 36px; }
.section__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }

@media (max-width: 1199.98px) {
  /* small laptops: the capsule's padding and the gaps tighten and the member chip takes its short label, so the capsule stays centred */
  .topbar__in { column-gap: 16px; }
  .topnav .segmented__item { padding: 0 14px; }
  .topbar__end { gap: 12px; }
  .memchip__full { display: none; }
  .memchip__short { display: inline; }
}
@media (max-width: 1023.98px) {
  /* tablets: compact paddings; in English the upload button keeps only its icon below 960px (the label would push the capsule off centre) */
  .topbar__in { column-gap: 12px; }
  .topnav .segmented__item { padding: 0 10px; font-size: 13px; }
  .topbar__end { gap: 10px; }
  .g { gap: 14px; }
  .g > [class*="span-"] { grid-column: span 12 !important; }
  .stack-y { gap: 14px; }
}
@media (max-width: 959.98px) {
  html:lang(en) .topbar__upload { width: 32px; padding: 0; }
  html:lang(en) .topbar__upload span { display: none; }
}
@media (max-width: 767.98px) {
  /* phones: a slim bar (wordmark, upload icon, avatar) and the app's five tabs as a glass capsule */
  .topbar { padding-top: env(safe-area-inset-top, 0px); }
  :root { --bar-h: 52px; }
  .topbar__in { display: flex; justify-content: space-between; column-gap: 12px; }
  .topnav, .memchip { display: none; }
  .topbar__upload { width: 32px; padding: 0; }
  .topbar__upload span { display: none; }
  .tabs { position: fixed; z-index: 40; left: 12px; right: 12px; bottom: calc(10px + env(safe-area-inset-bottom, 0px)); display: grid; }
  .page { padding-block: 24px 128px; }
  .page__head { margin-bottom: 20px; }
}
@media (min-width: 700px) and (max-width: 1023.98px) {
  .g > .span-t6 { grid-column: span 6 !important; }
}
@media (max-width: 640px) {
  .form__row { grid-template-columns: 1fr; }
}

/* ---------- Drawer (details), modal (tasks), toast: liquid glass sheets ----------
 * Translucent (--panel), blurred, lit from above, no border line: the same language as .lg. On wide screens the drawer is a
 * floating sheet 12px in from the edges; on phones it is a bottom sheet. Text inside keeps AA (--text-3 is a touch darker). */
.scrim { position: fixed; inset: 0; z-index: 70; background: var(--scrim); opacity: 0; transition: opacity var(--dur-2) var(--ease-out); }
.scrim.is-open { opacity: 1; }
.drawer, .modal, .toast { --text-3: var(--text-3-glass); }
.drawer {
  position: fixed; z-index: 80; top: 12px; right: 12px; bottom: 12px; display: flex; flex-direction: column; width: min(520px, calc(100% - 24px)); border-radius: 28px;
  background: var(--panel); -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), 0 40px 90px -34px var(--lg-shadow); transform: translateX(calc(100% + 24px));
  transition: transform var(--dur-2) var(--ease-out);
}
.drawer.is-open { transform: none; }
.drawer__head { position: relative; z-index: 2; display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 10px 12px 10px 24px; border-bottom: 1px solid var(--rule); }
.drawer__title { flex: 1; min-width: 0; font: 500 17px/24px var(--font-sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer__body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 22px 24px 40px; }
.drawer__foot { display: flex; flex-wrap: wrap; gap: 10px; padding: 14px 24px calc(14px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--rule); background: transparent; }
.drawer__foot .btn { flex: 1 1 160px; min-width: 0; }
@media (max-width: 640px) {
  .drawer { top: 6svh; right: 0; bottom: 0; width: 100%; border-radius: 28px 28px 0 0; transform: translateY(104%); }
  .drawer.is-open { transform: none; }
  .drawer__head { padding-left: 20px; }
  .drawer__body { padding: 18px 20px 32px; }
}
.modal {
  position: fixed; z-index: 80; left: 50%; top: 50%; display: flex; flex-direction: column; width: min(520px, calc(100% - 32px)); max-height: calc(100svh - 48px);
  border-radius: 28px; background: var(--panel); -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), 0 40px 90px -34px var(--lg-shadow);
  transform: translate(-50%, -47%) scale(0.98); opacity: 0; transition: transform var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out);
}
.modal.is-open { transform: translate(-50%, -50%); opacity: 1; }
.modal__head { display: flex; align-items: flex-start; gap: 12px; padding: 20px 12px 4px 24px; }
.modal__title { flex: 1; font: 500 18px/26px var(--font-sans); color: var(--text); }
html:lang(zh) .modal__title { line-height: 28px; }
.modal__body { overflow-y: auto; padding: 8px 24px; }
.modal__foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; padding: 18px 24px 22px; }
.nocase { text-transform: none; letter-spacing: 0; }
@media (max-width: 640px) {
  .modal { top: auto; bottom: 0; left: 0; width: 100%; max-height: 92svh; border-radius: 28px 28px 0 0; transform: translateY(24px); }
  .modal.is-open { transform: none; }
  .modal__head { padding: 18px 12px 4px 20px; }
  .modal__body { padding: 6px 20px; }
  .modal__foot { padding: 16px 20px calc(18px + env(safe-area-inset-bottom, 0px)); }
  .modal__foot .btn { flex: 1; }
}
.toast {
  position: fixed; z-index: 90; left: 50%; bottom: 28px; display: flex; align-items: center; gap: 10px; width: max-content; max-width: calc(100% - 32px); padding: 10px 16px; border-radius: var(--r-pill);
  background: var(--panel); color: var(--text); -webkit-backdrop-filter: var(--lg-blur); backdrop-filter: var(--lg-blur);
  box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 0 0.5px var(--lg-edge), 0 24px 50px -22px var(--lg-shadow);
  font: 500 13px/20px var(--font-sans);
  transform: translate(-50%, 14px); opacity: 0; transition: transform var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out); pointer-events: none;
}
.toast .ico { width: 16px; height: 16px; color: var(--teal); }
.toast.is-on { transform: translate(-50%, 0); opacity: 1; }
@media (max-width: 767.98px) { .toast { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); } }

/* ---------- Empty and loading ---------- */
.empty { display: grid; justify-items: center; gap: 10px; padding: 36px 16px; text-align: center; }
.empty .bubble { width: 44px; height: 44px; }
.empty .bubble .ico { width: 20px; height: 20px; }
.empty p { max-width: 34em; }
.skeleton { position: relative; overflow: hidden; border-radius: 8px; background: var(--none-bg); }
.skeleton::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent); animation: shimmer 1.2s infinite; }
@keyframes shimmer { to { transform: translateX(100%); } }


/* ---------- Brand marks ---------- */
.ne { fill: none; stroke: currentColor; stroke-width: 10; stroke-linecap: round; overflow: visible; }
.sample { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 6px; background: var(--none-bg); color: var(--text-2); font: 500 11px/16px var(--font-sans); letter-spacing: 0.06em; text-transform: uppercase; }
html:lang(zh) .sample { letter-spacing: 0.02em; font-size: 12px; }
.on-dark .sample, .forest-field .sample { background: rgba(242, 244, 246, 0.12); color: var(--sage); }

/* Reduced transparency (where the browser reports it): the glass becomes an opaque panel, the colour blooms inside cards stay */
@media (prefers-reduced-transparency: reduce) {
  .lg, .glass, .menu, .drawer, .modal, .toast, .tabs { background: var(--panel-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .segmented { background: var(--none-bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .topbar::before { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .view, .menu, .bars__bar { animation: none; }
  .scrim, .drawer, .modal, .toast { transition-duration: 0.01ms; }
  .segmented__thumb, .lg--link, .topbar::before { transition: none; }
  .lg--link:hover, .lg--link:active { transform: none; }
}

/* #main takes focus after a route change (screen readers start there); it never draws a ring round the whole page */
#main:focus, #main:focus-visible { outline: none; }
