/* ==========================================================================
   Track Anything — base.css
   Type scale · spacing · radii · shadows · liquid glass · ambient background ·
   motion · component primitives.
   Requires tokens.css (colour system) to be loaded first:
     <link rel="stylesheet" href="tokens.css"><link rel="stylesheet" href="base.css">
   Light on :root, dark under [data-theme="dark"] and under
   prefers-color-scheme: dark when no explicit theme is set.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Fonts
   Local (file://) faces for rendering; the Google Fonts equivalent is
     <link rel="preconnect" href="https://fonts.googleapis.com">
     <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght,SOFT,WONK@9..144,100..900,0..100,0..1&family=Nunito+Sans:opsz,wght@6..12,200..1000&display=swap" rel="stylesheet">
   Display = Fraunces (SOFT 100, WONK 0, optical size follows font-size).
   UI      = Nunito Sans (variable: wght 200–1000, opsz 6–12, YTLC 440–540).
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Fraunces";
  src: url("/fonts/Fraunces-VF.ttf") format("truetype");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Nunito Sans";
  src: url("/fonts/NunitoSans-VF.ttf") format("truetype");
  font-weight: 200 1000;
  font-stretch: 75% 125%;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   1. Scales (theme-independent)
   -------------------------------------------------------------------------- */
:root {
  /* families */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-ui: "Nunito Sans", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --display-axes: "SOFT" 100, "WONK" 0;

  /* type scale — sizes tuned to Nunito Sans (x-height .484 em vs Avenir Next .468):
     body 16→15.5, 14.5→14; titles 18→17.5, 15.5→15; labels stay ≥ 11.5 */
  --fs-display-l: 34px;  --lh-display-l: 1.08; --ls-display-l: -0.02em;  --fw-display: 500;
  --fs-display-m: 27px;  --lh-display-m: 1.12; --ls-display-m: -0.015em;
  --fs-display-s: 22px;  --lh-display-s: 1.2;  --ls-display-s: -0.01em;
  --fs-title-l: 17.5px;  --lh-title-l: 1.25;   --fw-title: 650;
  --fs-title-m: 15px;    --lh-title-m: 1.3;
  --fs-body-l: 15.5px;   --lh-body: 1.45;      --fw-body: 400;
  --fs-body-m: 14px;
  --fs-body-s: 12.5px;
  --fs-label: 12.5px;    --lh-label: 1.2;      --fw-label: 600;  --ls-label: 0.02em;
  --fs-label-caps: 11.5px; --fw-label-caps: 700; --ls-label-caps: 0.09em;
  --fs-numeric-l: 22px;  --fw-numeric: 600;

  /* spacing */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-7: 32px; --sp-8: 40px;

  /* radii — five canonical values + the two that sit between them */
  --r-glass: 26px;   /* glass cards, dialogs */
  --r-card: 22px;    /* cards inside glass, board columns, skeletons */
  --r-field: 18px;   /* inputs, banners, week-strip cells, snackbar */
  --r-chip: 14px;    /* chips, swatches, small tiles */
  --r-sheet: 34px;   /* bottom sheets, top corners */
  --r-pill: 999px;   /* buttons, pills, toggles */
  --r-tile: 22.37%;  /* squircle ratio for avatars / kind tiles / app icon */

  /* the dot system — one family of circles */
  --dot-1: 5px;   /* week-strip marks, nav indicator */
  --dot-2: 8px;   /* section / stage / pill dots, progress head */
  --dot-3: 12px;  /* the entry: checkbox checked, toggle knob core */
  --dot-4: 16px;  /* dot-calendar cells, rating */

  /* motion */
  --ease-soft: cubic-bezier(.2, .7, .2, 1);
  --dur-fast: 160ms;  /* taps, colour swaps */
  --dur-base: 260ms;  /* tab fade, week paging */
  --dur-slow: 420ms;  /* sheets, recolour */
  --press-scale: .975;

  /* glass geometry */
  --glass-blur: 22px;
  --glass-saturate: 1.2;
}

/* --------------------------------------------------------------------------
   2. Surface tokens that base.css adds on top of tokens.css
   (same three-state theme pattern as tokens.css)
   -------------------------------------------------------------------------- */
:root {
  --shadow-rgb: 47 36 48;
  --glass-hairline: rgb(47 36 48 / .08);
  --glass-highlight: rgb(255 255 255 / .85);
  --bg-glass-prominent: rgb(255 255 255 / .80);
  --bg-glass-pressed: rgb(255 255 255 / .72);
  --toggle-track-off: rgb(47 36 48 / .16);
  --toggle-track-on: #2F2430;      /* plum.900 — the icon tile idea: plum + rose dot */
  --snackbar-bg: #2F2430;
  --snackbar-ink: #FFF9FB;
  --snackbar-action: #F3AEC6;
  --shadow-1: 0 1px 2px rgb(var(--shadow-rgb) / .05), 0 2px 8px rgb(var(--shadow-rgb) / .05);
  --shadow-2: 0 12px 26px rgb(var(--shadow-rgb) / .08);
  --shadow-3: 0 18px 40px rgb(var(--shadow-rgb) / .16);
}
[data-theme="dark"] {
  --shadow-rgb: 0 0 0;
  --glass-hairline: rgb(255 255 255 / .10);
  --glass-highlight: rgb(255 255 255 / .09);
  --bg-glass-prominent: rgb(48 35 44 / .84);
  --bg-glass-pressed: rgb(48 35 44 / .72);
  --toggle-track-off: rgb(255 255 255 / .16);
  --toggle-track-on: #634A5B;      /* plum.600 so the rose knob keeps ≥ 3:1 */
  --snackbar-bg: #3A3040;
  --snackbar-ink: #F5EBEF;
  --snackbar-action: #F3AEC6;
  --shadow-1: 0 1px 2px rgb(0 0 0 / .25), 0 2px 8px rgb(0 0 0 / .20);
  --shadow-2: 0 12px 30px rgb(0 0 0 / .38);
  --shadow-3: 0 18px 44px rgb(0 0 0 / .5);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --shadow-rgb: 0 0 0;
    --glass-hairline: rgb(255 255 255 / .10);
    --glass-highlight: rgb(255 255 255 / .09);
    --bg-glass-prominent: rgb(48 35 44 / .84);
    --bg-glass-pressed: rgb(48 35 44 / .72);
    --toggle-track-off: rgb(255 255 255 / .16);
    --toggle-track-on: #634A5B;
    --snackbar-bg: #3A3040;
    --snackbar-ink: #F5EBEF;
    --snackbar-action: #F3AEC6;
    --shadow-1: 0 1px 2px rgb(0 0 0 / .25), 0 2px 8px rgb(0 0 0 / .20);
    --shadow-2: 0 12px 30px rgb(0 0 0 / .38);
    --shadow-3: 0 18px 44px rgb(0 0 0 / .5);
  }
}

/* --------------------------------------------------------------------------
   3. Reset-lite + base text
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg-canvas);
  color: var(--ink-primary);
  font-family: var(--font-ui);
  font-size: var(--fs-body-l);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, p, figure, ul, ol { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
svg { display: block; }
.icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.icon-s { width: 16px; height: 16px; }
.icon-l { width: 24px; height: 24px; }

/* --------------------------------------------------------------------------
   4. Type roles
   -------------------------------------------------------------------------- */
.display-l, .display-m, .display-s {
  font-family: var(--font-display);
  font-variation-settings: var(--display-axes);
  font-weight: var(--fw-display);
  font-optical-sizing: auto;
  color: var(--ink-primary);
  text-wrap: balance;
}
.display-l { font-size: var(--fs-display-l); line-height: var(--lh-display-l); letter-spacing: var(--ls-display-l); }
.display-m { font-size: var(--fs-display-m); line-height: var(--lh-display-m); letter-spacing: var(--ls-display-m); }
.display-s { font-size: var(--fs-display-s); line-height: var(--lh-display-s); letter-spacing: var(--ls-display-s); }
.title-l { font-size: var(--fs-title-l); line-height: var(--lh-title-l); font-weight: var(--fw-title); letter-spacing: -0.005em; }
.title-m { font-size: var(--fs-title-m); line-height: var(--lh-title-m); font-weight: var(--fw-title); }
.body-l { font-size: var(--fs-body-l); line-height: var(--lh-body); font-weight: var(--fw-body); }
.body-m { font-size: var(--fs-body-m); line-height: var(--lh-body); font-weight: var(--fw-body); }
.body-s { font-size: var(--fs-body-s); line-height: 1.4; font-weight: 500; }
.label { font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-label); letter-spacing: var(--ls-label); }
.label-caps, .eyebrow {
  font-size: var(--fs-label-caps); line-height: var(--lh-label); font-weight: var(--fw-label-caps);
  letter-spacing: var(--ls-label-caps); text-transform: uppercase;
}
.eyebrow { color: var(--accent-ink); }
.numeric, .numeric-l, .tabular { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.numeric { font-weight: 500; }
.numeric-l { font-size: var(--fs-numeric-l); line-height: 1.1; font-weight: var(--fw-numeric); letter-spacing: -0.01em; }
.numeric-l small { font-size: var(--fs-body-s); font-weight: 500; color: var(--ink-secondary); margin-left: 3px; letter-spacing: 0; }
.ink-2 { color: var(--ink-secondary); }
.ink-3 { color: var(--ink-secondary); } /* tertiary text still uses ink-secondary: ink-faint fails 4.5:1 on light */
/* CONTRAST RULE — --ink-faint is 3.2:1 on bg-canvas light, so it is NEVER used for readable text
   (captions, eyebrows, hints, handles, placeholders all use --ink-secondary: 6.2:1 light / 8.2:1 dark).
   --ink-faint is reserved for non-text UI: chevrons, grips, rings, dot-calendar strokes, page dots,
   progress tracks and the 10px weekday micro-labels of the dot calendar (decorative, redundant with the dates). */
.ink-accent { color: var(--accent-ink); }

/* --------------------------------------------------------------------------
   5. Motion
   -------------------------------------------------------------------------- */
.motion, .btn, .chip, .card, .glass, .toggle, .checkbox, .nav-item, .week-cell, .field input, .field textarea, .field select {
  transition-property: transform, background-color, border-color, color, box-shadow, opacity;
  transition-duration: var(--dur-fast);
  transition-timing-function: var(--ease-soft);
}
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 0ms; --dur-base: 0ms; --dur-slow: 0ms; --press-scale: 1; }
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0ms !important; scroll-behavior: auto !important; }
}

/* --------------------------------------------------------------------------
   6. Ambient background
   gradient + five soft glows from tokens (light/dark switch through the tokens)
   -------------------------------------------------------------------------- */
.ambient {
  position: relative;
  isolation: isolate;
  background-color: var(--bg-canvas);
  background-image:
    radial-gradient(460px 420px at 8% 6%,   color-mix(in srgb, var(--glow-1) 62%, transparent), transparent 70%),
    radial-gradient(520px 480px at 92% 14%, color-mix(in srgb, var(--glow-2) 58%, transparent), transparent 70%),
    radial-gradient(420px 400px at 78% 58%, color-mix(in srgb, var(--glow-3) 40%, transparent), transparent 70%),
    radial-gradient(480px 440px at 12% 70%, color-mix(in srgb, var(--glow-4) 52%, transparent), transparent 70%),
    radial-gradient(560px 520px at 55% 100%, color-mix(in srgb, var(--glow-5) 60%, transparent), transparent 70%),
    var(--ambient-gradient);
  background-repeat: no-repeat;
  background-attachment: scroll;
}
/* phone-sized variant: glows scaled to a 390-pt canvas */
.ambient-phone {
  background-image:
    radial-gradient(280px 260px at 0% 0%,    color-mix(in srgb, var(--glow-1) 62%, transparent), transparent 70%),
    radial-gradient(310px 290px at 100% 18%, color-mix(in srgb, var(--glow-2) 58%, transparent), transparent 70%),
    radial-gradient(240px 240px at 85% 56%,  color-mix(in srgb, var(--glow-3) 40%, transparent), transparent 70%),
    radial-gradient(285px 270px at 0% 74%,   color-mix(in srgb, var(--glow-4) 52%, transparent), transparent 70%),
    radial-gradient(250px 250px at 60% 100%, color-mix(in srgb, var(--glow-5) 60%, transparent), transparent 70%),
    var(--ambient-gradient);
}

/* --------------------------------------------------------------------------
   7. Liquid glass
   -------------------------------------------------------------------------- */
.glass {
  position: relative;
  background: var(--bg-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  border: 1px solid var(--glass-hairline);
  border-radius: var(--r-glass);
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--shadow-2);
}
.glass-prominent {
  position: relative;
  background: var(--bg-glass-prominent);
  -webkit-backdrop-filter: blur(28px) saturate(1.25);
  backdrop-filter: blur(28px) saturate(1.25);
  border: 1px solid var(--glass-hairline);
  border-radius: var(--r-glass);
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--shadow-3);
}
.glass-flat { box-shadow: inset 0 1px 0 var(--glass-highlight); }  /* sheets, nested */
.is-pressed.glass, .glass.is-pressed, .glass-prominent.is-pressed { transform: scale(var(--press-scale)); background: var(--bg-glass-pressed); }

/* --------------------------------------------------------------------------
   8. The dot
   -------------------------------------------------------------------------- */
.dot {
  display: inline-block; width: var(--dot-2); height: var(--dot-2);
  border-radius: 50%; background: var(--accent-dot); flex: none; vertical-align: middle;
}
.dot-1 { width: var(--dot-1); height: var(--dot-1); }
.dot-3 { width: var(--dot-3); height: var(--dot-3); }
.dot-4 { width: var(--dot-4); height: var(--dot-4); }
.dot-ring { background: transparent; border: 1.5px solid color-mix(in srgb, var(--ink-faint) 70%, transparent); }

/* --------------------------------------------------------------------------
   9. Buttons
   primary = plum pill · secondary = glass pill · tertiary = text · danger = text
   -------------------------------------------------------------------------- */
.btn {
  --btn-h: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  height: var(--btn-h); padding: 0 var(--sp-5);
  border-radius: var(--r-pill); border: 1px solid transparent;
  font-family: var(--font-ui); font-size: 15px; font-weight: 650; line-height: 1; letter-spacing: 0.005em;
  white-space: nowrap; text-decoration: none; user-select: none; -webkit-tap-highlight-color: transparent;
  transform: translateZ(0);
}
.btn-lg { --btn-h: 54px; padding: 0 var(--sp-6); font-size: 15.5px; }
.btn-sm { --btn-h: 36px; padding: 0 var(--sp-4); font-size: 13.5px; gap: 6px; }
.btn-block { width: 100%; }
.btn .icon { width: 18px; height: 18px; }
.btn-sm .icon { width: 16px; height: 16px; }

.btn-primary { background: var(--ink-primary); color: var(--ink-inverse); }
.btn-primary .dot { background: var(--accent-fill); }
.btn-primary:hover { filter: brightness(1.08); }
.btn-primary:active, .btn-primary.is-pressed { transform: scale(var(--press-scale)); filter: brightness(.94); }

.btn-secondary {
  background: var(--bg-glass-prominent); color: var(--ink-primary);
  border-color: var(--glass-hairline);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--shadow-1);
}
.btn-secondary:active, .btn-secondary.is-pressed { transform: scale(var(--press-scale)); background: var(--bg-glass-pressed); }

.btn-tertiary { background: transparent; color: var(--accent-ink); padding: 0 var(--sp-3); }
.btn-tertiary:active, .btn-tertiary.is-pressed { background: color-mix(in srgb, var(--accent-ink) 12%, transparent); transform: scale(var(--press-scale)); }
.btn-danger { background: transparent; color: var(--state-danger-ink); padding: 0 var(--sp-3); }
.btn-danger:active, .btn-danger.is-pressed { background: color-mix(in srgb, var(--state-danger-ink) 12%, transparent); }
.btn-danger-solid { background: var(--state-danger-ink); color: var(--ink-inverse); }

.btn-icon { width: var(--btn-h); padding: 0; border-radius: 50%; }
.btn-add {  /* the floating add button */
  --btn-h: 57px; width: 57px; padding: 0; border-radius: 50%;
  background: var(--ink-primary); color: var(--ink-inverse);
  box-shadow: var(--shadow-3), inset 0 1px 0 rgb(255 255 255 / .12);
}
.btn-add .icon { width: 24px; height: 24px; stroke-width: 2; }

.btn:focus-visible, .chip:focus-visible, .toggle:focus-visible, .checkbox:focus-visible, .nav-item:focus-visible,
.btn.is-focused, .chip.is-focused, .toggle.is-focused, .checkbox.is-focused {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg-canvas), 0 0 0 4px var(--accent-ink);
}
.btn:disabled, .btn.is-disabled, .chip.is-disabled, .toggle.is-disabled, .checkbox.is-disabled, .field.is-disabled {
  opacity: .42; pointer-events: none; filter: saturate(.6);
}
.btn.is-loading { color: transparent; position: relative; pointer-events: none; }
.btn.is-loading::after {
  content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--ink-inverse) 30%, transparent); border-top-color: var(--ink-inverse);
  animation: spin .8s linear infinite;
}
.btn-secondary.is-loading::after { border-color: color-mix(in srgb, var(--ink-primary) 25%, transparent); border-top-color: var(--ink-primary); }
@keyframes spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------------------------
   10. Pills / tags (kind-tinted fills with readable ink)
   -------------------------------------------------------------------------- */
.pill, .tag {
  --pill-fill: var(--bg-field); --pill-ink: var(--ink-secondary); --pill-dot: var(--ink-faint);
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 10px; border-radius: var(--r-pill);
  background: var(--pill-fill); color: var(--pill-ink);
  font-size: 12px; font-weight: 700; line-height: 1; letter-spacing: 0.01em; white-space: nowrap;
  border: 1px solid color-mix(in srgb, var(--glass-highlight) 45%, transparent);
}
.pill .dot { width: 6px; height: 6px; background: var(--pill-dot); }
.pill .icon { width: 13px; height: 13px; }
.pill-lg { height: 30px; padding: 0 12px; font-size: 13px; }
.pill-accent  { --pill-fill: var(--kind-tracker-fill); --pill-ink: var(--kind-tracker-ink); --pill-dot: var(--kind-tracker-solid); }
.pill-danger  { --pill-fill: var(--state-danger-fill); --pill-ink: var(--state-danger-ink); --pill-dot: var(--state-danger-ink); }
.pill-success { --pill-fill: var(--state-success-fill); --pill-ink: var(--state-success-ink); --pill-dot: var(--state-success-ink); }
.pill-warning { --pill-fill: var(--state-warning-fill); --pill-ink: var(--state-warning-ink); --pill-dot: var(--state-warning-ink); }
.pill-info    { --pill-fill: var(--state-info-fill); --pill-ink: var(--state-info-ink); --pill-dot: var(--state-info-ink); }
.pill-solid   { --pill-fill: var(--ink-primary); --pill-ink: var(--ink-inverse); --pill-dot: var(--accent-fill); border-color: transparent; }

/* kind modifiers — usable on .pill, .avatar, .chip, .item-card, .dot-cal, .progress */
.kind-project   { --kind-fill: var(--kind-project-fill);   --kind-ink: var(--kind-project-ink);   --kind-solid: var(--kind-project-solid); }
.kind-habit     { --kind-fill: var(--kind-habit-fill);     --kind-ink: var(--kind-habit-ink);     --kind-solid: var(--kind-habit-solid); }
.kind-task      { --kind-fill: var(--kind-task-fill);      --kind-ink: var(--kind-task-ink);      --kind-solid: var(--kind-task-solid); }
.kind-event     { --kind-fill: var(--kind-event-fill);     --kind-ink: var(--kind-event-ink);     --kind-solid: var(--kind-event-solid); }
.kind-meeting   { --kind-fill: var(--kind-meeting-fill);   --kind-ink: var(--kind-meeting-ink);   --kind-solid: var(--kind-meeting-solid); }
.kind-milestone { --kind-fill: var(--kind-milestone-fill); --kind-ink: var(--kind-milestone-ink); --kind-solid: var(--kind-milestone-solid); }
.kind-goal      { --kind-fill: var(--kind-goal-fill);      --kind-ink: var(--kind-goal-ink);      --kind-solid: var(--kind-goal-solid); }
.kind-tracker   { --kind-fill: var(--kind-tracker-fill);   --kind-ink: var(--kind-tracker-ink);   --kind-solid: var(--kind-tracker-solid); }
[class*="kind-"].pill, [class*="kind-"] .pill-kind, .pill[class*="kind-"] {
  --pill-fill: var(--kind-fill); --pill-ink: var(--kind-ink); --pill-dot: var(--kind-solid);
}

/* --------------------------------------------------------------------------
   11. Chips (one chip style: soft → plum when selected; kind shown by its dot)
   -------------------------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px;
  border-radius: var(--r-chip); border: 1px solid var(--glass-hairline);
  background: var(--bg-field); color: var(--ink-primary);
  font-size: 13.5px; font-weight: 600; line-height: 1; white-space: nowrap;
}
.chip .dot { width: var(--dot-2); height: var(--dot-2); background: var(--kind-solid, var(--ink-faint)); }
.chip .icon { width: 16px; height: 16px; }
.chip.is-selected { background: var(--ink-primary); color: var(--ink-inverse); border-color: transparent; }
.chip.is-selected .dot { background: var(--kind-solid, var(--accent-fill)); }
.chip.is-pressed { transform: scale(var(--press-scale)); }
.chip-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* --------------------------------------------------------------------------
   12. Selection controls
   -------------------------------------------------------------------------- */
/* checkbox: an empty ring → the entry dot, with the logo's halo between */
.checkbox {
  appearance: none; -webkit-appearance: none;
  display: inline-grid; place-items: center; width: 24px; height: 24px; margin: 0; flex: none;
  border-radius: 50%; border: 1.5px solid var(--border-strong);
  background: transparent; cursor: pointer; position: relative;
}
.checkbox::after {
  content: ""; width: var(--dot-3); height: var(--dot-3); border-radius: 50%;
  background: var(--accent-dot); transform: scale(0); transition: transform var(--dur-fast) var(--ease-soft);
}
.checkbox:checked, .checkbox.is-checked { border-color: var(--accent-dot); }
.checkbox:checked::after, .checkbox.is-checked::after { transform: scale(1); }
.checkbox-lg { width: 28px; height: 28px; }
.checkbox-lg::after { width: 14px; height: 14px; }

/* radio: same element, same language — use class="checkbox" on type=radio */
.radio { }

/* toggle: plum track + rose knob when on (the app-icon pairing) */
.toggle {
  appearance: none; -webkit-appearance: none;
  width: 46px; height: 28px; border-radius: var(--r-pill); margin: 0; flex: none;
  background: var(--toggle-track-off); position: relative; cursor: pointer; border: 0;
}
.toggle::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--bg-surface); box-shadow: 0 1px 3px rgb(var(--shadow-rgb) / .25);
  transition: transform var(--dur-fast) var(--ease-soft), background-color var(--dur-fast) var(--ease-soft);
}
.toggle:checked, .toggle.is-on { background: var(--toggle-track-on); }
.toggle:checked::after, .toggle.is-on::after { transform: translateX(18px); background: var(--accent-fill); }

/* rating: five dots, filled up to the value */
.rating { display: inline-flex; gap: 10px; align-items: center; }
.rating .rate {
  width: 32px; height: 32px; border-radius: 50%; border: 1.5px solid var(--border-strong);
  background: transparent; display: grid; place-items: center; padding: 0;
}
.rating .rate::after { content: ""; width: var(--dot-4); height: var(--dot-4); border-radius: 50%; background: var(--accent-dot); transform: scale(0); transition: transform var(--dur-fast) var(--ease-soft); }
.rating .rate.is-on { border-color: var(--accent-dot); }
.rating .rate.is-on::after { transform: scale(1); }

/* --------------------------------------------------------------------------
   13. Fields
   -------------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > label, .field-label { font-size: var(--fs-label); font-weight: var(--fw-label); letter-spacing: var(--ls-label); color: var(--ink-secondary); padding-left: 2px; }
.field .control {
  position: relative; display: flex; align-items: center; gap: 10px;
  min-height: 52px; padding: 0 var(--sp-4);
  border-radius: var(--r-field); border: 1px solid var(--glass-hairline);
  background: var(--bg-field); color: var(--ink-primary);
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  transition: border-color var(--dur-fast) var(--ease-soft), box-shadow var(--dur-fast) var(--ease-soft);
}
.field .control input, .field .control select, .field .control textarea {
  flex: 1; min-width: 0; border: 0; background: transparent; outline: none; padding: 0;
  font-size: var(--fs-body-l); line-height: 1.4; color: var(--ink-primary);
}
.field .control textarea { padding: 14px 0; resize: none; min-height: 92px; }
.field .control .icon { color: var(--ink-faint); }
.field .control .suffix { color: var(--ink-secondary); font-size: var(--fs-body-m); font-weight: 600; }
.field ::placeholder { color: color-mix(in srgb, var(--ink-secondary) 85%, transparent); } /* ≥ 4.5:1; reads as hint, not value */
.field.is-focused .control, .field .control:focus-within { border-color: var(--accent-ink); box-shadow: inset 0 0 0 .5px var(--accent-ink), inset 0 1px 0 var(--glass-highlight); }
.field.is-error .control { border-color: var(--state-danger-ink); box-shadow: inset 0 0 0 .5px var(--state-danger-ink); }
.field .help { font-size: var(--fs-body-s); font-weight: 500; color: var(--ink-secondary); padding-left: 2px; }
.field.is-error .help { color: var(--state-danger-ink); }
.field .control.picker { cursor: pointer; }
.field .control.picker .value { flex: 1; }
.field.is-filled .control .value { color: var(--ink-primary); }
.field .control .value.placeholder { color: color-mix(in srgb, var(--ink-secondary) 85%, transparent); }
.search.control { min-height: 48px; border-radius: var(--r-pill); }

/* --------------------------------------------------------------------------
   14. Cards
   -------------------------------------------------------------------------- */
.card { padding: var(--sp-4) 18px; border-radius: var(--r-glass); }
.card-inner { background: var(--bg-field); border: 1px solid var(--glass-hairline); border-radius: var(--r-card); padding: var(--sp-4); }
.card.is-pressed { transform: scale(var(--press-scale)); }

/* avatar / SoftIcon replacement: squircle, kind fill, kind ink */
.avatar {
  --size: 44px;
  width: var(--size); height: var(--size); border-radius: var(--r-tile); flex: none;
  display: grid; place-items: center;
  background: var(--kind-fill, var(--bg-field)); color: var(--kind-ink, var(--ink-secondary));
  border: 1px solid color-mix(in srgb, var(--glass-highlight) 60%, transparent);
}
.avatar .icon { width: calc(var(--size) * .46); height: calc(var(--size) * .46); }
.avatar-s { --size: 34px; } .avatar-m { --size: 44px; } .avatar-l { --size: 52px; } .avatar-xl { --size: 56px; }
.avatar.is-kept { background: var(--kind-solid, var(--accent-dot)); color: var(--ink-inverse); }
.avatar.is-kept.kind-tracker { background: var(--accent-dot); }
.avatar.is-kept .icon { display: none; }
.avatar.is-kept::after { content: ""; width: 38%; height: 38%; border-radius: 50%; background: var(--bg-canvas); }
.avatar.is-kept-dot { background: transparent; border-color: var(--accent-dot); }
.avatar.is-kept-dot .icon { display: none; }
.avatar.is-kept-dot::after { content: ""; width: 46%; height: 46%; border-radius: 50%; background: var(--accent-dot); }

/* item card (lists on Home / Today / Category) */
.item-card { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-radius: var(--r-card); }
.item-card .body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.item-card .title { font-size: var(--fs-title-m); font-weight: var(--fw-title); line-height: 1.3; }
.item-card .meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--fs-body-s); font-weight: 600; color: var(--ink-secondary); }
.item-card .meta .late { color: var(--state-danger-ink); font-weight: 700; }
.item-card .note { font-size: 13px; color: var(--ink-secondary); }
.item-card .chev { color: var(--ink-faint); }
.item-card.is-done .title { text-decoration: line-through; text-decoration-thickness: 1px; color: var(--ink-secondary); }
.item-card.is-done .avatar { opacity: .6; }
.item-card.is-pressed { transform: scale(var(--press-scale)); }

/* tracker card */
.tracker-card { display: flex; align-items: flex-start; gap: 14px; padding: 18px; border-radius: var(--r-glass); }
.tracker-card .body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.tracker-card .title { font-size: var(--fs-title-l); font-weight: var(--fw-title); line-height: 1.25; }
.tracker-card .desc { font-size: var(--fs-body-m); color: var(--ink-secondary); }
.tracker-card .pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.tracker-card .chev { color: var(--ink-faint); align-self: center; }
.tracker-card.is-captured .desc { color: var(--accent-ink); font-weight: 600; }

/* ritual card (Home rail) */
.ritual-card { width: 158px; min-height: 116px; padding: 14px; border-radius: var(--r-card); display: flex; flex-direction: column; justify-content: space-between; gap: 10px; }
.ritual-card .title { font-size: var(--fs-title-m); font-weight: var(--fw-title); line-height: 1.25; }
.ritual-card .rhythm { font-size: var(--fs-body-s); color: var(--ink-secondary); font-weight: 600; }

/* browse tile */
.browse-tile { position: relative; padding: 16px; min-height: 132px; border-radius: var(--r-glass); display: flex; flex-direction: column; justify-content: space-between; overflow: hidden; }
.browse-tile .top { display: flex; justify-content: space-between; align-items: flex-start; }
.browse-tile .top .icon { color: var(--ink-faint); }
.browse-tile .name { font-size: var(--fs-title-l); font-weight: var(--fw-title); }
.browse-tile .count { font-size: var(--fs-body-s); font-weight: 600; color: var(--ink-secondary); }
.browse-tile .mark { position: absolute; right: -18px; bottom: -22px; width: 96px; height: 96px; color: var(--kind-solid); opacity: .10; }
.browse-tile .mark .icon { width: 96px; height: 96px; stroke-width: 1.2; }

/* --------------------------------------------------------------------------
   15. Progress: bar with a head dot · ring of dots · sparkline end dot
   -------------------------------------------------------------------------- */
.progress { --value: 0; --progress-fill: var(--kind-solid, var(--accent-dot)); position: relative; height: 5px; border-radius: var(--r-pill); background: color-mix(in srgb, var(--ink-faint) 22%, transparent); }
.progress::before { content: ""; position: absolute; inset: 0 auto 0 0; width: calc(var(--value) * 1%); border-radius: inherit; background: var(--progress-fill); transition: width var(--dur-base) var(--ease-soft); }
.progress::after { content: ""; position: absolute; top: 50%; left: calc(var(--value) * 1%); width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; border-radius: 50%; background: var(--progress-fill); box-shadow: 0 0 0 2px var(--bg-canvas); }
.progress-row { display: flex; align-items: center; gap: 12px; }
.progress-row .progress { flex: 1; }
.progress-row .pct { font-size: var(--fs-body-s); font-weight: 700; color: var(--ink-secondary); min-width: 34px; text-align: right; }

.ring { --n: 4; --size: 76px; --ring-dot: 9px; position: relative; width: var(--size); height: var(--size); display: grid; place-items: center; flex: none; }
.ring > i { position: absolute; top: 50%; left: 50%; width: var(--ring-dot); height: var(--ring-dot); margin: calc(var(--ring-dot) / -2); border-radius: 50%;
  background: color-mix(in srgb, var(--ink-faint) 30%, transparent);
  transform: rotate(calc(var(--i) * 360deg / var(--n))) translateY(calc(var(--size) / -2 + var(--ring-dot) / 2)); }
.ring > i.on { background: var(--accent-dot); }
.ring .ring-label { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.ring .ring-label .numeric { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.ring .ring-label .body-s { color: var(--ink-secondary); font-size: 11px; }

/* --------------------------------------------------------------------------
   16. Week strip
   -------------------------------------------------------------------------- */
.week-strip { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; padding: 8px; border-radius: 24px; }
.week-cell {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 9px 0 8px;
  border-radius: var(--r-field); border: 1.5px solid transparent; cursor: pointer; background: transparent; color: var(--ink-primary);
}
.week-cell .wd { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-secondary); }
.week-cell .dn { font-size: 16px; font-weight: 650; line-height: 1; font-variant-numeric: tabular-nums; }
.week-cell .mk { width: var(--dot-1); height: var(--dot-1); border-radius: 50%; background: transparent; }
.week-cell.has-items .mk { background: var(--accent-dot); }
.week-cell.is-today { border-color: color-mix(in srgb, var(--accent-ink) 55%, transparent); }
.week-cell.is-selected { background: var(--ink-primary); color: var(--ink-inverse); border-color: var(--ink-primary); box-shadow: 0 8px 18px rgb(var(--shadow-rgb) / .18); }
.week-cell.is-selected .wd { color: color-mix(in srgb, var(--ink-inverse) 70%, transparent); }
.week-cell.is-selected.has-items .mk { background: var(--accent-fill); }
.week-cell.is-muted { opacity: .5; }

/* --------------------------------------------------------------------------
   17. Dot calendar (35 days, 7 × 5)
   -------------------------------------------------------------------------- */
.dot-cal { --cell: var(--dot-4); --gap: 10px; display: grid; grid-template-columns: repeat(7, var(--cell)); gap: var(--gap); justify-content: start; }
.dot-cal i { width: var(--cell); height: var(--cell); border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--ink-faint) 55%, transparent); background: transparent; }
.dot-cal i.on { background: var(--kind-solid, var(--accent-dot)); border-color: transparent; }
.dot-cal i.today { border-color: var(--accent-ink); border-width: 1.5px; }
.dot-cal i.today.on { box-shadow: 0 0 0 1.5px var(--bg-canvas), 0 0 0 3px var(--accent-ink); }
.dot-cal-wd { display: grid; grid-template-columns: repeat(7, var(--dot-4)); gap: 10px; margin-bottom: 8px; }
.dot-cal-wd span { font-size: 10px; font-weight: 700; letter-spacing: .04em; color: var(--ink-faint); text-align: center; text-transform: uppercase; }

/* --------------------------------------------------------------------------
   18. Navigation: glass bottom bar + floating add
   -------------------------------------------------------------------------- */
.nav-wrap { position: relative; width: 100%; padding-top: 72px; }  /* room for the floating add: 57 + 15 gap */
.nav { display: grid; grid-template-columns: repeat(4, 1fr); height: 64px; border-radius: 28px; padding: 6px; }
.nav-item {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 0; background: transparent; border-radius: var(--r-card); color: var(--ink-secondary);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.01em; cursor: pointer; position: relative;
}
.nav-item .icon { width: 21px; height: 21px; }
.nav-item .mk { width: var(--dot-1); height: var(--dot-1); border-radius: 50%; background: transparent; margin-top: 1px; }
.nav-item.is-active { color: var(--ink-primary); font-weight: 750; }
.nav-item.is-active .icon { stroke-width: 2.1; }
.nav-item.is-active .mk { background: var(--accent-dot); }
.nav-item.is-pressed { transform: scale(var(--press-scale)); background: var(--bg-glass-pressed); }
.nav-wrap .btn-add { position: absolute; right: 0; top: 0; }

/* --------------------------------------------------------------------------
   19. Sheet · dialog · snackbar · banner
   -------------------------------------------------------------------------- */
.sheet { border-radius: var(--r-sheet) var(--r-sheet) 0 0; padding: 10px 22px 22px; box-shadow: inset 0 1px 0 var(--glass-highlight); }
.sheet .handle { width: 42px; height: 5px; border-radius: 3px; background: color-mix(in srgb, var(--accent-fill) 45%, transparent); margin: 0 auto 16px; }
.sheet .sheet-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 6px; }
.sheet .sheet-sub { color: var(--ink-secondary); font-size: var(--fs-body-m); margin-bottom: 18px; }
.sheet .stack { display: flex; flex-direction: column; gap: 14px; }

.dialog { width: 320px; padding: 22px 22px 16px; border-radius: var(--r-glass); }
.dialog .display-s { margin-bottom: 8px; }
.dialog .body-m { color: var(--ink-secondary); }
.dialog .actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 16px; }

.snackbar {
  display: inline-flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 10px 0 16px;
  border-radius: var(--r-field); background: var(--snackbar-bg); color: var(--snackbar-ink);
  font-size: var(--fs-body-m); font-weight: 600; box-shadow: var(--shadow-3);
}
.snackbar .icon { width: 18px; height: 18px; }
.snackbar .act { color: var(--snackbar-action); font-weight: 750; background: transparent; border: 0; padding: 8px 10px; border-radius: var(--r-pill); }

.banner {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 8px 8px 8px 14px;
  border-radius: var(--r-field); font-size: 13px; font-weight: 600; color: var(--ink-primary);
}
.banner .icon { width: 18px; height: 18px; color: var(--accent-ink); }
.banner .text { flex: 1; }
.banner .text b { color: var(--accent-ink); font-weight: 750; }
.banner .btn-sm { --btn-h: 30px; font-size: 12.5px; padding: 0 10px; }
.banner .btn-icon { --btn-h: 30px; width: 30px; color: var(--ink-faint); border-radius: 50%; }
.banner.is-collapsed { display: inline-flex; min-height: 30px; padding: 0 12px 0 10px; border-radius: var(--r-pill); gap: 8px; font-size: 12px; }
.banner.is-collapsed .icon { width: 14px; height: 14px; }

/* --------------------------------------------------------------------------
   20. Section head · empty state · skeleton
   -------------------------------------------------------------------------- */
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 2px; }
.section-head .title-l { display: flex; align-items: center; gap: 10px; }
.section-head .title-l .dot { width: var(--dot-2); height: var(--dot-2); background: var(--kind-solid, var(--accent-dot)); }
.section-head .trail { display: flex; align-items: center; gap: 6px; }

.empty-state { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 28px 22px 24px; border-radius: var(--r-glass); }
.empty-state .avatar { margin-bottom: 6px; }
.empty-state .title-l { text-wrap: balance; }
.empty-state .body-m { color: var(--ink-secondary); max-width: 26ch; }
.empty-state .btn { margin-top: 10px; }

.skeleton { height: 74px; border-radius: var(--r-card); background: color-mix(in srgb, var(--bg-glass) 70%, transparent); border: 1px solid color-mix(in srgb, var(--accent-fill) 14%, transparent); animation: pulse 1.4s var(--ease-soft) infinite alternate; }
@keyframes pulse { from { opacity: .45; } to { opacity: .85; } }

/* --------------------------------------------------------------------------
   21. Layout helpers
   -------------------------------------------------------------------------- */
.stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.row { display: flex; align-items: center; gap: var(--sp-3); }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.phone { width: 390px; }
.hr { height: 1px; background: var(--glass-hairline); }

/* added by home-today */
/* --------------------------------------------------------------------------
   22. Phone mockup chrome + screen scaffolding (390 × 844)
   -------------------------------------------------------------------------- */
.phone-frame { position: relative; width: 390px; height: 844px; overflow: hidden; }
.status-bar { position: absolute; top: 0; left: 0; right: 0; height: 54px; z-index: 6; display: flex; align-items: center; justify-content: space-between; padding: 12px 26px 0 32px; color: var(--ink-primary); pointer-events: none; }
.status-bar .time { font-size: 15.5px; font-weight: 700; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.status-bar .glyphs { display: flex; align-items: center; gap: 6px; }
.status-bar .glyphs svg { display: block; }
.home-indicator { position: absolute; left: 50%; bottom: 8px; width: 134px; height: 5px; margin-left: -67px; border-radius: 3px; background: var(--ink-primary); opacity: .85; z-index: 6; }
.screen { position: absolute; inset: 0; padding: 54px 20px 0; overflow: hidden; }
.screen .scroll { display: flex; flex-direction: column; gap: var(--sp-6); padding-top: 10px; padding-bottom: 140px; }
.screen .scroll > section { display: flex; flex-direction: column; gap: 10px; }
.shell-nav { position: absolute; left: 16px; right: 16px; bottom: 44px; z-index: 5; width: auto; }
.status-scrim { position: absolute; top: 0; left: 0; right: 0; height: 76px; z-index: 5; pointer-events: none; -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); -webkit-mask-image: linear-gradient(#000 40%, transparent); mask-image: linear-gradient(#000 40%, transparent); background: linear-gradient(color-mix(in srgb, var(--bg-canvas) 70%, transparent), transparent); }
.hero { display: flex; flex-direction: column; gap: 8px; }
.hero .sub { color: var(--ink-secondary); font-size: var(--fs-body-m); max-width: 30ch; }
.hero-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.hero-row .eyebrow { display: block; margin-bottom: 6px; }
/* compact item card (Home lists) */
.item-card.is-compact { padding: 11px 14px; gap: 12px; }
.item-card.is-compact .avatar { --size: 38px; }
.item-card.is-compact .title { font-size: 15px; }
/* horizontal rail (rituals, templates) */
.rail { display: flex; gap: 12px; overflow: hidden; margin: 0 -20px; padding: 4px 20px 6px; }
.rail > * { flex: none; }
/* day group label on Today: eyebrow in ink-faint with an optional time */
.day-group { display: flex; align-items: baseline; justify-content: space-between; padding: 4px 4px 0; }
.day-group .eyebrow { color: var(--ink-secondary); }
.day-group .when { font-size: var(--fs-body-s); font-weight: 600; color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
/* glow card (Home daily summary): ring + headline */
.glow-card { display: flex; align-items: center; gap: 18px; padding: 16px 18px 16px 16px; }
.glow-card .title-l { margin-bottom: 3px; }
.glow-card .body-m { color: var(--ink-secondary); }

/* added by browse-track */
/* --------------------------------------------------------------------------
   Browse grid · template card · palette aliases · capture field tiles
   (phone chrome lives in the home-today / onboarding-splash blocks: .phone-frame,
   .status-bar, .screen, .shell-nav, .home-indicator, .hero, .rail; pushed-screen
   app bar is history-board's .appbar)
   -------------------------------------------------------------------------- */
/* browse grid: two columns on a 390-pt canvas; tiles compact to 112 so all eight fit above the nav */
.browse-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.browse-grid .browse-tile { min-height: 112px; padding: 14px; }
.browse-grid .browse-tile .avatar { --size: 40px; }
.browse-grid .browse-tile .mark { right: -16px; bottom: -20px; width: 84px; height: 84px; }
.browse-grid .browse-tile .mark .icon { width: 84px; height: 84px; }

/* template card (Track > Starting points), sits in a .rail */
.template-card { width: 140px; min-height: 130px; flex: none; padding: 14px; border-radius: var(--r-card); display: flex; flex-direction: column; justify-content: space-between; gap: 10px; }
.template-card .title { font-size: var(--fs-title-m); font-weight: var(--fw-title); line-height: 1.25; }
.template-card .hint { font-size: var(--fs-body-s); font-weight: 600; color: var(--ink-secondary); }
.template-card .avatar { --size: 38px; }
/* palette aliases for non-kind tints (templates, intro cards): same hue family as the kind tokens */
.tint-lavender { --kind-fill: var(--kind-habit-fill); --kind-ink: var(--kind-habit-ink); --kind-solid: var(--kind-habit-solid); }
.tint-sage     { --kind-fill: var(--kind-task-fill);  --kind-ink: var(--kind-task-ink);  --kind-solid: var(--kind-task-solid); }
.tint-peach    { --kind-fill: var(--kind-event-fill); --kind-ink: var(--kind-event-ink); --kind-solid: var(--kind-event-solid); }

/* capture: yes/no tile (a field, so it takes the field radius) · rating card · required mark */
.switch-tile { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 0 16px; border-radius: var(--r-field); border: 1px solid var(--glass-hairline); background: var(--bg-field); box-shadow: inset 0 1px 0 var(--glass-highlight); }
.switch-tile .title-m { flex: 1; }
.rating-card { padding: 14px 16px 16px; border-radius: var(--r-card); display: flex; flex-direction: column; gap: 10px; }
.rating-card .head { display: flex; align-items: center; justify-content: space-between; min-height: 28px; }
.rating-card .head .btn-sm { --btn-h: 28px; }
.req { color: var(--accent-ink); }

/* added by onboarding-splash */
/* page indicator (onboarding / board pages): plum pill for the current page, faint dots for the rest — never rose */
.page-dots { display: flex; align-items: center; justify-content: center; gap: 6px; }
.page-dots i { width: 6px; height: 6px; border-radius: var(--r-pill); background: color-mix(in srgb, var(--ink-faint) 38%, transparent); transition: width var(--dur-base) var(--ease-soft), background-color var(--dur-base) var(--ease-soft); }
.page-dots i.is-active { width: 20px; background: var(--ink-primary); }
/* kept today = the entry dot, whatever the kind's hue (the one rose dot on a dot calendar) */
.dot-cal i.today.on { background: var(--accent-dot); }
/* phone chrome for 390 × 844 mockups */
.phone-frame { position: relative; width: 390px; height: 844px; overflow: hidden; }
.status-bar { position: absolute; top: 0; left: 0; right: 0; height: 54px; display: flex; align-items: flex-end; justify-content: space-between; padding: 0 27px 9px 33px; font-size: 15.5px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink-primary); font-variant-numeric: tabular-nums; }
.status-bar .glyphs { display: flex; align-items: center; gap: 7px; color: var(--ink-primary); }
.home-indicator { position: absolute; left: 50%; bottom: 8px; width: 134px; height: 5px; margin-left: -67px; border-radius: 3px; background: var(--ink-primary); opacity: .9; }
.app-bar { position: absolute; top: 54px; left: 0; right: 0; height: 52px; display: flex; align-items: center; justify-content: center; padding: 0 16px; }
.app-bar .btn-icon { position: absolute; left: 16px; --btn-h: 40px; }
.app-bar .title { font-size: var(--fs-title-l); font-weight: var(--fw-title); }
/* the wordmark / stacked lockup as inline SVG: letters take the surface ink, the dot takes accent-dot */
.logo { color: var(--ink-primary); display: block; }
.logo svg { width: 100%; height: auto; display: block; }

/* added by history-board */
/* --------------------------------------------------------------------------
   22. App bar (pushed screens) · floating extended action
   -------------------------------------------------------------------------- */
.appbar { display: flex; align-items: center; gap: 8px; height: 52px; padding: 0 16px; }
.appbar .title-l { flex: 1; min-width: 0; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.appbar .btn-icon { --btn-h: 40px; }
.appbar .actions { display: flex; gap: 8px; }
.btn-float { box-shadow: var(--shadow-3), inset 0 1px 0 rgb(255 255 255 / .12); }

/* --------------------------------------------------------------------------
   23. Sparkline · stat trio (tracker trends)
   -------------------------------------------------------------------------- */
.sparkline { width: 100%; height: 56px; display: block; overflow: visible; }
.sparkline .line { fill: none; stroke: var(--kind-ink, var(--accent-ink)); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.sparkline .area { fill: var(--kind-solid, var(--accent-fill)); opacity: .18; }
.sparkline .end { fill: var(--accent-dot); stroke: var(--bg-canvas); stroke-width: 2; }
.sparkline .base { stroke: var(--glass-hairline); stroke-width: 1; }
.stat-trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.stat-trio .stat { display: flex; flex-direction: column; gap: 2px; }
.stat-trio .v { font-size: 16px; font-weight: 750; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; line-height: 1.2; }
.stat-trio .v small { font-size: 12px; font-weight: 600; color: var(--ink-secondary); margin-left: 2px; }
.stat-trio .k { font-size: 12px; font-weight: 600; color: var(--ink-secondary); letter-spacing: .01em; }

/* --------------------------------------------------------------------------
   24. Entry row (tracker history: date column + summary)
   -------------------------------------------------------------------------- */
.entry-row { display: flex; align-items: center; gap: 14px; padding: 12px 16px 12px 14px; border-radius: var(--r-card); }
.entry-row .date { width: 44px; flex: none; display: flex; flex-direction: column; align-items: center; gap: 0; }
.entry-row .date .mon { font-size: 10.5px; font-weight: 750; letter-spacing: .09em; text-transform: uppercase; color: var(--accent-ink); line-height: 1.2; }
.entry-row .date .day { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.entry-row .sum { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.45; color: var(--ink-secondary); }
.entry-row .sum b { color: var(--ink-primary); font-weight: 650; white-space: nowrap; }
.entry-row .vsep { width: 1px; align-self: stretch; background: var(--glass-hairline); }

/* --------------------------------------------------------------------------
   25. Board: column · task chip · drop slot
   -------------------------------------------------------------------------- */
/* .page-dots: defined by onboarding-splash (plum active pill) */
.board-col { display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: var(--r-card); border: 1.5px solid var(--glass-hairline); }
.board-col .col-head { display: flex; align-items: center; gap: 8px; padding: 2px 2px 6px 4px; }
.board-col .col-head .dot { width: var(--dot-2); height: var(--dot-2); background: var(--kind-solid, var(--accent-dot)); }
.board-col .col-head .title-m { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.board-col .col-head .btn-icon { --btn-h: 30px; color: var(--ink-faint); }
.board-col.is-hover { border-color: var(--kind-ink, var(--accent-ink)); }
.board-col .col-empty { flex: 1; display: grid; place-items: center; text-align: center; color: var(--ink-secondary); font-size: var(--fs-body-m); padding: 28px 12px; text-wrap: balance; }
.drop-slot { min-height: 62px; border-radius: var(--r-field); border: 1.5px dashed color-mix(in srgb, var(--kind-ink, var(--accent-ink)) 55%, transparent); display: grid; place-items: center; color: var(--kind-ink, var(--accent-ink)); font-size: 13px; font-weight: 650; background: color-mix(in srgb, var(--kind-fill, var(--bg-field)) 55%, transparent); }

.task-chip { display: flex; align-items: center; gap: 10px; padding: 12px 10px 12px 12px; border-radius: var(--r-field); background: var(--bg-field); border: 1px solid var(--glass-hairline); box-shadow: inset 0 1px 0 var(--glass-highlight); }
.task-chip .grip { color: var(--ink-faint); width: 14px; height: 18px; flex: none; }
.task-chip .body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.task-chip .title { font-size: var(--fs-title-m); font-weight: var(--fw-title); line-height: 1.3; }
.task-chip .meta { font-size: var(--fs-body-s); font-weight: 600; color: var(--ink-secondary); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.task-chip .btn-icon { --btn-h: 28px; color: var(--ink-faint); }
.task-chip.is-done .title { text-decoration: line-through; text-decoration-thickness: 1px; color: var(--ink-secondary); }
.task-chip.is-source { opacity: .35; }
.task-chip.is-dragging { background: var(--bg-glass-prominent); box-shadow: var(--shadow-3), inset 0 1px 0 var(--glass-highlight); transform: rotate(-1.5deg) scale(1.02); border-color: color-mix(in srgb, var(--kind-ink, var(--accent-ink)) 40%, transparent); }
.task-chip.is-dragging .grip { color: var(--kind-ink, var(--accent-ink)); }

/* --------------------------------------------------------------------------
   26. Sheet scrim · horizontal chip rail
   -------------------------------------------------------------------------- */
.scrim { position: absolute; inset: 0; background: rgb(47 36 48 / .32); }
[data-theme="dark"] .scrim { background: rgb(0 0 0 / .52); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .scrim { background: rgb(0 0 0 / .52); } }
.chip-rail { display: flex; gap: var(--sp-2); flex-wrap: nowrap; overflow: hidden; }
.chip-rail .chip { flex: none; }
.sheet .sheet-foot { padding-top: 6px; }
