/* ============================================================================
   ALL CLARK THINGS — DESIGN SYSTEM
   Warm Slate palette — espresso ink, terracotta-clay, ochre on warm linen.
   All colors flow from the tokens below — adjust :root to retheme everything.
   Secondary-text tokens (--muted, --col) are tuned to clear WCAG AA (4.5:1)
   on BOTH linen --background and --card; keep that in mind before lightening.
   ========================================================================== */

:root {
  /* Palette — Warm Slate: espresso ink + terracotta-clay accent + ochre,
     on warm linen. Adjust :root to retheme the whole dashboard. */
  --background: #faf6f1;          /* warm linen */
  --card: #fffdfa;
  --ink: #2a1d17;                 /* espresso */
  --ink-soft: #4a3a30;
  --muted: #6b5d52;               /* warm taupe — AA ~5.89:1 on linen, ~6.24:1 on card */
  --muted-strong: #574a40;        /* use for muted text <13px — AA ~7.9:1 on linen/card */
  --border: #ece3d8;
  --border-soft: hsl(28 30% 86% / 0.6); /* hairline row dividers */
  --secondary: #f0e7db;
  --secondary-hover: #e8dccb;     /* warm sand */
  --tint: 28 30% 92%;             /* warm linen tint base (h s l) */
  --on-ink: #fff;                 /* text/icon on ink + accent fills */
  --gold: #b8860b;                /* ochre, deepened for contrast on linen */
  --gold-soft: hsl(43 89% 38% / 0.12);
  /* Terracotta-clay — everything tappable */
  --accent: #9a4a23;
  --accent-deep: #7a3a19;
  --accent-soft: hsl(14 62% 37% / 0.14);

  /* Tones (semantic) */
  --pos: #4f7a2f;                 /* moss (money in) — AA ~4.69:1 on linen */
  --neg: #a3302a;                 /* brick red (money out) — kept distinct from clay accent */
  --col: #8a6308;                 /* ochre dark (warn) — AA ~5.04:1 on linen, ~5.35:1 on card */
  --util: hsl(205 35% 38%);       /* slate-pond blue */
  --inq: hsl(300 14% 44%);        /* dusty mauve */
  --act: #b8860b;

  /* Category colors (budget donut + calendar) */
  --cat-housing: hsl(200 38% 38%);
  --cat-transportation: #b7472a;
  --cat-utilities: hsl(285 18% 44%);
  --cat-food: #3f7a52;
  --cat-subscriptions: hsl(335 42% 52%); /* garden rose */
  --cat-other: #c98410;

  /* Type */
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, ui-serif, serif;

  /* Shape — iOS-scale rounding */
  --radius-sm: 0.625rem;           /* inputs / small controls — formalizes the
                                      former one-off 0.65rem so the scale is whole */
  --radius: 0.75rem;
  --radius-card: 1rem;
  --shadow: 20 25% 10%;           /* warm espresso shadow base (h s l) */
  --shadow-card: 0 1px 2px hsl(var(--shadow) / 0.04), 0 10px 30px -12px hsl(var(--shadow) / 0.1);

  /* Z-index scale (low → high): nav band < toast < lock overlay */
  --z-nav: 60;
  --z-search: 70;
  --z-toast: 100;
  --z-lock: 200;
}

/* ---- Reset / base ------------------------------------------------------- */
*, ::before, ::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--background);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
/* "The garden underneath" — a near-invisible fern-leaf scatter behind the whole
   app so the cream ground feels alive, not blank. Cards/header sit opaque on
   top; the motif only whispers through the gutters between them. Static layer,
   one paint; opacity is the single dial. Path data is a COPY of icons.js's
   "leaf" glyph (a CSS data-URI can't reference it) — edit both together. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.07;
  background-repeat: repeat;
  background-size: 300px 300px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300' viewBox='0 0 300 300' fill='none' stroke='%234a7c59' stroke-width='1.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cg transform='translate(34 46) rotate(18) scale(2.4)'%3E%3Cpath d='M13.5 2.5C6.5 2.5 2.5 6 2.5 12.5c6.5 0 10-4 11-10z'/%3E%3Cpath d='M2.5 13.5c3-4.5 6.5-7 10-8.5'/%3E%3C/g%3E%3Cg transform='translate(214 72) rotate(-42) scale(1.9)'%3E%3Cpath d='M13.5 2.5C6.5 2.5 2.5 6 2.5 12.5c6.5 0 10-4 11-10z'/%3E%3C/g%3E%3Cg transform='translate(122 158) rotate(132) scale(2.1)'%3E%3Cpath d='M13.5 2.5C6.5 2.5 2.5 6 2.5 12.5c6.5 0 10-4 11-10z'/%3E%3Cpath d='M2.5 13.5c3-4.5 6.5-7 10-8.5'/%3E%3C/g%3E%3Cg transform='translate(252 224) rotate(70) scale(1.6)'%3E%3Cpath d='M13.5 2.5C6.5 2.5 2.5 6 2.5 12.5c6.5 0 10-4 11-10z'/%3E%3C/g%3E%3Cg transform='translate(58 236) rotate(-118) scale(1.7)'%3E%3Cpath d='M13.5 2.5C6.5 2.5 2.5 6 2.5 12.5c6.5 0 10-4 11-10z'/%3E%3C/g%3E%3C/svg%3E");
}
h1, h2, h3, h4, p { margin: 0; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, select { font: inherit; color: inherit; }
table { border-collapse: collapse; }
ul { margin: 0; padding: 0; list-style: none; }
.tnum { font-variant-numeric: tabular-nums; }

/* ---- Layout ------------------------------------------------------------- */
.shell { max-width: 72rem; margin: 0 auto; padding: 0 1.25rem; }
@media (min-width: 1024px) { .shell { padding: 0 2rem; } }
main.shell { padding-top: 2rem; padding-bottom: 4rem; }
.section { margin-bottom: 2.75rem; }
.grid { display: grid; gap: 1rem; }
.cols-2 { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 640px) { .sm-cols-3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .lg-cols-4 { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 768px) { .md-cols-2 { grid-template-columns: repeat(2, 1fr); } }

/* ---- Header ------------------------------------------------------------- */
.site-header {
  position: relative;
  overflow: hidden;
  border-bottom: 0; /* the nav-band below carries the gold rule */
  background:
    radial-gradient(60% 120% at 85% 0%, hsl(38 95% 55% / 0.22), transparent 50%),
    radial-gradient(40% 90% at 10% 100%, hsl(140 30% 45% / 0.25), transparent 60%),
    var(--ink);
  color: var(--on-ink);
}
.site-header .shell { position: relative; z-index: 1; padding-top: 1.4rem; padding-bottom: 1.05rem; }

/* Ledger Currents — generative canvas behind the header text */
.header-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.85;
  pointer-events: none;
}
.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--gold);
  font-size: 12px;
  font-weight: 600;
}
.site-title {
  margin-top: 0.3rem;
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
@media (min-width: 640px) { .site-title { font-size: 34px; } }
.site-sub { margin-top: 0.375rem; font-size: 13.5px; color: hsl(0 0% 100% / 0.82); }

/* Compact header on inner tabs — the full branded header stays on the Planner
   (the landing tab); everywhere else it shrinks to reclaim above-the-fold space.
   Identity is preserved (same gradient + serif), just smaller. */
body.inner-tab .site-header .shell { padding-top: 0.7rem; padding-bottom: 0.55rem; }
body.inner-tab .eyebrow { font-size: 12px; }
body.inner-tab .site-title { font-size: 20px; margin-top: 0.15rem; }
@media (min-width: 640px) { body.inner-tab .site-title { font-size: 24px; } }

/* ---- Tabs ---------------------------------------------------------------
   The nav lives OUTSIDE the header element (its own .nav-band) so that the
   mobile fixed bar never sits inside an overflow-hidden stacking context —
   the iOS Safari combination that made it untappable. On desktop the band
   visually extends the header. */
.nav-band { background: var(--ink); border-bottom: 3px solid var(--gold); }
.nav-band .shell { padding-bottom: 1.25rem; }
.tabs {
  display: inline-flex;
  flex-wrap: nowrap;          /* one line, always — scroll past the edge, never wrap */
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;      /* app-like: the strip scrolls, the track stays hidden */
  gap: 0.25rem;
  padding: 0.25rem;
  border: 1px solid hsl(0 0% 100% / 0.15);
  background: hsl(0 0% 100% / 0.1);
  border-radius: 9999px;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  flex: none;                 /* never squish a label — overflow scrolls instead */
  border-radius: 9999px;
  padding: 0.5rem 1.25rem;
  font-size: 14px;
  font-weight: 600;
  color: hsl(0 0% 100% / 0.7);
}
.tabs button[aria-selected="true"] { background: var(--on-ink); color: var(--accent-deep); }
.tabs button .icon { display: none; } /* icons are for the phone bottom bar */
.tabs button .tab-label-sm { display: none; } /* short label is phone-bottom-bar only */
.tab-overflow-group { display: contents; } /* desktop: overflow tabs lay out inline */
.tab-more { display: none; }               /* desktop: the "More" button is phone-only */
.tab-panel[hidden] { display: none; }

/* Phone: tabs become an iOS-style bottom bar — frosted, icons + labels */
@media (max-width: 640px) {
  .nav-band { background: none; border: 0; }
  .nav-band .shell { padding: 0; }
  .site-header { border-bottom: 3px solid var(--gold); }
  .tabs {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: var(--z-nav);
    transform: translateZ(0); /* own compositor layer — reliable hit-testing */
    margin: 0;
    padding: 0.375rem 0.5rem calc(0.375rem + env(safe-area-inset-bottom, 0px));
    /* App-like: a single horizontally-scrollable strip that snaps, instead of
       6 cramped fixed columns. The active tab is centered by app.js on switch. */
    display: flex;
    gap: 0.25rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: color-mix(in srgb, var(--card) 92%, transparent);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    box-shadow: 0 -6px 24px -12px hsl(var(--shadow) / 0.25);
  }
  .tabs button {
    flex: 1 1 0;                  /* all six share the bar evenly — no hidden tabs, no scroll */
    min-width: 0;
    scroll-snap-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.125rem;
    padding: 0.375rem 0.125rem;
    border-radius: 0.75rem;
    color: var(--muted-strong);
    font-size: 12px;
    font-weight: 600;
  }
  .tabs button .tab-label { display: none; }    /* swap to the short label on phones */
  .tabs button .tab-label-sm {
    display: block; max-width: 100%;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .tabs button .icon { display: block; }
  /* Clear "you are here": a soft fern pill + deepened label, not just a tint. */
  .tabs button[aria-selected="true"] { background: var(--accent-soft); color: var(--accent-deep); }
  .tabs button[aria-selected="true"] .icon { color: var(--accent-deep); }
  body { padding-bottom: 4.5rem; } /* keep content clear of the bar */
  .toast-host { bottom: calc(4.75rem + env(safe-area-inset-bottom, 0px)); }

  /* 5 primary tabs + a "More" button; the periodic tabs (Subs, Uploads) pop up in
     a small sheet above the bar on tap. ≥44px touch targets throughout. */
  .tabs button, .tab-more { min-height: 44px; justify-content: center; }
  .tab-overflow-group { display: none; }
  .tab-more {
    display: flex; flex: 1 1 0; min-width: 0;
    flex-direction: column; align-items: center; gap: 0.125rem;
    padding: 0.375rem 0.125rem; border-radius: 0.75rem;
    color: var(--muted-strong); font-size: 12px; font-weight: 600; background: none;
  }
  .tab-more .more-dots { display: block; font-size: 17px; line-height: 0.55; letter-spacing: 1px; }
  .tab-more.active { background: var(--accent-soft); color: var(--accent-deep); }
  .tabs.show-overflow .tab-overflow-group {
    display: flex; flex-direction: column; gap: 0.25rem;
    position: fixed; right: 0.5rem;
    bottom: calc(4.75rem + env(safe-area-inset-bottom, 0px));
    min-width: 11rem; padding: 0.375rem;
    background: var(--card); border: 1px solid var(--border);
    border-radius: var(--radius-card); box-shadow: var(--shadow-card);
    z-index: calc(var(--z-nav) + 1);
  }
  .tabs.show-overflow .tab-overflow-group button {
    flex: none; flex-direction: row; justify-content: flex-start;
    gap: 0.5rem; padding: 0.65rem 0.75rem; width: 100%; min-height: 44px;
  }
  .tabs.show-overflow .tab-overflow-group .tab-label { display: block; }
  .tabs.show-overflow .tab-overflow-group .tab-label-sm { display: none; }
  .tabs.show-overflow .tab-overflow-group .icon { display: block; }
}

/* ---- Today strip ----------------------------------------------------------- */
.today-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 2rem;
}
.today-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.125rem;
  padding: 0.75rem 1rem;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.today-chip:hover { background: var(--secondary); }
/* Per-meaning signal as a small leading dot on the label, not a full-width top
   stripe — same semantic color (gold = "money due", fern = income/action,
   terracotta = debt, pond-blue = events) at a fraction of the visual area, so a
   row of chips reads calm instead of like a row of competing accents. Mirrors
   the .changes-dot vocabulary in the "since you last looked" feed. Decorative
   (non-text), so brightness over AA is fine here. */
.today-chip .stat-label { display: inline-flex; align-items: center; gap: 0.4rem; }
.today-chip .stat-label::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  flex: none; background: var(--gold);
}
.today-chip.chip-pos .stat-label::before { background: var(--pos); }
.today-chip.chip-accent .stat-label::before { background: var(--accent); }
.today-chip.chip-neg .stat-label::before { background: var(--neg); }
.today-chip.chip-util .stat-label::before { background: var(--util); }
.today-value {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  line-height: 1.1;
}
.today-sub { font-size: 12px; color: var(--muted-strong); }
.today-move {
  font-size: 13.5px;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Section headings ---------------------------------------------------- */
.section-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem; margin-bottom: 1rem; }
.rule-gold { display: inline-block; width: 2.5rem; height: 3px; border-radius: 9999px; background: var(--gold); }
.section-head h2 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
}
.kicker { font-size: 12px; color: var(--muted); }
@media (max-width: 639px) { .kicker { display: none; } }

/* ---- Cards --------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.card.pad { padding: 1.25rem; }
/* Sentence-case, lightly-tracked label. The dashboard previously set every
   stat-label in UPPERCASE; at the density they appear (each chip + every stat
   card) that read as template noise and competed with the numbers. Caps now
   stays reserved for genuinely label-like roles (the brand eyebrow, bureau
   names, tag pills). muted-strong keeps it AA at this smaller size. */
.stat-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--muted-strong);
}
.stat-value {
  margin-top: 0.5rem;
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 600;
  line-height: 1;
}
.stat-value.small-text { font-size: 16px; line-height: 1.3; }

/* Score cards */
.score-card { padding: 1.25rem; text-align: left; }
.score-bureau { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-soft); }
.score-num { font-family: var(--font-display); font-size: 44px; font-weight: 600; line-height: 1.05; }
.score-meta { margin-top: 0.25rem; font-size: 12.5px; color: var(--muted-strong); }
.score-bar { margin-top: 0.75rem; height: 6px; border-radius: 9999px; background: var(--secondary); overflow: hidden; }
.score-bar > span { display: block; height: 100%; border-radius: 9999px; background: linear-gradient(90deg, var(--gold), var(--pos)); }

/* ---- Credit hero: glanceable "where you stand + next move" ----------------- */
.credit-hero { margin-bottom: 1rem; }
.hero-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; }
.hero-head h2 { font-family: var(--font-display); font-size: 20px; font-weight: 600; margin: 0; }
.hero-grid { display: grid; grid-template-columns: minmax(0, 220px) 1fr; gap: 1.5rem; align-items: center; }
.hero-gauge { position: relative; display: flex; flex-direction: column; align-items: center; }
.gauge-arc { width: 100%; max-width: 220px; height: auto; }
.hero-gauge-num { position: absolute; top: 42%; left: 0; right: 0; text-align: center; pointer-events: none; }
.hero-gauge-num .score-num { font-size: 40px; }
.hero-gauge-cap { font-size: 12px; color: var(--muted-strong); margin-top: 0.1rem; }
.hero-gauge-range { display: flex; justify-content: space-between; width: 100%; max-width: 188px; font-size: 12px; color: var(--muted); margin-top: -0.5rem; }
.hero-side { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.hero-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.75rem; }
.hero-stat { display: flex; flex-direction: column; gap: 0.15rem; }
.hero-stat-val { font-family: var(--font-display); font-size: 24px; font-weight: 600; line-height: 1.1; }
.hero-cta { display: flex; flex-direction: column; gap: 0.15rem; text-decoration: none; color: inherit;
  background: var(--accent-soft); border: 1px solid var(--border); border-radius: var(--radius-card);
  padding: 0.75rem 0.9rem; transition: border-color 0.15s ease; }
a.hero-cta:hover, a.hero-cta:focus-visible { border-color: var(--accent); outline: none; }
.hero-cta-title { font-weight: 600; font-size: 14px; line-height: 1.35; }
.hero-cta-go { font-size: 12px; color: var(--accent); font-weight: 600; }
.hero-scores { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.75rem; margin-top: 1.25rem; }
.hero-score-card { padding: 0.85rem 1rem; }
.hero-score-card .score-num { font-size: 30px; }
.hero-firstpull { margin-top: 1rem; font-size: 12.5px; }
@media (max-width: 639px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-scores { grid-template-columns: 1fr; }
}

/* Factor matrix: ring each bureau's weakest FICO factor so the lever stands out. */
.factor-matrix td.weak .rating-pill { box-shadow: 0 0 0 2px var(--accent); font-weight: 700; }

/* Drop-off timeline: a visual age-off ladder above an always-visible (a11y) list. */
.drop-track { position: relative; height: 1.75rem; margin-top: 0.25rem; }
.drop-baseline { position: absolute; left: 0; right: 0; top: 50%; height: 2px; margin-top: -1px; background: var(--border); border-radius: 2px; }
.drop-lane { position: absolute; inset: 0; }
.drop-tick { position: absolute; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; border: 2px solid var(--card); }
.drop-tick.exact, .drop-dot.exact { background: var(--util); }
.drop-tick.ceiling, .drop-dot.ceiling { background: var(--muted); }
.drop-tick.unknown, .drop-dot.unknown { background: var(--col); }
.drop-axis { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); margin-top: 0.25rem; }
.drop-list { list-style: none; margin: 0.75rem 0 0; padding: 0; display: grid; gap: 0.4rem; }
.drop-list li { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; font-size: 13px; }
.drop-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.drop-name { font-weight: 600; }
.drop-when { font-size: 12.5px; }

/* What-if payoff slider: drag a monthly budget, watch the debt-free date move. */
.plan-slider { flex: 1; min-width: 8rem; accent-color: var(--accent); cursor: pointer; }
.plan-amount { font-weight: 600; flex: none; min-width: 4.5rem; text-align: right; }
.plan-text { flex-basis: 100%; }
.hero-debtfree { display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 0.9rem;
  font-size: 13px; font-weight: 600; color: var(--accent); text-decoration: none; }
.hero-debtfree:hover, .hero-debtfree:focus-visible { text-decoration: underline; outline: none; }
.hero-debtfree-go { color: var(--accent); }

/* "Work with Claude" nudge row — unobtrusive copy-prompt / hop-to-Uploads actions. */
.claude-bar { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0 0 1rem; }
.claude-bar-label { margin-right: 0.15rem; }

/* ---- Collapsible sections (Credit tab) ------------------------------------ */
details.sec > summary {
  list-style: none;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}
details.sec > summary::-webkit-details-marker { display: none; }
details.sec > summary .section-head { margin-bottom: 0; }
details.sec > summary .section-head h2::after {
  content: "›";
  display: inline-block;
  margin-left: 0.5rem;
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 18px;
  transition: transform 0.15s ease;
  transform: rotate(0deg);
}
details.sec[open] > summary .section-head h2::after { transform: rotate(90deg); }
details.sec > .sec-body { margin-top: 1rem; }

/* ---- Score trends ----------------------------------------------------------- */
.trend-row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.625rem; }
.spark { flex: none; }

/* ---- Cash flow (Household) ---------------------------------------------------- */
.cash-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
  background: hsl(var(--tint) / 0.45);
}
.cash-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 1.25rem;
  border-top: 1px solid var(--border-soft);
  font-size: 13px;
}
.cash-row:first-child { border-top: 0; }

/* ---- Road to 700 / payoff tracker / payment log ----------------------------- */
.paid-chk {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  align-self: center;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}
.paid-chk input { width: 1rem; height: 1rem; accent-color: var(--accent); }
.move-item .paid-chk { align-self: flex-start; }
.move-item.done h3 { text-decoration: line-through; color: var(--muted); }
.move-item.done .num-bubble { background: var(--pos); }

.debt-card { padding: 1rem 1.25rem; }
.debt-head { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; }
.debt-card h3 { font-family: var(--font-display); font-size: 16px; font-weight: 600; }

/* Compact tracker rows (TRACK layer) */
.debt-row > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  -webkit-user-select: none;
  user-select: none;
}
.debt-row > summary::-webkit-details-marker { display: none; }
.debt-row > summary::before { content: "›"; color: var(--muted); font-size: 16px; transition: transform 0.15s ease; }
.debt-row[open] > summary::before { transform: rotate(90deg); }
.debt-row > summary:hover { background: var(--secondary); }
.debt-row h3 { flex: 1; min-width: 10rem; font-family: var(--font-display); font-size: 15px; font-weight: 600; }
.debt-remaining { margin-left: auto; font-weight: 700; font-size: 15px; }
.debt-body { padding: 0.25rem 1rem 1rem; border-top: 1px dashed var(--border); }

/* Compact move rows (queued/completed Road moves) */
.move-row { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); }
.move-row > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0.75rem;
}
.move-row > summary::-webkit-details-marker { display: none; }
.move-row > summary:hover { background: var(--secondary); }
.move-row h3 { font-family: var(--font-display); font-weight: 600; }
.move-row.done h3 { text-decoration: line-through; color: var(--muted); }
.move-row-body { padding: 0.25rem 0.75rem 0.75rem 2.875rem; font-size: 13px; color: var(--ink-soft); }
.move-row-body p { margin-top: 0.25rem; }

/* Reference group */
.ref-body { padding-top: 0.5rem; }
.ref-body .section { margin-bottom: 2rem; }
.ref-body .section-head h2 { font-size: 18px; }
.debt-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0;
  margin-bottom: 0.375rem;
  border-bottom: 1px dashed var(--border);
}
a.btn { text-decoration: none; }

.pay-list { margin-top: 0.625rem; display: grid; gap: 0.25rem; }
.pay-list li { display: flex; align-items: center; gap: 0.75rem; font-size: 12.5px; padding: 0.25rem 0; border-top: 1px dashed var(--border); }

.cash-row.paid { opacity: 0.6; }
.cash-row.paid .tnum:last-child { text-decoration: line-through; }

/* ---- Tone helpers --------------------------------------------------------- */
.text-pos { color: var(--pos); } .text-neg { color: var(--neg); }
.text-col { color: var(--col); } .text-util { color: var(--util); }
.text-inq { color: var(--inq); } .text-act { color: var(--act); }
.text-late { color: var(--neg); } .text-disp { color: var(--inq); }

.badge {
  display: inline-block;
  border-radius: 9999px;
  padding: 0.125rem 0.625rem;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid;
}
.badge-pos  { color: var(--pos);  border-color: color-mix(in srgb, var(--pos) 35%, transparent); background: color-mix(in srgb, var(--pos) 9%, transparent); }
.badge-neg  { color: var(--neg);  border-color: color-mix(in srgb, var(--neg) 35%, transparent); background: color-mix(in srgb, var(--neg) 9%, transparent); }
.badge-col  { color: var(--col);  border-color: color-mix(in srgb, var(--col) 35%, transparent); background: color-mix(in srgb, var(--col) 9%, transparent); }
.badge-util { color: var(--util); border-color: color-mix(in srgb, var(--util) 35%, transparent); background: color-mix(in srgb, var(--util) 9%, transparent); }
.badge-inq  { color: var(--inq);  border-color: color-mix(in srgb, var(--inq) 35%, transparent); background: color-mix(in srgb, var(--inq) 9%, transparent); }
.badge-act  { color: var(--act);  border-color: color-mix(in srgb, var(--act) 40%, transparent); background: var(--gold-soft); }
.badge-late { color: var(--neg);  border-color: color-mix(in srgb, var(--neg) 35%, transparent); background: color-mix(in srgb, var(--neg) 9%, transparent); }
.badge-disp { color: var(--inq);  border-color: color-mix(in srgb, var(--inq) 35%, transparent); background: color-mix(in srgb, var(--inq) 9%, transparent); }
.badge-neutral { color: var(--ink-soft); border-color: var(--border); background: var(--secondary); }

/* ---- Profile toggle ------------------------------------------------------- */
.toggle-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; margin: 1.5rem 0 2rem; }
.pill-group { display: inline-flex; padding: 0.25rem; border: 1px solid var(--border); background: var(--card); border-radius: 9999px; box-shadow: var(--shadow-card); }
.pill-group button { border-radius: 9999px; padding: 0.375rem 1.25rem; font-size: 13.5px; font-weight: 600; color: var(--ink-soft); }
.pill-group button[aria-pressed="true"] { background: var(--accent); color: var(--on-ink); }
.legend { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.as-of { font-size: 12px; color: var(--muted); }

/* ---- Tables ---------------------------------------------------------------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--card); box-shadow: var(--shadow-card); }
.table-wrap + .table-wrap { margin-top: 1rem; }
.table-caption {
  padding: 0.75rem 1.25rem 0;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-soft);
}
.data-table { width: 100%; font-size: 13px; }
.data-table th {
  padding: 0.75rem 1rem;
  text-align: left;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table td { padding: 0.625rem 1rem; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
.data-table tr:last-child td { border-bottom: 0; }
.data-table td:first-child { font-weight: 600; color: var(--ink-soft); }

/* ---- Wins / plan lists ------------------------------------------------------ */
.numbered { display: grid; gap: 0.75rem; }
.numbered-item { display: flex; gap: 1rem; padding: 1rem 1.25rem; }
.num-bubble {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem;
  border-radius: 9999px;
  background: var(--ink); color: var(--on-ink);
  font-family: var(--font-display); font-size: 15px; font-weight: 600;
}
.numbered-item h3 { font-family: var(--font-display); font-size: 16px; font-weight: 600; }
.numbered-item p { margin-top: 0.25rem; font-size: 13px; color: var(--ink-soft); line-height: 1.55; max-width: 70ch; }
.tag-row { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.5rem; }

/* ---- Bureau cards (inquiries / focus) --------------------------------------- */
.bureau-card { padding: 1.25rem; }
.bureau-name { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-soft); }
.bureau-count { font-family: var(--font-display); font-size: 30px; font-weight: 600; line-height: 1.1; }
.bureau-detail { margin-top: 0.375rem; font-size: 12.5px; color: var(--muted-strong); line-height: 1.5; max-width: 60ch; }
.bureau-card ul { margin-top: 0.625rem; display: grid; gap: 0.375rem; }
.bureau-card li { position: relative; padding-left: 1rem; font-size: 13px; color: var(--ink-soft); }
.bureau-card li::before { content: ""; position: absolute; left: 0; top: 0.5em; width: 6px; height: 6px; border-radius: 9999px; background: var(--gold); }

/* ---- Ratings matrix ----------------------------------------------------------- */
.rating-pill { display: inline-block; padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 12px; font-weight: 700; }
.rating-Poor { background: color-mix(in srgb, var(--neg) 12%, transparent); color: var(--neg); }
.rating-Fair { background: color-mix(in srgb, var(--col) 12%, transparent); color: var(--col); }
.rating-Good { background: color-mix(in srgb, var(--util) 12%, transparent); color: var(--util); }
.rating-VeryGood { background: color-mix(in srgb, var(--pos) 12%, transparent); color: var(--pos); }
.rating-Exceptional { background: color-mix(in srgb, var(--pos) 20%, transparent); color: var(--pos); }

/* ---- Spotlight cards ------------------------------------------------------------ */
/* Calm note, not alarm: a hairline border + whisper of warmth lets the
   terracotta .flag label carry the "flagged" meaning (was a 35%-neg border +
   6%-neg fill that read as a red panel). */
.spotlight { padding: 1.25rem; border-color: var(--border); background: color-mix(in srgb, var(--neg) 3%, var(--card)); }
.spotlight .flag { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--neg); }
.spotlight h3 { margin-top: 0.375rem; font-family: var(--font-display); font-size: 18px; font-weight: 600; }
.spotlight p { margin-top: 0.375rem; font-size: 13px; color: var(--ink-soft); line-height: 1.55; max-width: 64ch; }
.spotlight .stats { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 0.875rem; }
.spotlight .stats b { display: block; font-family: var(--font-display); font-size: 20px; font-weight: 600; }
.spotlight .stats span { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }

/* ---- Forms ---------------------------------------------------------------------- */
.field { display: grid; gap: 0.25rem; }
.field > label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.input, select.input {
  width: 100%;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--secondary);
  padding: 0.55rem 0.8rem;
  font-size: 13.5px;
}
.input::placeholder { color: var(--muted); opacity: 1; }
.input:hover { background: var(--secondary-hover); }
.input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Native select arrow clashes with the custom field fill — swap for a marigold
   caret. Hex mirrors --gold (#c98410); a data-URI can't read a CSS var. */
select.input {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 2rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23c98410' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
}
/* keep the caret on hover — the .input:hover shorthand would otherwise wipe it */
select.input:hover { background-color: var(--secondary-hover); }
.btn {
  display: inline-flex; align-items: center; gap: 0.375rem;
  border: 1px solid var(--border);
  border-radius: 9999px;
  background: var(--card);
  padding: 0.5rem 0.875rem;
  font-size: 13px; font-weight: 600;
  color: var(--ink-soft);
}
.btn:hover { background: var(--secondary); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-ink); }
.btn-primary:hover { background: var(--accent-deep); }
.btn-danger { color: var(--neg); }
.btn-ghost { border-color: transparent; background: transparent; }
.btn-ghost:hover { background: var(--secondary); }

/* ---- Household ---------------------------------------------------------------- */
.bill-row { display: grid; grid-template-columns: 1fr; gap: 0.5rem; padding: 0.75rem 1rem; border-top: 1px solid var(--border-soft); }
.bill-row:first-child { border-top: 0; }
@media (min-width: 768px) { .bill-row { grid-template-columns: 2fr 1.2fr 1fr 0.8fr auto auto; align-items: center; } }
.summary-row { display: flex; flex-wrap: wrap; gap: 1.5rem; padding: 1rem 1.25rem; border-top: 1px solid var(--border); }
.summary-row b { display: block; font-family: var(--font-display); font-size: 20px; }
.summary-row span { font-size: 12px; font-weight: 600; letter-spacing: 0.01em; color: var(--muted-strong); }
.donut-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; }
.donut-legend { display: grid; gap: 0.375rem; font-size: 13px; }
.donut-legend .swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 0.5rem; }

/* ---- Calendar — the Planner hero --------------------------------------------
   Upcoming + Lists were retired (v0.63); the month grid now owns the Planner, so
   it's sized to fill the freed real-estate — cells grow with the viewport into a
   generous wall-calendar board instead of a cramped thumbnail. The grid already
   carries every payday/bill/event as a chip, so it is the at-a-glance view the
   Upcoming list used to duplicate. */
.cal-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 1.25rem; }
.cal-title { font-family: var(--font-display); font-size: clamp(24px, 3.2vw, 32px); font-weight: 600; letter-spacing: -0.01em; line-height: 1.05; min-width: 9ch; }
/* The board reads as the centerpiece: a touch more lift than a default card. */
.cal-board { overflow: hidden; box-shadow: 0 1px 2px hsl(var(--shadow) / 0.05), 0 18px 40px -16px hsl(var(--shadow) / 0.14); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); border-top: 1px solid var(--border); border-left: 1px solid var(--border); }
.cal-dow { padding: 0.6rem 0.5rem; text-align: center; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted-strong); border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); background: var(--secondary); }
.cal-cell { position: relative; min-height: clamp(6.5rem, 13vh, 9.5rem); padding: 0.5rem 0.5rem 0.4rem; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); font-size: 12px; cursor: pointer; vertical-align: top; transition: background 0.12s ease, transform 0.09s ease; }
.cal-cell:hover { background: var(--secondary); }
.cal-cell.dim { background: hsl(var(--tint) / 0.5); color: var(--muted); cursor: default; }
.cal-cell.today .day-num { background: var(--accent); color: var(--on-ink); }
/* Wash the whole of today's cell, not just its number, so "where am I" reads at
   a glance on the default tab. accent-soft is faint enough (~0.14) to sit under
   the cell's event chips without fighting them. */
.cal-cell.today { background: var(--accent-soft); }
.cal-cell.selected { outline: 2px solid var(--accent); outline-offset: -2px; }
.day-num { display: inline-flex; align-items: center; justify-content: center; width: 1.7rem; height: 1.7rem; border-radius: 9999px; font-size: 13.5px; font-weight: 600; }
.cal-dot { display: block; margin-top: 3px; padding: 2px 6px; border-radius: 5px; font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dot-event { background: color-mix(in srgb, var(--util) 14%, transparent); color: var(--util); }
.dot-payday { background: color-mix(in srgb, var(--pos) 14%, transparent); color: var(--pos); }
.dot-bill { background: color-mix(in srgb, var(--col) 14%, transparent); color: var(--col); }
/* "+N more" overflow tag — when a day carries more than CHIP_CAP items. Muted,
   not a colored chip, so it reads as a control rather than another event. The
   full list lives in the day editor below (tap the cell). */
.cal-more { display: block; margin-top: 3px; padding: 1px 6px; font-size: 12px; font-weight: 600; color: var(--muted-strong); }
/* Per-day item count — hidden on desktop (chips already show the load); becomes
   a corner badge on phone where chips collapse (see the small-screen block). */
.cal-count { display: none; }

/* Upcoming list */
.upcoming-row { display: flex; align-items: center; gap: 1rem; padding: 0.75rem 1.25rem; border-top: 1px solid var(--border-soft); }
.upcoming-row:first-child { border-top: 0; }
.upcoming-date { width: 3rem; flex: none; text-align: center; }
.upcoming-date .mon { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted-strong); }
.upcoming-date .day { font-family: var(--font-display); font-size: 20px; font-weight: 600; line-height: 1; }
.upcoming-bar { width: 4px; height: 2rem; flex: none; border-radius: 9999px; }

/* ---- Lists ---------------------------------------------------------------------- */
.list-card { display: flex; flex-direction: column; }
.list-head { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; border-bottom: 1px solid var(--border); }
.list-head input { flex: 1; min-width: 0; border: 0; background: transparent; padding: 0.125rem 0.25rem; border-radius: 4px; font-family: var(--font-display); font-size: 16px; font-weight: 600; }
.list-head input:focus { outline: 2px solid var(--accent); outline-offset: 1px; background: var(--accent-soft); }
.list-progress { flex: none; border-radius: 9999px; background: var(--secondary); padding: 0.125rem 0.5rem; font-size: 12px; font-weight: 600; color: var(--ink-soft); }
.list-items { padding: 0.5rem 0.75rem; display: grid; gap: 0.125rem; }
.list-item { display: flex; align-items: center; gap: 0.625rem; padding: 0.375rem 0.25rem; border-radius: var(--radius); }
.list-item:hover { background: var(--secondary); }
.list-item input[type="checkbox"] { width: 1rem; height: 1rem; accent-color: var(--accent); }
.list-item .txt { flex: 1; font-size: 13.5px; }
.list-item.done .txt { text-decoration: line-through; color: var(--muted); }
.list-item .del { opacity: 0; padding: 0.25rem; border-radius: 9999px; line-height: 1; font-size: 12px; color: var(--neg); }
.list-item:hover .del { opacity: 1; }
.list-add { display: flex; gap: 0.5rem; padding: 0.625rem 1rem 1rem; }

/* ---- Footer / data tools ----------------------------------------------------------- */
.disclaimer {
  margin-top: 3rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-card);
  background: var(--card);
  padding: 1rem 1.25rem;
  font-size: 12.5px;
  color: var(--muted-strong);
  max-width: 72ch;            /* cap prose line length (was running ~180ch wide) */
}
.site-footer { border-top: 1px solid var(--border); background: var(--card); }
.site-footer .shell { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; padding: 1.5rem 1.25rem; }
.footer-note { font-size: 12.5px; color: var(--muted); }
.footer-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem; }

/* Settings & data fold — collapses the footer's data tools into one calm entry
   point. A plain <details> (matches the app's other folds), so it expands
   inline with no positioned dropdown to clip. */
.settings-fold > summary { list-style: none; -webkit-user-select: none; user-select: none; }
.settings-fold > summary::-webkit-details-marker { display: none; }
.settings-fold > summary::after {
  content: "›"; color: var(--muted); font-size: 15px; line-height: 1;
  transition: transform 0.15s ease;
}
.settings-fold[open] > summary::after { transform: rotate(90deg); }
.settings-menu {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-top: 0.6rem; padding: 0.85rem;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--secondary); animation: reveal 0.22s ease;
}
.settings-danger {
  flex-basis: 100%;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
  margin-top: 0.35rem; padding-top: 0.7rem;
  border-top: 1px dashed var(--border);
}
.settings-danger-note { flex: 1; min-width: 12rem; font-size: 12px; color: var(--muted-strong); }
/* Armed reset turns solid terracotta — unmistakable "next tap erases". */
.btn-danger.armed { background: var(--neg); border-color: var(--neg); color: var(--on-ink); }

/* ---- Motion & depth (visual polish pass) --------------------------------------------
   Subtle, fast, and fully disabled for reduced-motion users. */
.card, .today-chip, .table-wrap { transition: box-shadow 0.18s ease, transform 0.18s ease; }
.today-chip:hover { transform: translateY(-1px); box-shadow: 0 2px 4px hsl(var(--shadow) / 0.06), 0 14px 34px -14px hsl(var(--shadow) / 0.18); }
.btn { transition: background 0.15s ease, transform 0.1s ease; }
.btn:active { transform: scale(0.97); }
.sec-body, .debt-body, .move-row-body { animation: reveal 0.22s ease; }
@keyframes reveal {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: none; }
}
.score-bar > span { transition: width 0.4s ease; }
/* Hover depth on cards — shadow only (no lift) so large info panels stay calm
   while gaining a sense of focus under the pointer. */
.card:hover { box-shadow: 0 2px 6px hsl(var(--shadow) / 0.06), 0 18px 42px -18px hsl(var(--shadow) / 0.16); }
/* Entrance choreography — staggered reveal of a freshly switched tab's top
   blocks. Index (--enter-i) is set in app.js choreograph(); scoped to
   no-preference so the reduce kill-switch below never strands a block hidden. */
@media (prefers-reduced-motion: no-preference) {
  .ct-enter {
    animation: ct-enter 0.44s cubic-bezier(0.22, 0.7, 0.2, 1) both;
    animation-delay: calc(var(--enter-i, 0) * 45ms);
  }
  /* Tactile press — a subtle squish answers every tap on a card-like surface.
     Buttons already squish via their own :active; this covers the rest. Scoped
     to no-preference so the reduce kill-switch leaves them perfectly still. */
  .today-chip, .account-card, .search-hit { transition: transform 0.09s ease; }
  .cal-cell:active, .today-chip:active, .account-card:active, .search-hit:active { transform: scale(0.985); }
}
@keyframes ct-enter {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}
/* uPlot chart shell + hover tooltip (Util.lineChart) */
.uchart { position: relative; }
.uchart-tip {
  position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.4rem 0.55rem;
  box-shadow: var(--shadow-card); font-size: 12px; line-height: 1.5;
  transition: opacity 0.12s ease; z-index: 5; white-space: nowrap;
}
.uchart-tip .t-x {
  font-size: 12px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.15rem;
}
.uchart-tip .t-row { display: flex; align-items: center; gap: 0.4rem; }
.uchart-tip .t-dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; flex: none; }
.uchart-tip .t-lab { color: var(--ink-soft); }
.uchart-tip .t-row b { margin-left: auto; font-family: var(--font-display); font-variant-numeric: tabular-nums; }
/* Skylight feed status chip (footer) */
.sky-status { display: inline-flex; align-items: center; gap: 0.35rem; }
.sky-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; }
.sky-dot.sky-pos { background: var(--pos); box-shadow: 0 0 0 3px var(--accent-soft); }
.sky-dot.sky-col { background: var(--col); }
.sky-dot.sky-util { background: var(--util); }
/* Household sync-status chip (footer) — same shape as the Skylight chip; shows
   whether your edits have propagated to the family's other devices. */
.sync-status { display: inline-flex; align-items: center; gap: 0.35rem; }
.sync-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; }
.sync-dot.sync-saved { background: var(--pos); box-shadow: 0 0 0 3px var(--accent-soft); }
.sync-dot.sync-syncing { background: var(--util); }
.sync-dot.sync-offline { background: var(--col); }
/* Skeleton shimmer (Util.skeleton) — reserves a heavy widget's space while it
   initializes, or stands in when its library is unavailable. */
.skeleton { border-radius: var(--radius); background: linear-gradient(100deg, var(--secondary) 30%, var(--secondary-hover) 50%, var(--secondary) 70%); background-size: 200% 100%; }
@media (prefers-reduced-motion: no-preference) {
  .sync-dot.sync-syncing { animation: sync-pulse 1s ease-in-out infinite; }
  .skeleton { animation: skeleton-shimmer 1.3s ease-in-out infinite; }
}
@keyframes sync-pulse { 50% { opacity: 0.3; } }
@keyframes skeleton-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.sky-dot.sky-muted { background: var(--muted); }

/* Skylight connection graphic — "the garden wire" (Calendar tab, v35).
   Leaf node (this dashboard) → dotted wire with flowing seed-packets →
   Skylight frame node. State (live / ready / off) comes from /api/skylight/status.
   Motion IS the push; the global reduced-motion rule below freezes the packets
   (they default to opacity:0) leaving a static fern dotted wire = still connected. */
.sky-link { display: flex; flex-direction: column; gap: 0.55rem; padding: 0.7rem 0.9rem;
  margin-bottom: 0.85rem; border: 1px solid var(--border); border-radius: var(--radius-card);
  background: var(--card); cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.12s; }
.sky-link:hover { box-shadow: var(--shadow-card); border-color: var(--secondary-hover); }
.sky-link:active { transform: translateY(1px); }
.sky-link--off { cursor: default; }
.sky-link--off:hover { box-shadow: none; border-color: var(--border); }

.sky-rail { display: flex; align-items: center; gap: 0.6rem; }
.sky-node { width: 2rem; height: 2rem; flex: none; display: grid; place-items: center;
  border-radius: 50%; background: var(--secondary); color: var(--muted); position: relative;
  transition: color 0.25s, background 0.25s, box-shadow 0.25s; }
.sky-wire { position: relative; flex: 1 1 auto; height: 2px; color: var(--border);
  background-image: radial-gradient(circle, currentColor 0 1px, transparent 1.4px);
  background-size: 7px 2px; background-repeat: repeat-x; background-position: center;
  transition: color 0.25s; }
.sky-pkt { position: absolute; top: 50%; left: 0; width: 6px; height: 6px; margin-top: -3px;
  border-radius: 50%; background: var(--accent); opacity: 0; will-change: left, opacity, transform; }
.sky-live-badge { position: absolute; right: -3px; bottom: -3px; width: 14px; height: 14px;
  display: grid; place-items: center; border-radius: 50%; background: var(--card); color: var(--accent); }

.sky-meta { display: flex; align-items: center; gap: 0.45rem; font-size: 12.5px; }
.sky-tag { flex: none; font-size: 12px; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; padding: 0.1rem 0.42rem; border-radius: 999px;
  background: var(--secondary); color: var(--muted); }
.sky-meta-text { color: var(--muted-strong); }

.sky-link--live .sky-wire { color: var(--accent); }
.sky-link--live .sky-node--src { color: var(--accent-deep); background: var(--accent-soft); }
.sky-link--live .sky-node--dst { color: var(--on-ink); background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-soft); animation: skyHalo 2.4s ease-out infinite; }
.sky-link--live .sky-tag { background: var(--accent-soft); color: var(--accent-deep); }
.sky-link--live .sky-pkt { animation: skyFlow 1.9s linear infinite; }
.sky-link--live .sky-pkt:nth-child(2) { animation-delay: 0.63s; }
.sky-link--live .sky-pkt:nth-child(3) { animation-delay: 1.26s; }

.sky-link--ready .sky-wire { color: var(--gold); }
.sky-link--ready .sky-node--src, .sky-link--ready .sky-node--dst { color: var(--col); background: var(--gold-soft); }
.sky-link--ready .sky-tag { background: var(--gold-soft); color: var(--col); }

/* Self-service subscribe-URL row (revealed under the connection panel when a
   feed is published) — copy-paste the Calendar URL into the Skylight app. */
.sky-copy { margin: -0.35rem 0 0.95rem; display: flex; flex-direction: column; gap: 0.4rem; }
.sky-copy-label { font-size: 12px; color: var(--muted); }
.sky-copy-row { display: flex; gap: 0.45rem; align-items: center; }
.sky-copy-url { flex: 1 1 auto; min-width: 0; font-size: 12px; font-family: var(--mono, monospace); }

@keyframes skyFlow {
  0%   { left: 6%;  opacity: 0; transform: scale(0.5); }
  18%  { opacity: 1; transform: scale(1); }
  82%  { opacity: 1; transform: scale(1); }
  100% { left: 94%; opacity: 0; transform: scale(0.5); }
}
@keyframes skyHalo {
  0%   { box-shadow: 0 0 0 0 var(--accent-soft); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after { animation: none !important; transition: none !important; }
}

/* Score cards get a touch more presence */
.score-card { position: relative; overflow: hidden; }
.score-card::after {
  content: "";
  position: absolute;
  top: 0; right: 0;
  width: 38%; height: 3px;
  background: linear-gradient(90deg, transparent, var(--gold));
}
.num-bubble { box-shadow: inset 0 -2px 0 hsl(0 0% 0% / 0.18); }
.cash-head { background: linear-gradient(180deg, hsl(var(--tint) / 0.65), hsl(var(--tint) / 0.3)); }

/* ---- Subscriptions ---------------------------------------------------------------------- */
.sub-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  border-top: 1px solid var(--border-soft);
}
.sub-row:first-of-type { border-top: 0; }
.sub-row.canceled { opacity: 0.5; }
.sub-row.canceled input:first-child { text-decoration: line-through; }
select.status-keep { color: var(--pos); font-weight: 600; }
select.status-review { color: var(--col); font-weight: 600; }
select.status-cancel { color: var(--neg); font-weight: 600; }
select.status-canceled { color: var(--muted); }

/* ---- Icons & toasts (premium pass) --------------------------------------------------- */
.icon { flex: none; vertical-align: -2px; }
.btn .icon { margin-right: 0.1rem; }
.icon-row { display: inline-flex; align-items: center; gap: 0.375rem; }
.icon-row .icon { color: var(--col); }

/* Category glyphs (Util.catIconEl) — leading icon on category headers & rows.
   Tone comes from an inline color set per category; the svg inherits it. */
.cat-ico { display: inline-flex; align-items: center; flex: none; }
.cat-ico .icon { color: inherit; vertical-align: -2px; }
.cat-head { display: inline-flex; align-items: center; gap: 0.4rem; }
.bill-name { display: flex; align-items: center; gap: 0.45rem; min-width: 0; }
.bill-name input { flex: 1; min-width: 0; }

.toast-host {
  position: fixed;
  bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: grid;
  gap: 0.5rem;
  justify-items: center;
  pointer-events: none;
}
.toast {
  background: color-mix(in srgb, var(--ink) 93%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--background);
  border-radius: 9999px;
  padding: 0.625rem 1.25rem;
  font-size: 13px;
  font-weight: 500;
  box-shadow: 0 6px 24px -8px hsl(var(--shadow) / 0.45);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  max-width: min(90vw, 26rem);
}
.toast.show { opacity: 1; transform: none; }

/* ---- Payoff planner row ------------------------------------------------------------------ */
.planner-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border);
}

/* ---- PIN lock --------------------------------------------------------------------------- */
.lock-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-lock);
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(60% 120% at 85% 0%, hsl(38 95% 55% / 0.25), transparent 45%),
    var(--ink);
}
.lock-card {
  display: grid;
  gap: 0.875rem;
  justify-items: center;
  text-align: center;
  padding: 2.5rem 3rem;
}
.lock-title { font-family: var(--font-display); font-size: 30px; font-weight: 600; color: var(--background); }
.lock-input {
  width: 11rem;
  text-align: center;
  letter-spacing: 0.5em;
  font-size: 22px;
  padding: 0.5rem 0 0.5rem 0.5em;
  background: hsl(0 0% 100% / 0.08);
  border: 1px solid hsl(0 0% 100% / 0.25);
  border-radius: var(--radius);
  color: var(--on-ink);
}
.lock-input:focus { outline: 2px solid var(--gold); } /* fern reads too dark on the ink lock ground */
.lock-btn {
  background: var(--accent);
  color: var(--on-ink);
  font-weight: 700;
  font-size: 14px;
  padding: 0.5rem 2.25rem;
  border-radius: 9999px;
}
.lock-msg { min-height: 1.25rem; font-size: 12.5px; color: hsl(38 80% 70%); }
.lock-card.shake { animation: shake 0.3s ease; }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-7px); }
  75% { transform: translateX(7px); }
}

/* ---- Standalone app mode (installed PWA) ---------------------------------------------- */
.site-header { padding-top: env(safe-area-inset-top, 0px); }
.site-footer .shell { padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px)); }
@media (display-mode: standalone) {
  .site-header { border-top: 0; }
  body { -webkit-user-select: none; user-select: none; } /* app-like: no accidental text selection */
  input, textarea, .txt, .data-table td { -webkit-user-select: text; user-select: text; }
}

/* ---- Interactive accent (global residuals) ---------------------------------------
   Fern green = "you can tap this". Per-component accent is folded into each base
   rule above; only genuinely-global accent rules remain here. */
input[type="checkbox"] { accent-color: var(--accent); }
a { color: var(--accent-deep); }
.day-num { transition: background 0.15s ease; }

/* (grouped-input visual + hover + placeholder folded into the .input base rule.) */

/* Comfortable touch targets on phones */
@media (pointer: coarse) {
  .btn { padding: 0.65rem 1.1rem; font-size: 13.5px; }
  .input, select.input { font-size: 16px; } /* prevents iOS zoom-on-focus */
  .paid-chk input, .list-item input[type="checkbox"] { width: 1.25rem; height: 1.25rem; }
  .cal-cell { min-height: clamp(5.5rem, 12vh, 8rem); }
  /* hover never fires on touch — keep the list-item delete reachable */
  .list-item .del { opacity: 0.55; padding: 0.4rem; }
}
/* Bigger touch pills apply only to the DESKTOP layout (the rounded top tabs).
   The phone bottom bar (<=640) keeps its own compact icon+label sizing —
   the old unscoped rule was bloating those buttons off the edge. */
@media (pointer: coarse) and (min-width: 641px) {
  .tabs button { padding: 0.65rem 1.4rem; font-size: 15px; }
}

/* (frosted pill toast folded into the .toast base rule above; side-stripe removed.) */

/* Masked value (Debt to clear privacy toggle) */
.today-chip .eye-btn {
  margin-left: auto;
  align-self: flex-end;
  margin-top: -1.4rem;
  color: var(--muted);
  padding: 0.25rem;
  border-radius: 9999px;
}
.today-chip .eye-btn:hover { color: var(--accent-deep); background: var(--accent-soft); }
.masked-value { letter-spacing: 0.15em; color: var(--muted); }

/* ---- Strategy execution steps -------------------------------------------------------- */
.steps-fold { margin-top: 0.5rem; }
.steps-fold > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent-deep);
  padding: 0.25rem 0;
}
.steps-fold > summary::-webkit-details-marker { display: none; }
.steps-fold > summary::before { content: "›"; margin-right: 0.375rem; transition: transform 0.15s ease; }
.steps-fold[open] > summary::before { transform: rotate(90deg); }
.steps-fold > summary:hover { color: var(--accent); }
.steps-list {
  margin: 0.375rem 0 0.25rem;
  padding-left: 1.25rem;
  list-style: decimal;
  display: grid;
  gap: 0.375rem;
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.steps-list li::marker { color: var(--accent); font-weight: 700; }

/* ---- Show-more pattern -------------------------------------------------------------- */
.more-wrap { display: flex; justify-content: center; padding: 0.375rem 0 0.625rem; border-top: 1px solid var(--border-soft); }
.more-btn { color: var(--accent-deep); font-weight: 600; font-size: 12.5px; }
.more-btn:hover { background: var(--accent-soft); }

/* ---- Strategy: waterfall bar -------------------------------------------------------- */
.flow-bar { display: flex; height: 26px; border-radius: 9999px; overflow: hidden; background: var(--secondary); }
.flow-seg { display: block; height: 100%; min-width: 2px; }

/* ---- Utility ----------------------------------------------------------------------- */
.muted { color: var(--muted); }
.mt-1 { margin-top: 0.5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; }
.flex-between { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
/* Skip-to-content — off-screen until keyboard focus, then pinned top-left so
   keyboard/screen-reader users jump past the nav straight to the active tab. */
.skip-link { position: fixed; top: 0.5rem; left: 0.5rem; z-index: var(--z-toast); transform: translateY(-150%); transition: transform 0.15s ease; background: var(--accent); color: var(--on-ink); padding: 0.5rem 0.875rem; border-radius: var(--radius-sm); font-weight: 600; text-decoration: none; }
.skip-link:focus { transform: none; outline: 2px solid var(--on-ink); outline-offset: 2px; }

/* ---- Small screens ------------------------------------------------------------------ */
@media (max-width: 639px) {
  .cal-cell { min-height: 4.75rem; font-size: 12px; }
  .cal-dot, .cal-more { display: none; }       /* chips + overflow tag are noise at phone width… */
  /* …so a busy day shows a corner count instead — clearer than a featureless ring. */
  .cal-count { display: inline-flex; align-items: center; justify-content: center; position: absolute; top: 0.3rem; right: 0.3rem; min-width: 1.15rem; height: 1.15rem; padding: 0 0.25rem; border-radius: 9999px; background: var(--accent-soft); color: var(--accent-deep); font-size: 12px; font-weight: 700; }
  .cal-cell.today .day-num { box-shadow: 0 0 0 2px var(--gold-soft); } /* today still gets its ring */
  .score-num { font-size: 36px; }
  .site-header .shell { padding-top: 1.5rem; }
}

@media print {
  .site-header, .site-footer, .tabs, .footer-actions { display: none !important; }
  .card, .table-wrap { box-shadow: none; }
  body::before { display: none; } /* don't waste ink on the botanical texture */
}

/* Accounts */
.account-card.needs-verify { border-style: dashed; }

/* ---- Interaction polish pass (affordance + tap feedback) -----------------------------
   Hover-gated so touch devices never get stuck in a hover state. */
@media (hover: hover) {
  /* Inactive desktop pill tabs had no hover affordance — only the selected one read. */
  .tabs button:not([aria-selected="true"]):hover { color: var(--on-ink); background: hsl(0 0% 100% / 0.08); }
  .pill-group button:not([aria-pressed="true"]):hover { background: var(--secondary); }
}
/* Press feedback on the Today strip chips (they are buttons). */
.today-chip:active { transform: translateY(0) scale(0.985); }
/* On-brand text selection instead of the browser default blue. */
::selection { background: var(--accent-soft); color: var(--ink); }

/* ============================================================================
   QoL pass (S2–S10) — privacy blur, search, deep-link focus, empty states,
   provenance/as-of, mini sparklines, change feed, density toggle, ingest inbox.
   ========================================================================== */

/* S10 — Privacy: blur every tabular number at once (inputs stay sharp so you
   can still type). Toggle lives in the footer; preference rides the ui bag. */
.privacy-blur .tnum:not(input) {
  filter: blur(7px);
  transition: filter 0.12s ease;
  user-select: none;
  cursor: default;
}

/* S6 — Search: one box to find anything; results jump to the owning tab. */
.search-host { margin: 0 0 0.6rem; }
.search-wrap {
  position: relative; display: flex; align-items: center; gap: 0.5rem;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0 0.75rem;
}
.search-wrap > .icon { color: var(--muted); flex: none; }
.search-input {
  flex: 1; min-width: 0; border: 0; background: none; padding: 0.6rem 0;
  font: inherit; color: var(--ink); outline: none;
}
.search-input::placeholder { color: var(--muted); }
.search-results {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-card); z-index: var(--z-search);
  max-height: 60vh; overflow-y: auto;
}
.search-hit {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  width: 100%; text-align: left; background: none; border: 0;
  border-bottom: 1px solid var(--border-soft); padding: 0.55rem 0.85rem;
  cursor: pointer; font: inherit; color: var(--ink);
}
.search-hit:last-child { border-bottom: 0; }
.search-hit:hover, .search-hit:focus-visible { background: var(--secondary); outline: none; }
.search-hit-label { font-weight: 600; }
.search-hit-sub { font-size: 0.78rem; color: var(--muted-strong); }

/* S9 — Deep-link focus: a glance chip lands on its control and flashes it. */
[data-focus] { scroll-margin-top: 4.5rem; }
.focus-flash {
  animation: focus-flash 1.5s ease;
  border-radius: var(--radius-card);
}
@keyframes focus-flash {
  0%, 18% { box-shadow: 0 0 0 3px var(--accent-soft), 0 0 0 1px var(--accent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .focus-flash { animation: none; }
}

/* S8 — Provenance: every static-data surface wears its age; stale data dims. */
.asof-row { margin: 0 0 1rem; }
.asof-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.72rem; color: var(--muted);
  background: var(--secondary); border-radius: 999px;
  padding: 0.15rem 0.55rem; white-space: nowrap;
}
.asof-chip .icon { opacity: 0.75; }
.asof-chip.stale {
  color: var(--col); background: var(--gold-soft);
  font-weight: 600;
}

/* S7 — Empty / first-run states: a friendly nudge instead of a blank. */
.empty-state {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 0.4rem; padding: 2.25rem 1.25rem; color: var(--muted);
  background: var(--card); border: 1px dashed var(--border); border-radius: var(--radius-card);
}
.empty-state .icon { color: var(--accent); opacity: 0.8; }
.empty-title { font-weight: 700; color: var(--ink-soft); }
.empty-hint { font-size: 0.85rem; max-width: 28rem; line-height: 1.5; }

/* S2 — "Since you last looked": a dismissible feed of what moved between visits. */
.changes-host:empty { display: none; }
.changes-feed {
  background: var(--card); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: 0.6rem 0.85rem; margin: 0 0 0.6rem;
}
.changes-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.35rem; }
.changes-title {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; color: var(--muted);
}
.changes-title .icon { opacity: 0.7; }
.changes-dismiss { background: none; border: 0; color: var(--muted); cursor: pointer; padding: 0.15rem; display: inline-flex; }
.changes-dismiss:hover { color: var(--ink); }
.changes-lines { display: flex; flex-direction: column; gap: 0.1rem; }
.changes-line {
  display: flex; align-items: center; gap: 0.5rem; width: 100%; text-align: left;
  background: none; border: 0; padding: 0.3rem 0.15rem; cursor: pointer; font: inherit; color: var(--ink);
  border-radius: var(--radius);
}
.changes-line:hover { background: var(--secondary); }
.changes-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--muted); }
.changes-dot.pos { background: var(--pos); }
.changes-dot.neg { background: var(--neg); }

/* S3 — Simple view: same data, less chrome. Lists also shorten via
   Util.collapseList; here we drop explanatory subtitles and tighten spacing.
   Only non-data chrome is hidden — nothing that carries a number or a name. */
.density-simple .kicker { display: none; }
.density-simple .section { margin-bottom: 1rem; }
.density-simple .empty-hint { display: none; }

/* S4 — Staged ingestion inbox: capture data without touching code. */
.ingest-host { margin-top: 1.5rem; }
details.ingest {
  background: var(--card); border: 1px dashed var(--border); border-radius: var(--radius-card);
}
details.ingest > summary {
  list-style: none; cursor: pointer; padding: 0.7rem 1rem; user-select: none;
}
details.ingest > summary::-webkit-details-marker { display: none; }
.ingest-summary { display: inline-flex; align-items: center; gap: 0.45rem; font-weight: 600; color: var(--ink-soft); }
.ingest-summary .icon { color: var(--accent); }
.ingest-body { padding: 0 1rem 1rem; }
.ingest-add { display: flex; flex-direction: column; gap: 0.5rem; }
.ingest-add .btn-primary { align-self: flex-start; }
textarea.ingest-input { resize: vertical; min-height: 2.6rem; font: inherit; }
.ingest-list { margin-top: 0.85rem; display: flex; flex-direction: column; gap: 0.4rem; }
.ingest-item {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 0.55rem 0.7rem; background: var(--background); border: 1px solid var(--border-soft); border-radius: var(--radius);
}
.ingest-item-main { min-width: 0; }
.ingest-text { font-size: 0.9rem; overflow-wrap: anywhere; }
.ingest-meta { font-size: 0.72rem; margin-top: 0.1rem; }
.ingest-actions { display: flex; align-items: center; gap: 0.3rem; flex: none; }

/* ============================================================================
   Polish pass — focus legibility on dark, themed scrollbars, transparency
   fallback. All additive; nothing above changes behavior.
   ========================================================================== */

/* Focus ring on the dark ground: the global fern --accent ring reads ~2.7:1 on
   --ink (below the 3:1 UI minimum). Gold clears AA on header/nav/lock surfaces.
   Placed last so it wins source-order over the base :focus-visible rule. */
.site-header :focus-visible,
.nav-band :focus-visible,
.lock-overlay :focus-visible { outline-color: var(--gold); }

/* Themed thin scrollbars for the horizontal/long scroll regions — a soft sage
   thumb instead of the cold OS default on the warm palette. */
.table-wrap, .search-results {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--muted) 38%, transparent) transparent;
}
.table-wrap::-webkit-scrollbar, .search-results::-webkit-scrollbar { width: 8px; height: 8px; }
.table-wrap::-webkit-scrollbar-track, .search-results::-webkit-scrollbar-track { background: transparent; }
.table-wrap::-webkit-scrollbar-thumb, .search-results::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 32%, transparent);
  border-radius: 9999px;
  border: 2px solid transparent;   /* inset padding → a slimmer thumb */
  background-clip: padding-box;
}
.table-wrap:hover::-webkit-scrollbar-thumb, .search-results:hover::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 55%, transparent);
  background-clip: padding-box;
}

/* Solid fallback for frosted surfaces when the user asks for less transparency
   (the blur otherwise drops contrast on the toast + mobile tab bar). */
@media (prefers-reduced-transparency: reduce) {
  .toast { background: var(--ink); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (max-width: 640px) and (prefers-reduced-transparency: reduce) {
  .tabs { background: var(--card); -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ---- Uploads tab (js/uploads.js) ----------------------------------------- */
/* Composition mirrors the other tabs: a rule-gold + h2 section-head, then
   content in .card.pad blocks. The dropzone echoes the ingest inbox's dashed
   capture surface; the rows reuse the .ingest-item token recipe (inset on
   --background, hairline --border-soft) so files and text captures read alike. */
.uploads { display: flex; flex-direction: column; gap: 1.25rem; }
.uploads .section-head { margin-bottom: 0; }
.uploads .upload-note { font-size: 12.5px; color: var(--muted-strong); margin: -0.5rem 0 0; }
.upload-err {
  margin: -0.5rem 0 0; padding: 0.6rem 0.75rem; border-radius: var(--radius);
  background: color-mix(in srgb, var(--neg) 7%, var(--card));
  border: 1px solid color-mix(in srgb, var(--neg) 30%, transparent);
}
.upload-err-head { font-size: 12.5px; font-weight: 600; color: var(--neg); }
.upload-err-head .icon { color: var(--neg); }
.upload-err-row { font-size: 12px; color: var(--muted-strong); margin-top: 0.15rem; }

.uploads .upload-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 1.75rem 1rem;
  border: 1.5px dashed var(--border);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--muted-strong);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}
.uploads .upload-drop .icon { color: var(--accent); opacity: 0.85; }
.uploads .upload-drop:hover { border-color: var(--accent); color: var(--ink-soft); }
.uploads .upload-drop:focus-visible {
  border-color: var(--accent); color: var(--ink-soft);
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.uploads .upload-drop.is-over {
  border-style: solid;
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--ink);
}
.uploads .upload-drop.is-busy { opacity: 0.6; pointer-events: none; }
.uploads .upload-drop-title { font-family: var(--font-display); font-size: 16px; font-weight: 600; color: var(--ink); }
.uploads .upload-drop-hint { font-size: 12.5px; color: var(--muted-strong); }

.uploads .upload-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.6rem; margin-bottom: 0.75rem;
}
.uploads .upload-updated { font-size: 12px; color: var(--muted-strong); }

.uploads .upload-list { display: flex; flex-direction: column; gap: 0.4rem; }
.uploads .upload-item {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  background: var(--background);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.uploads .upload-item .icon { color: var(--accent); flex: none; }
.uploads .upload-item-main { flex: 1; min-width: 0; }
.uploads .upload-item-name {
  font-size: 0.9rem; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.uploads .upload-item-meta { font-size: 0.72rem; color: var(--muted-strong); margin-top: 0.1rem; }

.uploads .upload-subjects { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; }
.uploads .upload-subject {
  display: flex; align-items: baseline; gap: 0.45rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--background);
}
.uploads .upload-subject-label { font-size: 12px; color: var(--muted-strong); }
.uploads .upload-subject-count {
  font-family: var(--font-display); font-size: 18px; font-weight: 600;
  line-height: 1; color: var(--ink);
}
.uploads .upload-subject-count.is-zero { color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .uploads .upload-drop { transition: none; }
}
