:root {
  --bg: #0e1726;
  --bg-2: #15203a;
  --card: #182441;
  --card-2: #1f2d52;
  --line: #28365e;
  --text: #e8eefc;
  --muted: #9fb0d4;
  --accent: #38bdf8;
  --good: #34d399;
  --bad: #f87171;
  --warn: #fbbf24;
  --radius: 14px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* Light theme (applied by time of day via data-theme on <html>) */
html[data-theme="light"] {
  --bg: #eef2f9;
  --bg-2: #ffffff;
  --card: #ffffff;
  --card-2: #eef3fb;
  --line: #d7dfee;
  --text: #101a2e;
  --muted: #5a6a86;
  --accent: #0ea5e9;
  --good: #15803d;
  --bad: #dc2626;
  --warn: #b45309;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  font-size: 16px;
  overscroll-behavior-y: none;
}

body {
  padding-bottom: calc(72px + var(--safe-bottom));
  /* No min-height: 100vh - on phones 100vh is taller than the visible window (it counts the system bars), which made every short page scroll for no reason. The background comes from html, so nothing is lost. */
  touch-action: manipulation;
}

/* Header */
.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: linear-gradient(180deg, var(--bg-2), var(--bg));
  padding: calc(10px + var(--safe-top)) 14px 0;
  border-bottom: 1px solid var(--line);
}
.title-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
}
/* Explicit columns: a hidden back button leaves the grid entirely, and without this the
   menu button would auto-place into the middle column and sit in the centre on Home. */
#backBtn { grid-column: 1; justify-self: center; }
.title-center { grid-column: 2; }
#menuBtn { grid-column: 3; justify-self: center; }
.title-center {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 0;
}
.title-row h1 {
  font-size: 1.15rem;
  margin: 0;
  letter-spacing: 0.3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.icon-btn {
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.5rem;
  line-height: 1;
  padding: 6px 10px;
  border-radius: 10px;
  cursor: pointer;
}
.icon-btn:active { background: var(--card); }
/* A gear icon-btn gets a quick quarter-turn on press instead of just the
   background flash every other icon-btn gets - a small "it's a settings
   dial" cue, snapping back once released rather than spinning freely. */
.gear-btn { transition: transform 0.3s ease; }
.gear-btn:active { transform: rotate(75deg); }

.portfolio-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 10px 0;
  scrollbar-width: none;
}
.portfolio-tabs::-webkit-scrollbar { display: none; }
.ptab {
  flex: 0 0 auto;
  background: var(--card);
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
.ptab.active {
  background: var(--accent);
  color: #06243a;
  border-color: var(--accent);
  font-weight: 600;
}

main { padding: 14px; }

/* Swipe between portfolio tabs (Stocks surface): a brief directional slide as
   the new portfolio's content lands, so the gesture reads as a deliberate move
   rather than the page flickering under your thumb. The class is added after the
   re-render and removed on animationend (see flashSwipeDirection). */
@keyframes swipe-from-right {
  from { transform: translateX(16px); opacity: 0.5; }
  to { transform: none; opacity: 1; }
}
@keyframes swipe-from-left {
  from { transform: translateX(-16px); opacity: 0.5; }
  to { transform: none; opacity: 1; }
}
main.swipe-in-right { animation: swipe-from-right 0.18s ease-out; }
main.swipe-in-left { animation: swipe-from-left 0.18s ease-out; }
@media (prefers-reduced-motion: reduce) {
  main.swipe-in-right, main.swipe-in-left { animation: none; }
}

/* Summary card */
.summary {
  background: linear-gradient(135deg, var(--card), var(--card-2));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 14px;
}
.summary .big {
  font-size: 1.8rem;
  font-weight: 700;
  margin: 2px 0;
}
.summary .grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 12px;
  margin-top: 12px;
}
.summary .cell .k { color: var(--muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.5px; }
.summary .cell .v { font-size: 1.02rem; font-weight: 600; margin-top: 2px; }
.summary .row-between { display: flex; align-items: center; justify-content: space-between; }
.summary .label { color: var(--muted); font-size: 0.78rem; }
.summary .summary-top { align-items: flex-start; }
.summary .summary-earned { text-align: right; }
.summary .summary-earned .v { font-size: 1.3rem; font-weight: 700; margin-top: 2px; }

/* Toolbar */
.toolbar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; align-items: center; }
.sortbar { display: flex; gap: 6px; }
.sort-btn {
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: 999px;
  padding: 7px 12px;
  font-size: 0.8rem;
  cursor: pointer;
  white-space: nowrap;
}
.sort-btn.active { background: var(--accent); color: #06243a; border-color: var(--accent); font-weight: 600; }
.seg { display: flex; background: var(--card); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.seg button {
  background: transparent; color: var(--muted); border: none;
  padding: 6px 10px; font-size: 0.75rem; cursor: pointer; white-space: nowrap;
}
.seg button.active { background: var(--card-2); color: var(--text); font-weight: 600; }
.search {
  flex: 1 1 100%;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  padding: 9px 12px;
  font-size: 0.9rem;
  min-width: 0;
}
.search::placeholder { color: var(--muted); }

/* Stock list */
.stock-list { display: flex; flex-direction: column; gap: 10px; padding-bottom: 76px; }
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 9px 12px;
  cursor: pointer;
}
.card:active { background: var(--card-2); }
.card .top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.card .name { font-weight: 600; font-size: 1rem; }
.card .cat { color: var(--muted); font-size: 0.76rem; margin-top: 2px; }
.card .pct { font-size: 1.05rem; font-weight: 700; white-space: nowrap; }
.card .sub { display: flex; justify-content: space-between; gap: 8px; margin-top: 2px; color: var(--muted); font-size: 0.82rem; }
.card .sub b { color: var(--text); font-weight: 600; }
.card .cat { font-size: 0.72rem; }
.card-left { min-width: 0; flex: 1 1 auto; }
.cat-badge { display: inline-block; margin-left: 6px; background: #e0f2fe; border: 1px solid #bae6fd; color: #0c4a6e; border-radius: 999px; padding: 1px 8px; font-size: 0.56rem; vertical-align: middle; }
.meta-line { color: var(--muted); font-size: 0.74rem; margin-top: 3px; }
.meta-line b { color: var(--text); font-weight: 600; }
.meta-line.warn { color: var(--warn); font-weight: 600; }
/* Stock card's "Since <year> · N yrs" line — deliberately much smaller than
   the other meta-lines so it reads as a footnote, not primary info; only the
   year itself is bold to still catch the eye. */
.meta-line.since-year { font-size: 0.6rem; }
.meta-line.since-year b { font-weight: 700; }
/* Per-portfolio "prices updated" line under each Portfolios-card stat */
.stat-upd { font-size: 0.58rem; color: var(--muted); margin-top: 2px; }
.stat-upd.warn { color: var(--warn); font-weight: 600; }
/* Holdings summary card: prices-updated status, tucked bottom-right */
.summary-upd { text-align: right; font-size: 0.6rem; color: var(--muted); margin-top: 6px; }
.summary-upd.warn { color: var(--warn); font-weight: 600; }
.price-status-section { padding: 1px 16px 0; text-align: right; font-size: 0.65rem; }
.price-status { color: var(--muted); }
.price-status.warn { color: var(--warn); font-weight: 600; }
/* Price status section below portfolios card */
.price-status-container { margin: 12px 0 16px; }
.price-status-row { display: flex; justify-content: space-between; font-size: 0.65rem; padding: 6px 0; border-bottom: 1px solid var(--line); }
.price-status-row:last-child { border-bottom: none; }
.ps-label { color: var(--muted); }
.ps-text { color: var(--muted); }
.ps-text.warn { color: var(--warn); font-weight: 600; }
/* ---------- Dividends surface ---------- */
/* Per-stock card: compact per-year breakdown under the header */
.div-years { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 6px; display: flex; flex-direction: column; gap: 3px; }
.div-year-row { display: grid; grid-template-columns: 3.2rem 1fr auto; align-items: baseline; gap: 8px; font-size: 0.72rem; }
.div-year-k { color: var(--muted); font-weight: 700; }
.div-year-v { color: var(--text); font-weight: 600; }
.div-year-sub { color: var(--muted); font-size: 0.66rem; text-align: right; }
/* Overview: annual-analysis table */
.div-table { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.div-trow { display: grid; grid-template-columns: 3.2rem 1fr 1fr 1fr; align-items: center; gap: 6px; padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 0.76rem; }
.div-trow:last-child { border-bottom: none; }
.div-thead { color: var(--muted); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.4px; border-bottom: 1px solid var(--line); }
.div-tyear { font-weight: 700; }
.div-yoy { text-align: right; font-weight: 600; }
.div-profit { font-size: 0.64rem; opacity: 0.85; font-weight: 500; }
/* Dividend annual-analysis table carries an extra FY-total column (5 cols). The
   shared .div-trow is 4-col (also used by the Metals overview), so widen only
   here. */
.div-annual .div-trow { grid-template-columns: 2.4rem 1fr 1fr 1.15fr 1fr; font-size: 0.72rem; gap: 4px; }
.div-fy-sub { font-size: 0.62rem; opacity: 0.8; }
/* Calendar: current-month highlight */
.div-month { }
.div-month-cur { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.div-cal-row { padding: 4px 0; }
/* Stocks tab: group headings for current-year status */
.div-group-head { font-size: 0.85rem; font-weight: 700; color: var(--text); margin-top: 16px; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.3px; opacity: 0.9; }
.div-group-head:first-child { margin-top: 0; }
/* Form: month toggle grid + per-year editor rows */
.div-mon-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.div-mon-btn { padding: 7px 0; border-radius: 8px; border: 1px solid var(--line); background: var(--card); color: var(--muted); font-size: 0.74rem; }
.div-mon-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
/* Per-year month selector: compact single-letter buttons in a 3-col grid. Year input
   + months grid sit side-by-side in .div-year-input-group. */
.div-year-input-group { display: flex; flex-direction: column; gap: 6px; flex: 1; }
.div-year-months { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; }
.div-year-mon-btn { padding: 4px 0; border-radius: 4px; border: 1px solid var(--line); background: var(--card); color: var(--muted); font-size: 0.62rem; font-weight: 600; cursor: pointer; transition: all .1s ease; }
.div-year-mon-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.div-yedit-head { display: grid; grid-template-columns: 1fr 1fr 1fr 2rem; gap: 6px; color: var(--muted); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 4px; }
.div-yedit-row { display: grid; grid-template-columns: 1fr 1fr 1fr 2rem; gap: 6px; align-items: center; margin-bottom: 6px; }
/* US years skip units/per-unit — the month picker and a per-month breakdown
   side by side, so the row tops-aligns rather than centring a tall stack. */
.div-yedit-head-us { grid-template-columns: 1.5fr 1fr 2rem; }
.div-yedit-row-us { grid-template-columns: 1.5fr 1fr 2rem; align-items: start; }
/* India dividend breakdown: per-month inputs with live calculation */
.div-yedit-row-india { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 6px; }
.div-year-left-col { display: flex; flex-direction: column; gap: 8px; flex: 0 0 180px; }
.div-year-right-col { flex: 1; }
.div-units-group { display: flex; flex-direction: column; gap: 6px; padding: 8px; background: var(--card-2); border-radius: 6px; }
.div-units-row { display: flex; flex-direction: column; gap: 4px; }
.div-units-label-text { font-size: 0.65rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.div-units-input-row { display: flex; align-items: center; gap: 4px; }
.div-units-input-row input { flex: 0 0 45px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 4px; font-size: 0.75rem; }
.div-units-input-row .btn { padding: 3px 5px; font-size: 0.6rem; }
.div-fetch-info { font-size: 0.62rem; color: var(--muted); line-height: 1.3; }
.div-fetch-date { font-weight: 700; color: var(--accent); }
.div-india-breakdown { display: flex; flex-direction: column; gap: 4px; }
.div-india-month-inputs { display: flex; flex-direction: column; gap: 4px; }
.div-month-input { display: flex; align-items: center; gap: 4px; font-size: 0.7rem; }
.div-month-input span { flex: 0 0 42px; color: var(--muted); font-weight: 600; }
.div-month-input input { flex: 0 0 60px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 4px; font-size: 0.7rem; }
.div-breakdown-summary { display: flex; flex-direction: column; gap: 3px; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.div-breakdown-calc { font-size: 0.68rem; color: var(--muted); }
.div-breakdown-total { font-size: 0.76rem; font-weight: 700; color: var(--accent); }
/* Year slider: navigate between dividend entry years */
.div-year-slider .div-slider-nav { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.div-slider-nav .icon-btn { padding: 4px 8px; font-size: 0.8rem; }
.div-slider-nav .icon-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.div-year-label { font-weight: 700; min-width: 40px; text-align: center; font-size: 0.95rem; }
.div-year-row-item { transition: opacity 0.15s ease; }
.div-year-row-item.hidden { display: none; }
.div-year-editor + .btn { margin-top: 2px; }
/* Dividend stocks tab: stats bar showing counts and totals per market */
.div-stats-bar { display: flex; align-items: stretch; gap: 12px; margin: 16px 0 20px; padding: 8px; background: linear-gradient(135deg, var(--card-2) 0%, var(--card) 100%); border: 1px solid var(--line); border-radius: 12px; }
/* Each side doubles as the India/US switch — tappable, with an active state
   so it also reads as the current selection (replaces the old tab row). */
.div-stat-item { flex: 1; display: flex; flex-direction: column; justify-content: center; cursor: pointer; padding: 8px 10px; border-radius: 8px; border: 1px solid transparent; transition: all 0.15s ease; }
.div-stat-item:hover { background: var(--card-2); }
.div-stat-item.active { background: var(--card); border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.div-stat-label { font-size: 0.65rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 600; margin-bottom: 4px; }
.div-stat-count { font-size: 1.4rem; font-weight: 700; color: var(--accent); }
.div-stat-total { font-size: 0.76rem; color: var(--text); font-weight: 600; margin-top: 2px; }
.div-stat-sep { width: 1px; background: var(--line); }
/* Enhanced dividend card design */
.div-card-enhanced { transition: all 0.2s ease; }
.div-card-enhanced:hover { transform: translateY(-2px); box-shadow: 0 8px 16px rgba(0,0,0,0.3); }
.div-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.div-card-name-section { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.div-cur-total { font-size: 0.85rem; }
/* Consolidated (all-years) payout months, top of card — months from the
   current month onward this year get the highlighted "upcoming" style. */
.div-card-months { display: flex; flex-wrap: wrap; gap: 4px; }
/* Consolidated "ever paid in these months" list, in its own grey panel across
   the card — the per-year rows below now carry month chips too, so this needs
   to read as a separate kind of fact rather than more of the same. */
.div-months-panel { margin-top: 10px; padding: 8px 10px; border-radius: 8px; background: var(--card-2); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 6px; }
.div-months-panel-label { font-size: 0.6rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.div-months-panel .hint { margin: 0; }
/* A plain chip's own background IS --card-2, which the panel now also uses —
   lift the chips to --card so they don't vanish into it. The blue "upcoming"
   chips set their own background and are left alone. */
.div-months-panel .div-month-chip:not(.upcoming) { background: var(--card); }
.div-years { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
/* Per-year entry row (dividend stock card only) — deliberately its own class
   family (div-year-entry*, not div-year-row/k/v) because .div-year-row and
   friends are ALSO used, unrelated, by the Metals "by source" breakdown
   (grid-based, single-line) - reusing those names here would have silently
   broken that layout the moment this became a 2-line flex-column row. */
.div-year-entry { display: flex; flex-direction: column; gap: 5px; padding: 4px 0; font-size: 0.7rem; }
.div-year-entry.current-year { background: rgba(56,189,248,0.08); padding: 6px 8px; margin: 0 -8px; border-radius: 4px; font-weight: 600; }
/* Year / total / month-chips / calc all on ONE line — a stock usually pays in
   about three months, so a second row per year was mostly empty space. Wraps
   rather than overflowing when a year does have many payout months. */
.div-year-entry-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.div-year-entry-k { color: var(--muted); flex: 0 0 35px; }
.div-year-entry-v { font-weight: 700; color: var(--text); }
.div-year-entry-calc { font-size: 0.62rem; color: var(--muted); margin-left: auto; text-align: right; }
/* Per-year payout-month chips — this year's own months, from our per-year
   months fix (not the record-level consolidated list above). */
.div-year-month-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.div-month-chip { font-size: 0.6rem; font-weight: 600; padding: 2px 7px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line); color: var(--muted); }
.div-month-chip.upcoming { background: rgba(56,189,248,0.14); border-color: rgba(56,189,248,0.4); color: var(--accent); font-weight: 700; }
/* A chip carrying that month's own figure: name plain, amount in a blue pill.
   Only the amount-bearing variant tightens its right padding — the plain chips
   on the card's consolidated months line keep the symmetric padding above. */
.div-month-chip.has-amt { display: inline-flex; align-items: center; gap: 5px; padding-right: 3px; }
.div-chip-amt { background: rgba(56,189,248,0.16); border: 1px solid rgba(56,189,248,0.38); color: var(--accent); border-radius: 999px; padding: 1px 6px; font-weight: 700; }
/* Metals: price control row under the summary card */
.metal-price-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 2px 10px; }
.metal-price-row .hint { margin: 0; }
/* Switch-style toggle (e.g. stock form's "Dividend available") */
.switch { position: relative; display: inline-flex; align-items: center; width: 46px; height: 26px; cursor: pointer; flex: 0 0 auto; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; z-index: 1; }
.switch-track { position: absolute; inset: 0; background: var(--line); border-radius: 999px; transition: background .15s ease; }
.switch-thumb { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.35); transition: transform .15s ease; }
.switch input:checked + .switch-track { background: var(--accent); }
.switch input:checked + .switch-track .switch-thumb { transform: translateX(20px); }
.card-right { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: 0 0 auto; }
.kv { display: flex; align-items: center; gap: 5px; font-size: 0.7rem; }
.kv-label { color: #38bdf8; font-weight: 700; font-size: 0.58rem; }
.kv-val { background: #e0f2fe; border: 1px solid #bae6fd; border-radius: 6px; padding: 1px 7px; font-weight: 700; color: #0c4a6e; font-size: 0.72rem; }
.kv-val.pos { color: #15803d; }
.kv-val.neg { color: #b91c1c; }
.note { font-size: 0.62rem; line-height: 1.45; color: var(--muted); margin: 6px 0 0; }

.stats { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.stat { flex: 1 1 calc(33% - 8px); min-width: 90px; background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; padding: 7px 9px; overflow: hidden; }
/* stat values: nowrap so currency strings like "+₹1,91,997.42" never break
   across lines; long values get a smaller size class (set by _statSizeClass
   in app.js based on character count). text-overflow:ellipsis is a final
   safety net for absurdly wide numbers (>10 crore range) — never seen in
   practice but keeps the card visually contained. */
.stat-v { font-size: 0.9rem; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat-v.stat-v-sm { font-size: 0.76rem; }
.stat-v.stat-v-xs { font-size: 0.66rem; }
.stat-k { font-size: 0.58rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 2px; }
.insight-cards { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.insight-card { flex: 1 1 calc(50% - 8px); min-width: 140px; background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.insight-card .ic-k { font-size: 0.58rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.insight-card .ic-v { font-size: 0.82rem; font-weight: 600; margin-top: 2px; }

.bar-row { display: flex; align-items: center; gap: 8px; margin: 5px 0; font-size: 0.76rem; }
.bar-row .bl { flex: 0 0 38%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track { flex: 1; background: var(--bg-2); border: 1px solid var(--line); border-radius: 6px; height: 14px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--accent); border-radius: 6px 0 0 6px; }
.bar-row .bn { flex: 0 0 auto; color: var(--muted); min-width: 18px; text-align: right; }

.badge { display: inline-block; font-size: 0.7rem; padding: 2px 7px; border-radius: 999px; border: 1px solid var(--line); }
.badge.good { color: var(--good); border-color: rgba(52,211,153,0.4); background: rgba(52,211,153,0.1); }
.badge.bad { color: var(--bad); border-color: rgba(248,113,113,0.4); background: rgba(248,113,113,0.1); }
.badge.warn { color: var(--warn); border-color: rgba(251,191,36,0.4); background: rgba(251,191,36,0.1); }
.badge.muted { color: var(--muted); }
.badge.fd-reinvested { color: var(--accent); border-color: rgba(14,165,233,0.45); background: rgba(14,165,233,0.12); }
/* Marks a fund/bond/FD whose money is counted on the Emergency Fund page rather
   than in this surface's own totals. Distinct from the status badges beside it —
   this says "counted elsewhere", not "in this state". */
.badge.ef-badge { color: #7c3aed; border-color: rgba(124,58,237,0.45); background: rgba(124,58,237,0.12); font-weight: 700; }
@media (prefers-color-scheme: dark) { .badge.ef-badge { color: #c4b5fd; } }

/* Emergency Fund — Interest breakdown (realised vs pending rows) and the
   Invested-in section grouped by category (MF / Bonds / FD). */
.ef-interest-list { display: flex; flex-direction: column; gap: 8px; }
.ef-interest-group-label {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--muted); margin: 10px 0 2px;
}
.ef-interest-group-label:first-child { margin-top: 0; }
.ef-interest-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--card-2); border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: 10px; padding: 9px 11px;
}
.ef-interest-row.is-realised { border-left-color: var(--good); }
.ef-interest-row.is-pending { border-left-color: var(--warn); }
.ef-interest-row.is-mine { border-left-color: var(--accent); }
.ef-interest-row.is-spouse { border-left-color: #7c3aed; }
.ef-interest-icon {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  background: var(--card); display: flex; align-items: center; justify-content: center;
  font-size: 1rem;
}
.ef-interest-body { flex: 1 1 auto; min-width: 0; }
.ef-interest-label { font-size: 0.82rem; font-weight: 600; }
.ef-interest-sub { font-size: 0.66rem; color: var(--muted); margin-top: 1px; }
.ef-interest-amt { font-size: 0.92rem; font-weight: 700; white-space: nowrap; flex: 0 0 auto; }

.ef-group-header {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 2px; margin: 14px 0 8px;
  border-bottom: 1px solid var(--line);
}
.ef-group-header:first-of-type { margin-top: 4px; }
.ef-group-ico { font-size: 1rem; }
.ef-group-title { flex: 1 1 auto; font-size: 0.8rem; font-weight: 700; }
.ef-group-total { font-size: 0.82rem; font-weight: 700; color: var(--muted); white-space: nowrap; }

.conv { font-size: 0.95rem; }
.pos { color: var(--good); }
.neg { color: var(--bad); }
.flat { color: var(--muted); }

.empty {
  text-align: center;
  color: var(--muted);
  padding: 50px 20px;
}
.empty .e-icon { font-size: 2.4rem; }
.empty p { margin: 8px 0 0; }

/* FAB */
.fab {
  position: fixed;
  right: 18px;
  bottom: calc(78px + var(--safe-bottom));
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--accent);
  color: #06243a;
  border: none;
  font-size: 2rem;
  line-height: 1;
  box-shadow: 0 8px 20px rgba(0,0,0,0.4);
  cursor: pointer;
  z-index: 30;
}
.fab.fab-secondary {
  right: calc(18px + 56px + 12px);
  width: 48px; height: 48px;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 1.4rem;
  display: flex; align-items: center; justify-content: center;
}
/* When the primary + FAB is hidden (e.g. MF Stats tab), the secondary FAB docks
   to the corner slot + would have used, instead of floating with an empty gap. */
.fab.fab-secondary.solo { right: 18px; }

/* OCR review */
.ocr-sheet { max-width: 720px; }
/* Projected whole-portfolio totals after Apply — sits where the instruction
   blurb used to be, so the overall % can be eyeballed against the broker app.
   Borrows .summary's look; 3 columns keeps the six cells compact in the modal. */
.ocr-preview { margin-bottom: 12px; }
.ocr-preview .big { font-size: 1.5rem; }
.ocr-preview .grid { grid-template-columns: repeat(3, 1fr); gap: 8px 10px; margin-top: 10px; }
.ocr-preview .cell .v { font-size: 0.92rem; }
@media (max-width: 520px) { .ocr-preview .grid { grid-template-columns: 1fr 1fr; } }
.ocr-head, .ocr-row { display: grid; grid-template-columns: 20px 1fr 64px 76px 76px; gap: 8px; align-items: center; }
/* Groww/wife-in: Avg is hidden (Groww's Market Price view doesn't show it).
   Units + price are shown and editable. */
.ocr-head.no-avg, .ocr-row.no-avg { grid-template-columns: 20px 1fr 64px 96px; }
/* Inline avg-update banner — shown for a wife-in row when parsed units differ
   from saved units (buy/sell happened, avg has to be re-entered). Spans the
   full row width below the main fields. */
.ocr-row .ocr-avg-banner {
  grid-column: 1 / -1;
  margin-top: 8px;
  padding: 8px 10px;
  background: rgba(249, 115, 22, 0.10);
  border: 1px solid rgba(249, 115, 22, 0.45);
  border-radius: 8px;
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.ocr-row .ocr-avg-msg {
  font-size: 0.74rem;
  color: var(--text);
  flex: 1; min-width: 180px;
  line-height: 1.35;
}
.ocr-row .ocr-avg-banner input[type="number"] {
  width: 96px;
  padding: 5px 6px;
  font-size: 0.78rem;
}
.ocr-head { color: var(--muted); font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.4px; padding: 4px 0; border-bottom: 1px solid var(--line); }
.ocr-row { padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 0.78rem; }
.ocr-row.no-match { opacity: 0.55; }
.ocr-row input[type="number"] { padding: 5px 6px; font-size: 0.78rem; width: 100%; }
.ocr-row input.ocr-suspect { border-color: #f97316; background: rgba(249,115,22,0.12); color: #f97316; font-weight: 700; }
.ocr-row .ocr-parsed { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ocr-row .ocr-matched { color: var(--muted); font-size: 0.66rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ocr-row .ocr-match-sel {
  margin-top: 3px;
  width: 100%;
  font-size: 0.72rem;
  padding: 3px 4px;
  background: var(--card-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px;
  max-width: 100%;
}
.ocr-row.no-match .ocr-match-sel { color: var(--muted); }
.ocr-list { max-height: 56vh; overflow-y: auto; margin: 4px 0 10px; }

/* Bottom nav */
.bottom-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 25;
  display: flex;
  background: var(--bg-2);
  border-top: 1px solid var(--line);
  padding-bottom: var(--safe-bottom);
}
.bottom-nav button {
  flex: 1;
  background: transparent;
  border: none;
  color: var(--muted);
  padding: 12px 0 14px;
  font-size: 0.75rem;
  cursor: pointer;
}
.bottom-nav button .bn-ico { display: block; font-size: 1.2rem; margin-bottom: 2px; }
.bottom-nav button.active { color: var(--accent); }

/* Trend view */
.trend-view { display: flex; flex-direction: column; gap: 14px; }
.chart-card, .snap-list {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
}
.chart-info { font-size: 0.78rem; margin-top: 8px; min-height: 1.4em; color: var(--muted); font-weight: 600; text-align: center; }
.chart-card h3, .snap-list h3 { margin: 0 0 10px; font-size: 0.95rem; }
.snapshot-reminder {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px; padding: 10px 11px;
  background: rgba(251,191,36,0.1); border: 1px solid rgba(251,191,36,0.35);
  border-radius: 10px;
}
.snapshot-reminder-t { color: var(--warn); font-size: 0.8rem; font-weight: 700; }
.snapshot-reminder-d { color: var(--muted); font-size: 0.7rem; line-height: 1.35; margin-top: 2px; }
.snap-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 0; border-top: 1px solid var(--line); gap: 8px;
}
.snap-row:first-of-type { border-top: none; }
.snap-row .d { font-size: 0.85rem; }
.snap-row .m { color: var(--muted); font-size: 0.74rem; }

/* Modal */
.modal-host {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(4,9,20,0.6);
  display: flex; align-items: flex-end; justify-content: center;
}
.modal-host.hidden { display: none; }
.sheet {
  background: var(--bg-2);
  width: 100%;
  max-width: 560px;
  max-height: 92vh;
  overflow-y: auto;
  border-radius: 18px 18px 0 0;
  border: 1px solid var(--line);
  padding: 16px 16px calc(20px + var(--safe-bottom));
  animation: rise 0.18s ease-out;
}
@keyframes rise { from { transform: translateY(20px); opacity: 0.6; } to { transform: translateY(0); opacity: 1; } }
.sheet h2 { margin: 0 0 14px; font-size: 1.1rem; }
.field { margin-bottom: 12px; }
.field label { display: block; font-size: 0.78rem; color: var(--muted); margin-bottom: 5px; }
.field input, .field select, .field textarea {
  width: 100%;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  padding: 10px 12px;
  font-size: 0.95rem;
}
/* Remove number spinners everywhere */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.field textarea { resize: vertical; min-height: 60px; font-family: inherit; line-height: 1.45; }
.field-row { display: flex; gap: 10px; }
.field-row .field { flex: 1; }
.sold-only.hidden { display: none; }

.hist-rows { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.hist-row { display: flex; gap: 8px; align-items: center; }
.hist-row input { width: auto; }
.hist-row input[type="month"] { flex: 1; min-width: 0; }
.hist-row input[type="number"] { width: 96px; }
.hist-row .icon-btn { font-size: 1.3rem; padding: 2px 8px; }
.hist-row .hist-lock { flex: 0 0 28px; width: 28px; }

.chart-card.tappable { cursor: pointer; }
.tap-hint { display: inline-block; margin-top: 6px; padding: 2px 9px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line); color: var(--muted); font-size: 0.6rem; }

/* Heatmap */
.heatmap-scroll { overflow: auto; max-height: 72vh; border: 1px solid var(--line); border-radius: 12px; -webkit-overflow-scrolling: touch; }
table.heatmap { border-collapse: collapse; font-size: 0.72rem; }
.heatmap th, .heatmap td { border: 1px solid var(--line); padding: 5px 6px; text-align: center; white-space: nowrap; }
.heatmap td { min-width: 56px; position: relative; font-weight: 700; }
.hm-sticker { position: absolute; bottom: 1px; right: 1px; font-size: 0.8rem; line-height: 1; pointer-events: none; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.5)); }
/* Top-left, opposite corner from .hm-sticker - that one is a stock's own
   best/worst month (row-wise), this is the best/worst STOCK for that month
   (column-wise), so the two never need to share a spot even when both land
   on the same cell. */
.hm-col-sticker { position: absolute; top: 1px; left: 1px; font-size: 0.8rem; line-height: 1; pointer-events: none; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.5)); }
.heatmap thead th { position: sticky; top: 0; background: var(--bg-2); z-index: 2; color: var(--muted); font-weight: 600; }
.heatmap th.rowhead, .heatmap th.corner { position: sticky; left: 0; background: var(--bg-2); text-align: left; }
.heatmap th.rowhead { z-index: 1; max-width: 160px; }
.heatmap th.corner { z-index: 3; color: var(--muted); }
.heatmap .hm-name { font-weight: 600; font-size: 0.66rem; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.heatmap .hm-cat { display: inline-block; margin-top: 3px; padding: 1px 6px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line); color: var(--muted); font-size: 0.5rem; }
.hm-name-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
/* Bookmark-for-investing toggle - outline star until tapped, filled gold once
   bookmarked. Inline SVG (not emoji) so fill/stroke can be styled precisely. */
.hm-bookmark {
  flex: 0 0 auto; background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.hm-bookmark svg { width: 15px; height: 15px; fill: none; stroke: var(--muted); }
.hm-bookmark.active svg { fill: var(--warn); stroke: var(--warn); }
.hm-bookmark:active { transform: scale(0.9); }
.legend-wrap { margin-top: 14px; }
.legend-wrap h3 { margin: 0 0 8px; font-size: 0.9rem; }
.heat-legend { display: flex; flex-wrap: wrap; gap: 5px; }
.heat-legend .hl { font-size: 0.64rem; padding: 3px 8px; border-radius: 5px; }

.btn-row { display: flex; gap: 10px; margin-top: 8px; }
.btn {
  flex: 1; border: none; border-radius: 10px; padding: 12px;
  font-size: 0.95rem; font-weight: 600; cursor: pointer;
}
.btn.primary { background: var(--accent); color: #06243a; }
.btn.ghost { background: var(--card); color: var(--text); border: 1px solid var(--line); }
.btn.danger { background: transparent; color: var(--bad); border: 1px solid rgba(248,113,113,0.4); }
.btn.small { flex: 0 0 auto; padding: 8px 14px; font-size: 0.82rem; }

.menu-list { display: flex; flex-direction: column; gap: 2px; }
.menu-list button {
  text-align: left; background: transparent; border: none; color: var(--text);
  padding: 14px 6px; font-size: 0.95rem; border-radius: 8px; cursor: pointer;
  display: flex; align-items: center; gap: 12px;
}
.menu-list button:active { background: var(--card); }
.menu-list .desc { color: var(--muted); font-size: 0.76rem; }
.hint { color: var(--muted); font-size: 0.78rem; line-height: 1.4; }
.hint.warn { color: var(--warn); font-weight: 600; }

/* !important: some buttons (e.g. .fab.fab-secondary) set display:flex with higher
   specificity (2 classes) and would otherwise win over plain `.hidden` and keep
   the element visible. This is the only reliable way for a utility class. */
.hidden { display: none !important; }
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(90px + var(--safe-bottom)); z-index: 60;
  background: var(--card-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 16px; font-size: 0.85rem; box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  max-width: min(92vw, 420px); text-align: center;
}
/* A toast that does something has to look like it does something, or it reads
   as one more message that went past. */
.toast.is-tappable {
  cursor: pointer; border-color: var(--accent);
  box-shadow: 0 6px 20px rgba(0,0,0,0.45), inset 0 0 0 1px var(--accent);
}
.toast.is-tappable:active { transform: translateX(-50%) scale(0.98); }

/* Loader overlay (used during OCR) */
.loader-overlay {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(0,0,0,0.6);
  display: flex; align-items: center; justify-content: center;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.loader-card {
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 14px; padding: 20px 26px; min-width: 200px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  box-shadow: 0 10px 32px rgba(0,0,0,0.45);
}
.spinner {
  width: 32px; height: 32px;
  border: 3px solid var(--card-2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loader-msg { font-size: 0.84rem; color: var(--muted); text-align: center; }

/* ─────────────── Feed & Recommendations tab ─────────────── */

.feed-filter {
  display: flex; gap: 8px; margin-bottom: 12px;
}
.feed-filter-btn {
  flex: 1; padding: 8px 12px; border: 1px solid var(--line);
  background: var(--card); border-radius: 8px; font-size: 0.78rem;
  color: var(--muted); cursor: pointer; transition: all 0.2s;
}
.feed-filter-btn.active {
  background: var(--accent); color: var(--bg); border-color: var(--accent);
  font-weight: 600;
}

.feed-disclaimer {
  font-size: 0.72rem; color: var(--muted);
  background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; margin-bottom: 12px;
  line-height: 1.45;
}

/* ── Portfolio Risk Analysis (Overview tab) ── */
.pa-card .pa-sub {
  font-size: 0.72rem; color: var(--muted); margin: 0 0 12px;
}
.health-score {
  display: flex; align-items: center; gap: 12px;
  margin: 2px 0 12px; padding: 10px 11px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 10px;
}
.health-score.good { border-color: rgba(22,163,74,0.4); }
.health-score.neutral { border-color: rgba(251,191,36,0.38); }
.health-score.bad { border-color: rgba(239,68,68,0.42); }
.health-ring {
  flex: 0 0 58px; width: 58px; height: 58px; border-radius: 50%;
  border: 3px solid var(--line); display: flex; flex-direction: column;
  align-items: center; justify-content: center; background: var(--card);
}
.health-score.good .health-ring { border-color: #16a34a; }
.health-score.neutral .health-ring { border-color: var(--warn); }
.health-score.bad .health-ring { border-color: #ef4444; }
.health-num { font-size: 1.05rem; font-weight: 800; line-height: 1; }
.health-den { font-size: 0.58rem; color: var(--muted); margin-top: 1px; }
.health-copy { min-width: 0; flex: 1; }
.health-title { font-size: 0.86rem; font-weight: 700; }
.health-detail { font-size: 0.7rem; color: var(--muted); line-height: 1.35; margin-top: 3px; }
.pa-flag {
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: 8px; padding: 9px 11px; margin-bottom: 12px;
}
.pa-flag .pa-flag-t { font-size: 0.8rem; font-weight: 700; }
.pa-flag .pa-flag-d { font-size: 0.72rem; color: var(--muted); margin-top: 3px; line-height: 1.4; }
.pa-flag.good { border-left-color: #16a34a; }
.pa-flag.good .pa-flag-t { color: #16a34a; }
.pa-flag.bad { border-left-color: #ef4444; }
.pa-flag.bad .pa-flag-t { color: #ef4444; }
.pa-flag.neutral { border-left-color: var(--muted); }

.pa-section { margin-top: 16px; }
.pa-section .pa-h {
  font-size: 0.76rem; font-weight: 700; color: var(--text);
  margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.4px;
}
.pa-card .bar-fill.over { background: #ef4444; }

.pa-note {
  font-size: 0.7rem; color: var(--muted); margin-top: 8px;
  line-height: 1.4; padding: 6px 0;
}
.pa-note.bad { color: #ef4444; }

.pa-mood { display: flex; gap: 8px; }
.pa-mood-cell {
  flex: 1; text-align: center; padding: 10px 6px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 10px;
}
.pa-mood-cell.good { border-color: rgba(22,163,74,0.4); }
.pa-mood-cell.bad { border-color: rgba(239,68,68,0.4); }
.pa-mood-n { font-size: 1.2rem; font-weight: 700; }
.pa-mood-cell.good .pa-mood-n { color: #16a34a; }
.pa-mood-cell.bad .pa-mood-n { color: #ef4444; }
.pa-mood-k { font-size: 0.64rem; color: var(--muted); margin-top: 2px; }

.feed-actions {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 12px; flex-wrap: wrap;
}
.feed-schedule { display: flex; align-items: center; gap: 6px; flex: 1; flex-wrap: wrap; }
.feed-anchor { font-size: 0.78rem; font-weight: 600; color: var(--text); }
.feed-sep { color: var(--muted); font-size: 0.78rem; }
.feed-last { color: var(--muted); font-size: 0.78rem; }
.feed-sync-link {
  font-size: 0.78rem; color: var(--accent); cursor: pointer; text-decoration: underline;
}
.feed-sync-link:active { opacity: 0.6; }
.feed-status {
  font-size: 0.7rem; padding: 3px 8px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--line); color: var(--muted);
  margin-left: auto;
}
.feed-status.online  { color: #16a34a; border-color: rgba(22,163,74,0.4); }
.feed-status.offline { color: #f97316; border-color: rgba(249,115,22,0.4); }
.feed-status.nokey   { color: #ef4444; border-color: rgba(239,68,68,0.4); }

/* Section heading above the card list */
.feed-section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 4px 0 10px; flex-wrap: wrap;
}
.feed-section-title { font-size: 0.95rem; font-weight: 700; margin: 0; }
.feed-section-sub { font-size: 0.68rem; color: var(--muted); }

/* Every portfolio's day at a glance, above the selected one's own list. */
.feed-cross { display: flex; gap: 8px; margin: 10px 0; flex-wrap: wrap; }
.feed-cross-item {
  flex: 1 1 0; min-width: 96px; display: flex; flex-direction: column; gap: 3px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card);
}
.feed-cross-item.active { border-color: var(--accent); background: var(--card-2); }
.feed-cross-label { font-size: 0.66rem; color: var(--muted); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.feed-cross-stat { font-size: 0.7rem; color: var(--muted); }
.feed-cross-stat.muted { opacity: 0.7; }
.feed-cross-stat .fc-today { color: var(--text); font-weight: 700; }
.feed-cross-stat .fc-flag { color: var(--text); font-weight: 700; }
.feed-cross-stat .fc-flag.on { color: #f97316; }

/* What moved since the last check - suppressed entirely when nothing did. */
.feed-digest {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 10px 0; padding: 7px 11px; border-radius: 10px;
  background: var(--card); border: 1px solid var(--line); font-size: 0.74rem; font-weight: 600;
}
.feed-digest-up { color: #16a34a; }
.feed-digest-down { color: #ef4444; }
.feed-digest-note { color: var(--muted); font-weight: 500; font-size: 0.68rem; }

/* "was X" under a card's badge, when today's call differs from the last. */
.feed-changed { display: flex; align-items: center; gap: 5px; font-size: 0.68rem; color: var(--muted); }
.feed-changed .fc-arrow { font-size: 0.6rem; }
.feed-changed.up .fc-arrow { color: #16a34a; }
.feed-changed.down .fc-arrow { color: #ef4444; }

.feed-list { display: flex; flex-direction: column; gap: 0; }
.feed-item { display: flex; flex-direction: column; margin-bottom: 10px; }
.feed-timeline { display: flex; align-items: center; gap: 8px; padding: 4px 14px 2px; }
.ft-dots { display: flex; gap: 5px; align-items: center; }
.ft-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.ft-dot.pos { background: #16a34a; }
.ft-dot.neg { background: #ef4444; }
.ft-dot.neu { background: var(--muted); opacity: 0.45; }
.ft-today { font-size: 0.66rem; color: var(--muted); }

.feed-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 14px; padding: 12px 14px;
  display: flex; flex-direction: column; gap: 7px;
}
.feed-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.feed-stock { font-weight: 700; font-size: 0.95rem; }

/* Row 2 — sentiment flag pill + article count */
.feed-flag-row { display: flex; align-items: center; gap: 8px; }
.feed-flag {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.2px;
  padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card-2);
}
.feed-flag.pos { color: #16a34a; background: rgba(22,163,74,0.12);  border-color: rgba(22,163,74,0.4); }
.feed-flag.neg { color: #ef4444; background: rgba(239,68,68,0.12);  border-color: rgba(239,68,68,0.4); }
.feed-flag.mix { color: #d97706; background: rgba(217,119,6,0.12);  border-color: rgba(217,119,6,0.4); }
.feed-flag.neu { color: var(--muted); }
.feed-flag.muted { font-weight: 600; background: transparent; }
.feed-count { font-size: 0.7rem; color: var(--muted); }

/* Transparent article-count breakdown next to the verdict pill */
.feed-breakdown { display: inline-flex; gap: 6px; align-items: center; }
.feed-breakdown .fb {
  font-size: 0.66rem; font-weight: 700; padding: 1px 6px; border-radius: 6px;
  background: var(--card-2); border: 1px solid var(--line);
}
.feed-breakdown .fb.pos { color: #16a34a; }
.feed-breakdown .fb.neg { color: #ef4444; }
.feed-breakdown .fb.neu { color: var(--muted); }

.feed-reason { font-size: 0.79rem; color: var(--text); opacity: 0.88; line-height: 1.45; }
.feed-expand-hint { font-size: 0.7rem; color: var(--accent); font-weight: 600; }

/* Sentiment detail strip (inside expanded panel) */
.feed-sent-detail {
  display: flex; gap: 8px; margin-bottom: 4px;
}
.feed-sent-item {
  flex: 1; display: flex; flex-direction: column; gap: 2px;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: 9px; padding: 7px 9px;
}
.feed-sent-k { font-size: 0.62rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.feed-sent-v { font-size: 0.92rem; font-weight: 700; }
.feed-sent-v.pos { color: #16a34a; }
.feed-sent-v.neg { color: #ef4444; }
.feed-sent-v.mix { color: #d97706; }
.feed-sent-v.neu { color: var(--muted); }
.feed-sent-x { font-size: 0.6rem; color: var(--muted); }

.feed-badge {
  flex: 0 0 auto;
  font-size: 0.72rem; font-weight: 600;
  padding: 4px 10px; border-radius: 999px;
  white-space: nowrap;
  background: var(--card-2); border: 1px solid var(--line); color: var(--text);
}
.feed-badge.red    { background: rgba(239,68,68,0.12);  border-color: rgba(239,68,68,0.45);  color: #ef4444; }
.feed-badge.orange { background: rgba(249,115,22,0.12); border-color: rgba(249,115,22,0.45); color: #f97316; }
.feed-badge.green  { background: rgba(22,163,74,0.12);  border-color: rgba(22,163,74,0.45);  color: #16a34a; }
.feed-badge.blue   { background: rgba(59,130,246,0.12); border-color: rgba(59,130,246,0.45); color: #3b82f6; }
.feed-badge.grey   { background: var(--card-2); border-color: var(--line); color: var(--muted); }

.feed-articles {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 6px; padding-top: 8px;
  border-top: 1px solid var(--line);
}
.feed-article {
  display: flex; flex-direction: column; gap: 3px;
  padding: 6px 0;
}
.feed-article-title {
  font-size: 0.84rem; font-weight: 600; color: var(--text);
  line-height: 1.35;
}
.feed-article-title a { color: inherit; text-decoration: none; }
.feed-article-title a:active { color: var(--accent); }
.feed-article-summary { font-size: 0.74rem; color: var(--muted); line-height: 1.4; }
.feed-article-meta {
  font-size: 0.66rem; color: var(--muted);
  display: flex; gap: 8px; align-items: center; margin-top: 2px;
}
.feed-article-source { font-weight: 600; }
.feed-article-sentiment {
  font-size: 0.6rem; font-weight: 600; padding: 1px 7px; border-radius: 999px;
  background: var(--card-2); border: 1px solid var(--line); color: var(--muted);
  margin-left: auto;
}
.feed-article-sentiment.pos { color: #16a34a; border-color: rgba(22,163,74,0.4); }
.feed-article-sentiment.neg { color: #ef4444; border-color: rgba(239,68,68,0.4); }
.feed-article-sentiment.neu { color: var(--muted); }

.feed-empty {
  text-align: center; color: var(--muted);
  padding: 24px 12px; font-size: 0.86rem;
}

/* ─────────────── Backup & Restore sheet ─────────────── */

.backup-folder {
  display: flex; align-items: center; gap: 6px;
  font-size: 0.78rem; color: var(--muted);
  padding: 4px 0 14px;
  flex-wrap: wrap;
}
.backup-folder-label { color: var(--muted); }
.backup-folder-name { color: var(--text); font-weight: 600; }
.backup-folder-change { margin-left: auto; }

.backup-actions {
  display: flex; align-items: center; gap: 12px;
  padding: 4px 0 14px;
}
.backup-actions .btn { flex: 0 0 auto; }
.backup-last { color: var(--muted); font-size: 0.78rem; }

.backup-section-title {
  margin: 6px 0 8px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  font-weight: 600;
}

.backup-list { display: flex; flex-direction: column; gap: 6px; }
.backup-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.backup-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.backup-date { font-weight: 600; font-size: 0.86rem; color: var(--text); }
.backup-detail { font-size: 0.72rem; color: var(--muted); }

.menu-foot {
  padding-top: 12px;
  border-top: 1px solid var(--line);
  margin-top: 14px;
}

/* ─────────────── App lock (PIN + biometric) ───────────────
   The lock-screen overlay (full viewport, z-index above modals) and a
   lock-card variant rendered inside a modal sheet for Setup / Change PIN.
   Both share the same internals (.pin-dots + .kpad) so the visual language
   stays consistent. */

body.locked { overflow: hidden; }

.lock-screen {
  position: fixed; inset: 0; z-index: 90;
  background: linear-gradient(160deg, var(--bg) 0%, var(--bg-2) 100%);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: lock-fade-in 0.28s ease-out;
}
.lock-screen.fade-out { animation: lock-fade-out 0.24s ease-in forwards; }
@keyframes lock-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes lock-fade-out { from { opacity: 1; } to { opacity: 0; } }

.lock-screen.shake .lock-card { animation: lock-shake 0.42s cubic-bezier(.36,.07,.19,.97); }
@keyframes lock-shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-8px); }
  40%, 60% { transform: translateX(8px); }
}

.lock-card {
  width: 100%; max-width: 340px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 26px 22px 18px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.45), 0 2px 8px rgba(0,0,0,0.2);
}
/* Modal-embedded variant (Setup / Change PIN) — no fixed positioning. */
.lock-card-modal { margin: 0 auto; }

.lock-logo {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--card);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem;
  border: 1px solid var(--line);
  margin-bottom: 4px;
}

.lock-title {
  font-size: 1.15rem; font-weight: 700; color: var(--text);
  letter-spacing: 0.2px; text-align: center;
}

.lock-sub {
  font-size: 0.82rem; color: var(--muted);
  text-align: center; min-height: 1.2em;
  margin-bottom: 8px;
}

.lock-error {
  font-size: 0.78rem; color: #ef4444;
  min-height: 1.1em; text-align: center;
  margin-top: -2px;
}

/* PIN-progress dots */
.pin-dots {
  display: flex; gap: 14px;
  margin: 6px 0 8px;
}
.pin-dot {
  width: 13px; height: 13px;
  border-radius: 50%;
  border: 1.5px solid var(--muted);
  background: transparent;
  transition: background 0.12s ease, transform 0.12s ease, border-color 0.12s ease;
}
.pin-dot.filled {
  background: var(--accent);
  border-color: var(--accent);
  transform: scale(1.1);
}

/* Numeric keypad */
.kpad {
  display: grid;
  grid-template-columns: repeat(3, 70px);
  grid-auto-rows: 60px;
  gap: 10px;
  margin-top: 6px;
}
.kpad .kp {
  font-size: 1.35rem; font-weight: 500;
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 14px;
  cursor: pointer;
  transition: background 0.1s ease, transform 0.06s ease;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
.kpad .kp:active { background: var(--card-2); transform: scale(0.96); }
.kpad .kp-empty { background: transparent; border: none; }
.kpad .kp-bio { font-size: 1.5rem; }
.kpad .kp-back { font-size: 1.2rem; color: var(--muted); }

.lock-foot {
  margin-top: 14px;
}
.link-btn {
  background: none; border: none;
  color: var(--muted); font-size: 0.78rem;
  cursor: pointer; padding: 6px 10px; border-radius: 6px;
  text-decoration: underline; text-decoration-color: rgba(0,0,0,0.25);
}
.link-btn:active { color: var(--text); }

.lock-bio-row {
  display: flex; gap: 10px; margin-top: 14px; width: 100%;
}
.lock-bio-row .btn { flex: 1; }

/* Compact keypad on narrow phones — keep buttons fully tappable but fit width. */
@media (max-width: 360px) {
  .kpad { grid-template-columns: repeat(3, 64px); grid-auto-rows: 56px; gap: 8px; }
  .kpad .kp { font-size: 1.25rem; }
}

/* ─────────────── Home launcher (Stocks / Mutual Funds) ─────────────── */
/* Name on the left, date on the right. Baseline-aligned so the date sits with
   the title rather than floating against the top of a two-line block. */
.home-hero { padding: 22px 2px 6px; display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.home-hero-left { min-width: 0; display: flex; align-items: center; gap: 10px; }
.home-hero-text { min-width: 0; }
.home-hero-right { flex: 0 0 auto; text-align: right; }
.home-title { margin: 0; font-size: 2.4rem; line-height: 1; font-weight: 800; letter-spacing: 0.3px;  }
.home-ver { margin-top: 3px; font-size: 0.66rem; line-height: 1; font-weight: 700; letter-spacing: 0.3px; color: var(--muted); opacity: 0.8; }
.home-title-ico { width: 58px; height: 58px; border-radius: 13px; flex: 0 0 auto; }
.home-tag { margin: 4px 0 0; color: var(--muted); font-size: 0.72rem; line-height: 1.35; white-space: nowrap; }

/* Bigger than the tagline, smaller than the name - it is the second thing you
   read, not the first. */
.home-today { font-size: 1.15rem; font-weight: 800; letter-spacing: -0.2px; white-space: nowrap; }
.home-days { margin-top: 3px; font-size: 0.74rem; font-weight: 700; color: var(--accent); white-space: nowrap; }
/* The last few days of a month are worth noticing, not just reading. */
.home-days.is-tight { color: var(--warn); }
.home-summary { display: flex; gap: 12px; margin-top: 16px; }
.summary-stat { flex: 1; background: linear-gradient(135deg, var(--card), var(--card-2)); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 12px; display: flex; flex-direction: column; gap: 4px; }
.stat-label { color: var(--muted); font-size: 0.75rem; display: flex; align-items: center; gap: 6px; }
/* Small circled "i" next to a headline figure — opens a sheet explaining what
   the number is made of. Sized off the label so it never dominates it. */
.info-btn {
  flex: 0 0 auto; width: 15px; height: 15px; padding: 0; line-height: 1;
  border-radius: 50%; border: 1px solid var(--line);
  background: var(--card-2); color: var(--muted);
  font-size: 0.62rem; font-weight: 700; font-style: italic; font-family: Georgia, serif;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.info-btn:hover { color: var(--text); border-color: var(--muted); }

/* Same idea as .info-btn, sized for an emoji glyph instead of the italic "i" —
   opens the Emergency Fund contribution-projection calculator. */
.calc-btn {
  flex: 0 0 auto; width: 18px; height: 18px; padding: 0; line-height: 1;
  border-radius: 50%; border: 1px solid var(--line);
  background: var(--card-2); color: var(--muted);
  font-size: 0.62rem;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.calc-btn:hover { color: var(--text); border-color: var(--muted); }
.summary .cell .k.ef-k-icon { display: flex; align-items: center; gap: 5px; }

/* Contribution projection popup (the 🧮 next to "Collected") */
.ef-proj-current {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 12px; background: var(--card-2); border: 1px solid var(--line);
  border-radius: 10px; margin-bottom: 14px;
}
.ef-proj-current .bl { color: var(--muted); font-size: 0.82rem; }
.ef-proj-current .bn { font-size: 1.05rem; font-weight: 700; }
.ef-proj-big {
  background: var(--card-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; margin-top: 12px; text-align: center;
}
.ef-proj-big .label { color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.4px; }
.ef-proj-big .big { font-size: 1.6rem; font-weight: 700; margin: 4px 0; color: var(--accent); }
.ef-proj-big .hint { font-size: 0.7rem; margin: 0; }
.ef-proj-months { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ef-proj-month {
  flex: 0 0 auto; background: var(--card); border: 1px solid var(--line); border-radius: 999px;
  padding: 7px 13px; font-size: 0.8rem; color: var(--text); cursor: pointer;
}
.ef-proj-month.active { background: var(--accent); border-color: var(--accent); color: #06243a; font-weight: 700; }

/* Emergency Fund — Rules tab (the written policy) */
.ef-rules { display: flex; flex-direction: column; }
.ef-rule { display: flex; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line); }
.ef-rule:first-child { border-top: none; padding-top: 0; }
.ef-rule-num {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  background: var(--card-2); border: 1px solid var(--line); color: var(--accent);
  font-size: 0.7rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.ef-rule-body { flex: 1 1 auto; min-width: 0; }
.ef-rule-text { font-size: 0.84rem; line-height: 1.4; }
.ef-rule-sub { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.ef-rule-sub-row {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 0.76rem; padding: 5px 9px;
  background: var(--card-2); border-radius: 8px;
}
.ef-rule-sub-v { color: var(--accent); font-weight: 700; white-space: nowrap; }

/* Credit card month grid (Expense → Credit Card). Reuses .heatmap-scroll /
   table.heatmap for the sticky-header + horizontal-scroll mechanics; these
   overrides only change what's specific to a money grid (right-aligned figures,
   a wider first column for card names, and a divider above the summary rows). */
.cc-scroll { max-height: none; }
.cc-grid td { text-align: right; font-weight: 600; }
.cc-grid th.rowhead, .cc-grid th.corner { max-width: none; white-space: nowrap; font-weight: 600; }
.cc-grid tr.cc-sum th.rowhead { color: var(--muted); font-weight: 700; }
.cc-grid tr.cc-sum:first-of-type th, .cc-grid tr.cc-sum:first-of-type td { border-top: 2px solid var(--line); }
/* "To be paid" row: heatmap background from cc-heat-* (trend vs previous
   month) layers UNDER cc-fully-paid (a ring + extra-bold text, once every
   card billed that month is marked settled) — two independent signals, so
   neither one's color should stomp the other's. */
.cc-grid td.cc-heat-better { background: rgba(52,211,153,0.4); border-radius: 4px; }
.cc-grid td.cc-heat-worse { background: rgba(248,113,113,0.4); border-radius: 4px; }
.cc-grid td.cc-heat-flat { background: transparent; }
.cc-grid td.cc-fully-paid { font-weight: 800; box-shadow: inset 0 0 0 1px rgba(52,211,153,0.55); border-radius: 4px; }

.btn.warn { background: var(--warn); color: #3a2405; }

/* Month timeline strip above the card list — tap a month to view/edit that
   specific bill. Same bare horizontal-scroll-rail technique as
   .due-soon-rail, just without its "more to scroll" fade (a month strip is
   expected to run long, unlike a short due-soon list). */
.cc-timeline-scroll { overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin: 4px 0 14px; }
.cc-timeline-scroll::-webkit-scrollbar { display: none; }
/* Fixed under the app header (its `top` is set inline in app.js, from the
   header's measured height) so the month picker stays reachable while the
   card list, reimbursement box and grid scroll underneath it. An opaque
   background + z-index below the header's own (20) so it reads as a second,
   lower band rather than letting content show through or covering the
   header itself. Horizontal side padding compensates for the page's own
   edge padding, which this element no longer scrolls past when pinned. */
.cc-timeline-sticky { position: sticky; z-index: 15; background: var(--bg); padding: 8px 0; margin: 0 -14px 10px; }
.cc-timeline-sticky .cc-timeline { padding: 0 14px 2px; }
.cc-timeline { display: flex; gap: 6px; padding-bottom: 2px; }
.cc-timeline-chip {
  flex: 0 0 auto; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card-2); color: var(--muted);
  font-size: 0.76rem; font-weight: 600; white-space: nowrap; cursor: pointer;
}
.cc-timeline-chip.is-current { border-color: var(--accent); }
/* Selected chip — matches the app's own subdued "selected tab" convention
   (.seg button.active: card-2 fill, text colour, bold) rather than a loud
   solid accent fill, with an accent ring to still read clearly as chosen. */
.cc-timeline-chip.active { background: var(--card-2); border-color: var(--accent); color: var(--text); font-weight: 700; box-shadow: inset 0 0 0 1px var(--accent); }
/* Fully paid — every card billed that month has a status set. A green ring
   so it's visible whether or not the chip is also the active selection
   (which already owns the accent background); tinted fill only when it
   ISN'T selected, so the two states never compete for the same background. */
.cc-timeline-chip.is-paid { border-color: var(--good); }
.cc-timeline-chip.is-paid:not(.active) { background: rgba(52,211,153,0.18); color: var(--good); }
.cc-timeline-chip.is-paid.active { box-shadow: inset 0 0 0 2px var(--good); }

/* Card list: this-month status, read-only (set from the card's own
   Details > Months tab, not from here). Ontime shows as a "Paid" badge
   (.cc-status-badge, reuses .badge.good) — from outside the editor, settled
   vs not is what matters; the Ontime/Late distinction stays in the editor. */
.cc-status-badge { font-weight: 700; }
/* Average-usage-vs-limit badge next to "Avg use ₹X" — always green, unlike
   the month-specific "% used" badge above (which warns past 30%): this is a
   steady long-term figure, not something to flag. */
.cc-avg-util-badge { margin-left: 6px; font-weight: 700; }
.cc-status-late { color: var(--bad); font-weight: 700; }
.cc-status-unpaid { color: var(--warn); font-weight: 700; }
/* Card name row — the selected month's usage badge sits beside the name
   (it's the figure that changes with the timeline selection), not down in
   the static bank/limit line. */
.cc-name-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* This list isn't the last thing on the page (the reimbursement box and
   grid follow it) so it doesn't need .stock-list's shared FAB-clearance
   padding-bottom — that was showing up as a large, out-of-place gap before
   the reimbursement box. */
.cc-card-list { padding-bottom: 0; }

/* Common per-month reimbursement box below the card list */
.cc-reimb-card { margin-top: 10px; }
.cc-reimb-card input {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--card-2); color: var(--text); font-size: 0.95rem;
}
.cc-reimb-card input:focus { outline: none; border-color: var(--accent); }

/* "What makes up Total Invested" sheet */
.brk-head { display: flex; justify-content: space-between; color: var(--muted); font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: 0.5px; padding: 0 0 6px; border-bottom: 1px solid var(--line); }
.brk-list { display: flex; flex-direction: column; }
.brk-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--line); }
.brk-row:last-child { border-bottom: none; }
.brk-main { min-width: 0; }
.brk-name { font-size: 0.92rem; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.brk-count { font-size: 0.62rem; font-weight: 700; color: var(--muted);
  background: var(--card-2); border: 1px solid var(--line); border-radius: 999px; padding: 1px 6px; }
/* Me · US's own count on the Stocks row - blue, right beside India's badge. */
.brk-count-us { color: #fff; background: #3b82f6; border-color: #3b82f6; }
/* Metals row - gold/silver gram totals, same pill shape as brk-count-us. */
.brk-count-gold { color: #3a2a00; background: #d4a017; border-color: #d4a017; }
.brk-count-silver { color: #1f2937; background: #c0c7d1; border-color: #c0c7d1; }
.brk-note { font-size: 0.7rem; color: var(--muted); margin-top: 3px; line-height: 1.35; }
.brk-nums { text-align: right; flex: 0 0 auto; }
.brk-inv { font-size: 0.95rem; font-weight: 700; display: flex; align-items: baseline; justify-content: flex-end; gap: 6px; }
/* Share of Total Invested, pinned beside the rupee figure it divides into.
   Muted and chip-shaped so it reads as context for that amount rather than
   competing with it or with the return % on the line below. */
.brk-alloc { font-size: 0.66rem; font-weight: 700; color: var(--muted); background: var(--bg-2);
  border: 1px solid var(--line); padding: 1px 7px; border-radius: 999px; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.brk-earn { font-size: 0.72rem; margin-top: 2px; display: flex; align-items: center; justify-content: flex-end; gap: 4px; white-space: nowrap; }
.brk-pct { font-weight: 700; }
.brk-pct.muted { color: var(--muted); font-weight: 400; }
.brk-total { border-top: 2px solid var(--line); margin-top: 2px; padding-top: 12px; }
.brk-total .brk-name { font-size: 1rem; }
.brk-total .brk-inv { font-size: 1.1rem; }
.stat-value { font-size: 1.15rem; font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 6px; }
.summary-badge { font-size: 0.82rem; padding: 4px 8px; border-radius: 6px; font-weight: 600; color: #fff; }
.summary-badge.pos { background: linear-gradient(135deg, #10b981, #34d399); }
.summary-badge.neg { background: linear-gradient(135deg, #ef4444, #f87171); }
.summary-badge.flat { background: linear-gradient(135deg, #6b7280, #9ca3af); }
.home-cards { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
.home-card {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  background: linear-gradient(135deg, var(--card), var(--card-2));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 16px; cursor: pointer; color: var(--text);
}
.home-card:active { background: var(--card-2); }
.home-card-ico {
  flex: 0 0 auto; font-size: 1.7rem; width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 14px;
}
/* A resting heartbeat's own rhythm (lub-dub, pause) rather than a plain
   even pulse - two quick beats then a longer rest. transform-only (no width/
   height/layout change), so it's GPU-composited: the browser runs it on the
   compositor thread same as a video decode, untouched by JS or layout work
   elsewhere in the app, and it costs nothing while the Health Check card
   isn't even on screen since the animation is scoped to its own element. */
@keyframes home-card-beat {
  0%, 40%, 100% { transform: scale(1); }
  15% { transform: scale(1.14); }
  30% { transform: scale(1.05); }
}
.home-card-beat { animation: home-card-beat 1.8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .home-card-beat { animation: none; }
}
.metal-bar-ico { display: flex; align-items: center; justify-content: center; }
.metal-bar-ico svg { width: 30px; height: 30px; display: block; }
img.metal-bar-ico { width: 30px; height: 30px; object-fit: contain; display: block; }
.home-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.home-card-title { font-size: 1.05rem; font-weight: 700; }
.home-card-sub { font-size: 0.76rem; color: var(--muted); }
.home-card-arrow { flex: 0 0 auto; color: var(--muted); font-size: 1.5rem; line-height: 1; }
.home-rates { margin-top: 14px; }
.home-rates-row { display: flex; gap: 8px; }
.home-rate-box {
  flex: 1 1 0; min-width: 0; background: var(--card-2); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 8px; text-align: center;
}
.home-rate-lbl { font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.home-rate-val { font-size: 0.92rem; font-weight: 800; margin-top: 3px; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.home-rate-sub { font-size: 0.6rem; color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 0.9em; }
.home-rates-foot { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 6px; }
.home-rate-asof { font-size: 0.64rem; color: var(--muted); }
.home-rate-refresh, .home-rate-settings {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--card); color: var(--muted); font-size: 0.8rem; line-height: 1;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.home-rate-settings { font-size: 0.62rem; font-weight: 800; }
.home-rate-refresh.spinning { animation: homeRateSpin 0.8s linear infinite; }
@keyframes homeRateSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .home-rate-refresh.spinning { animation: none; } }


/* Back button in the header (shown in Stocks/MF modes) */
#backBtn { font-size: 1.7rem; padding: 6px 8px; }

/* ─────────────── Mutual Funds surface ─────────────── */
.mf-toolbar { justify-content: space-between; }
.mf-sortbar { margin-left: auto; }
.mf-foot { margin-top: 14px; padding-bottom: 20px; }
.mf-view .stock-list { padding-bottom: 20px; }
/* FD ladder — maturity-ordered rungs (date chip · bank · maturity value) */
.fd-ladder { display: flex; flex-direction: column; gap: 10px; padding-bottom: 20px; }
.fd-ladder-row { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.fd-ladder-date { flex: 0 0 auto; width: 44px; text-align: center; }
.fd-ladder-mon { font-weight: 700; font-size: 0.9rem; }
.fd-ladder-yr { font-size: 0.68rem; color: var(--muted); }
.fd-ladder-body { flex: 1; min-width: 0; }
.fd-ladder-body .name { font-size: 0.9rem; font-weight: 600; }
.fd-ladder-body .cat { font-size: 0.72rem; color: var(--muted); }
.fd-ladder-val { flex: 0 0 auto; }
.fd-ladder-row.fd-done { opacity: 0.58; }
/* Gap rung — a month with no FD maturing (dashed, not tappable) */
.fd-ladder-gap { cursor: default; border-style: dashed; opacity: 0.7; }
.fd-ladder-gap .fd-ladder-body .name { color: var(--muted); font-weight: 600; }
/* FD summary — "Current invested" line under the big Total invested number */
.fd-subline { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }
/* FD form → Chain tab: the reinvestment chain (funded-from → this → rolled-into) */
.fd-chain { display: flex; flex-direction: column; gap: 8px; }
.fd-chain-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; cursor: pointer; }
.fd-chain-row .fd-chain-body { min-width: 0; }
.fd-chain-row .name { font-size: 0.9rem; font-weight: 600; }
.fd-chain-row .cat { font-size: 0.72rem; color: var(--muted); }
.fd-chain-int { flex: 0 0 auto; font-weight: 600; font-size: 0.9rem; }
.fd-chain-current { border-color: var(--accent); cursor: default; }
/* FD form → "Funded by" checkbox list (tick matured FDs to merge in) */
.fd-parent-list { display: flex; flex-direction: column; gap: 6px; }
.fd-parent-row { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.82rem; }
.fd-parent-row input { flex: 0 0 auto; }
.mf-catline { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mf-beat { font-size: 0.62rem; padding: 1px 6px; }
/* Invested · Value on one line with Value emphasized */
.card .sub.mf-sub2 { gap: 8px; font-size: 0.78rem; display: flex; align-items: flex-start; justify-content: space-between; }
.card .sub.mf-sub2 span:first-child { display: flex; flex-direction: column; gap: 0px; align-items: flex-start; }
.card .sub.mf-sub2 .value-emphasis { display: flex; align-items: center; gap: 4px; font-size: 0.88rem; font-weight: 600; }
.card .sub.mf-sub2 .value-emphasis .mf-value-card { font-size: 0.82rem; font-weight: 600; padding: 6px 10px; }
.mf-meta-mini { font-size: 0.62rem; color: var(--muted); margin-top: 2px; }
/* Legacy: Invested · Value · XIRR on one line — XIRR pinned to the right end */
.card .sub.mf-sub3 { gap: 8px; font-size: 0.78rem; }
.card .sub.mf-sub3 span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card .sub.mf-sub3 span:last-child { margin-left: auto; text-align: right; }
.mf-actions { margin-top: 10px; }
.mf-value-list { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 4px; max-height: 46vh; overflow-y: auto; }
.mf-value-row { display: flex; align-items: center; gap: 10px; }
.mf-value-name { flex: 1; min-width: 0; font-size: 0.82rem; display: flex; flex-direction: column; gap: 2px; }
.mf-value-name > div:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mf-value-cap { font-size: 0.68rem; color: var(--muted); }
.mf-value-row input { flex: 0 0 38%; }

/* Transaction log row — two tidy lines: (date · amount) then (units · NAV).
   Inputs here sit directly in a .txn-line, not a .field wrapper, so they miss
   the app's normal `.field input` theming entirely and fall back to bare
   browser-default styling (white background, black text, inset border) - a
   glaring mismatch against the rest of the dark UI. Themed explicitly below. */
.mf-txn-row {
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px; background: var(--card);
  border: 1px solid var(--line); border-radius: 10px;
}
.mf-txn-row--sell { border-left: 3px solid var(--bad); }
.txn-line { display: flex; gap: 8px; align-items: center; }
.mf-txn-row input {
  flex: 1 1 0; width: auto; min-width: 0;
  background: var(--card-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; font-size: 0.85rem;
}
.mf-txn-row input:focus { outline: none; border-color: var(--accent); }
.mf-txn-row input::placeholder { color: var(--muted); }
.mf-txn-row .icon-btn { flex: 0 0 auto; color: var(--muted); border-radius: 8px; }
.mf-txn-row .icon-btn:hover, .mf-txn-row .icon-btn:active { color: var(--bad); background: var(--card-2); }
/* Credit card month editor's Ontime/Late Payment status dropdown — same
   dark-theme treatment as .mf-txn-row input (selects don't inherit it). */
.mf-txn-row select.cc-status-select {
  flex: 0 0 auto; width: auto; min-width: 0;
  background: var(--card-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; font-size: 0.8rem;
}
.mf-txn-row select.cc-status-select:focus { outline: none; border-color: var(--accent); }

/* Buy/Sell summary caption + empty state above each transaction list */
.mf-txn-pane { margin-top: 10px; }
.mf-txn-summary { display: flex; justify-content: space-between; gap: 10px; font-size: 0.78rem; color: var(--muted); padding: 0 2px 8px; }
.mf-txn-empty { padding: 24px 10px; text-align: center; color: var(--muted); font-size: 0.85rem; border: 1px dashed var(--line); border-radius: 10px; }
.mf-txn-btn-row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; padding-right: 2px; }
.mf-txn-btn-row .icon-btn { font-size: 1.5rem; padding: 8px 10px; }

/* Bond Schedule tab: read-only projected cash-flow rows (date / interest /
   principal / balance left). Scrolls internally — a monthly 5-year bond is 60
   rows and must not push the sheet footer away. */
.bond-sched { max-height: 46vh; overflow-y: auto; -webkit-overflow-scrolling: touch; margin-top: 8px; }
.bond-sched-row {
  display: grid; grid-template-columns: 1.25fr 1fr 1fr 1fr; gap: 6px;
  padding: 7px 4px; border-bottom: 1px solid var(--line);
  font-size: 0.76rem; font-variant-numeric: tabular-nums;
}
.bond-sched-row span:not(:first-child) { text-align: right; }
.bond-sched-head {
  position: sticky; top: 0; background: var(--card);
  font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--muted); font-weight: 700;
}
/* Already-passed installments recede so the next one to land reads as the live
   edge of the schedule. */
.bond-sched-row.is-past { opacity: 0.5; }

/* Fund Holdings tab: units-held / avg-NAV readout, sits above the Buy/Sell
   sub-tabs and stays live as the log is edited. */
.mf-units-info {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 10px 12px; margin-bottom: 10px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  font-size: 0.85rem;
}
.mf-units-info b { color: var(--accent); }

/* Benchmark tab live readout */
.mf-bench-readout { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.mf-bench-now { display: flex; justify-content: space-between; gap: 10px; font-size: 0.82rem; }
.mf-bench-status { margin-top: 8px; }
.mf-bench-badge { font-size: 0.72rem; padding: 3px 10px; }

/* Tab layout (Holdings | Overview via #mfBottomNav; Edit fund | Fund Holdings | Benchmark via .seg) */
.tab-content { display: block; }
.tab-content.hidden { display: none; }
.icon-only { padding: 6px 8px; font-size: 1.3rem; }

/* Toolbar with icon button for Update values */
.mf-toolbar-top { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.mf-toolbar-top .seg { flex: 1; }
.mf-toolbar-top .sortbar { margin-left: auto; flex: 1; }
.mf-toolbar-top .icon-btn { flex: 0 0 auto; padding: 6px 8px; }

/* Fund form: fixed Save/Cancel footer + independently scrollable body, so a long
   investment log doesn't bury the buttons or the +Add/OCR controls below it. */
.sheet.has-fixed-footer { display: flex; flex-direction: column; padding: 0; max-height: 92vh; overflow: hidden; }
.sheet.has-fixed-footer .sheet-scroll { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 16px 16px 8px; flex: 1; min-height: 0; }
.sheet.has-fixed-footer .sheet-footer { flex: 0 0 auto; padding: 12px 16px calc(14px + var(--safe-bottom)); border-top: 1px solid var(--line); background: var(--bg-2); }
.sheet.has-fixed-footer .sheet-footer .btn-row { margin-top: 0; }
.mf-txn-rows { max-height: 38vh; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-right: 2px; }

/* Fund value card with gradient backgrounds */
.mf-value-card {
  padding: 8px 12px;
  border-radius: 10px;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(135deg, #10b981, #34d399);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
  display: inline-block;
}

.mf-value-card.positive {
  background: linear-gradient(135deg, #10b981, #34d399);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
}

.mf-value-card.negative {
  background: linear-gradient(135deg, #ef4444, #f87171);
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
}

html[data-theme="light"] .mf-value-card.positive {
  background: linear-gradient(135deg, #15803d, #22c55e);
  box-shadow: 0 4px 12px rgba(21, 128, 61, 0.25);
}

html[data-theme="light"] .mf-value-card.negative {
  background: linear-gradient(135deg, #dc2626, #ef4444);
  box-shadow: 0 4px 12px rgba(220, 38, 38, 0.25);
}

/* Benchmark tab visualization */
.mf-bench-list { display: flex; flex-direction: column; gap: 12px; padding: 0 0 20px; }
.mf-bench-row { padding: 12px; border: 1px solid var(--line); border-radius: 10px; }
.mf-bench-name { font-weight: 600; font-size: 0.9rem; margin-bottom: 10px; }
.mf-bench-bar { display: flex; align-items: center; gap: 8px; font-size: 0.72rem; }
.mf-bench-low, .mf-bench-high { color: var(--muted); flex: 0 0 auto; min-width: 35px; }
.mf-bench-low { text-align: right; }
.mf-bench-high { text-align: left; }
.mf-bench-peak-row { border-color: var(--good); }
.mf-bench-bottom-row { border-color: var(--bad); }
/* Normal rows reserve room below the bar for the value badge under the marker dot */
.mf-bench-row--badge { padding-bottom: 30px; }

/* Benchmark sub-tabs */
.mf-bench-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.mf-bench-tabs .sort-btn { flex: 1; }

/* Gradient colors: Returns = light-to-dark green, XIRR = yellow-to-orange */
:root {
  --bench-ret-light: #86efac;
  --bench-ret-dark: #16a34a;
  --bench-xirr-light: #fde047;
  --bench-xirr-dark: #f97316;
}

html[data-theme="light"] {
  --bench-ret-light: #4ade80;
  --bench-ret-dark: #15803d;
  --bench-xirr-light: #fbbf24;
  --bench-xirr-dark: #ea580c;
}

/* Thin track — the marker dot (below) is intentionally bigger than this bar */
.mf-bench-track { flex: 1; height: 8px; background: var(--card-2); border-radius: 6px; position: relative; overflow: visible; }
.mf-bench-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 6px 0 0 6px; z-index: 1; }
.mf-bench-track.ret .mf-bench-fill { background: linear-gradient(90deg, var(--bench-ret-light), var(--bench-ret-dark)); }
.mf-bench-track.xirr .mf-bench-fill { background: linear-gradient(90deg, var(--bench-xirr-light), var(--bench-xirr-dark)); }
.mf-bench-track.ret::before, .mf-bench-track.xirr::before {
  content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  border-radius: 6px; opacity: 0.18; z-index: 0;
}
.mf-bench-track.ret::before { background: linear-gradient(90deg, var(--bench-ret-light), var(--bench-ret-dark)); }
.mf-bench-track.xirr::before { background: linear-gradient(90deg, var(--bench-xirr-light), var(--bench-xirr-dark)); }

/* Current-position marker — a bold white dot, visibly larger than the thin track */
.mf-bench-marker {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  width: 18px; height: 18px; background: #fff; border-radius: 50%; z-index: 2;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35), 0 0 0 3px rgba(255,255,255,0.35);
}

/* Current-value badge, centred under the marker dot; colour set inline per position */
.mf-bench-value-badge {
  position: absolute; top: 16px; transform: translateX(-50%);
  padding: 1px 8px; border-radius: 999px; font-size: 0.72rem; font-weight: 700;
  white-space: nowrap; z-index: 3; box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.mf-bench-peak { color: var(--good); font-weight: 700; font-size: 1rem; min-width: 90px; text-align: right; }
.mf-bench-bottom { color: var(--bad); font-weight: 700; font-size: 1rem; min-width: 90px; text-align: right; }

/* Overview tab enhancements */
.mf-perf-section { margin-bottom: 12px; }
.mf-perf-label { font-size: 0.75rem; color: var(--muted); text-transform: uppercase; font-weight: 600; letter-spacing: 0.5px; margin-bottom: 6px; }
.mf-perf-top, .mf-perf-bottom { display: flex; flex-direction: column; gap: 4px; }
.mf-perf-item { display: flex; justify-content: space-between; align-items: center; padding: 6px 8px; background: var(--card-2); border-radius: 6px; font-size: 0.82rem; }
.mf-perf-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mf-perf-ret { font-weight: 600; flex: 0 0 auto; margin-left: 8px; }
.mf-goal-row { display: flex; align-items: center; gap: 12px; margin: 12px 0; font-size: 0.82rem; }
.mf-goal-current { font-weight: 600; flex: 0 0 auto; min-width: 80px; text-align: right; }
.mf-goal-track { flex: 1; height: 20px; background: var(--card-2); border-radius: 10px; overflow: hidden; }
.mf-goal-fill { height: 100%; background: linear-gradient(90deg, var(--good), #22c55e); border-radius: 10px; transition: width 0.3s ease; }
.mf-goal-target { font-weight: 600; flex: 0 0 auto; min-width: 80px; text-align: left; color: var(--muted); }
.mf-goal-meta { text-align: center; color: var(--muted); font-size: 0.75rem; font-weight: 600; }

/* Stats tab: Nifty 50 header row + per-fund day/month/year change rows */
.mf-stats-nifty {
  display: flex; align-items: center; justify-content: space-between;
  background: linear-gradient(135deg, var(--card), var(--card-2));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; margin-bottom: 12px; font-size: 0.85rem; font-weight: 600;
}
.mf-stats-nifty .mf-stats-pct { font-size: 1rem; }
.mf-stats-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; cursor: pointer; }
.mf-stats-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.mf-stats-vals { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.mf-stats-pct { font-weight: 700; font-size: 0.95rem; }

/* Home → "Coming up this week": horizontally-scrolling strip of incoming money
   (FD maturities + bond payouts), between the summary and the section cards.
   Small chip-style cards so several fit on screen at once. Scrolls inside its
   own rail (same technique as .portfolio-tabs) so the page body never scrolls
   sideways, with scroll-snap so a flick lands on a card rather than mid-card.
   Cards carry no instrument name - the FD/BOND badge is the identifier, so
   every card is the same shape regardless of source. */
.due-soon { margin-top: 18px; }
.due-soon-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.due-soon-title { font-size: 0.82rem; font-weight: 700; }
.due-soon-count { font-size: 0.68rem; color: var(--muted); }
/* Wraps the rail so a fade can sit over its trailing edge - the cue that more
   cards are scrollable off-screen once the strip grows beyond what fits. Shown
   only while .can-scroll (the rail genuinely overflows) and hidden again once
   .at-end (scrolled all the way, so there's nothing further to hint at). */
.due-soon-scroller { position: relative; }
.due-soon-scroller::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 2px; width: 26px;
  background: linear-gradient(to right, transparent, var(--bg) 88%);
  opacity: 0; transition: opacity 0.15s ease; pointer-events: none;
}
.due-soon-scroller.can-scroll::after { opacity: 1; }
.due-soon-scroller.can-scroll.at-end::after { opacity: 0; }
.due-soon-rail {
  display: flex; gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.due-soon-rail::-webkit-scrollbar { display: none; }
.due-soon-group { display: flex; gap: 8px; flex: 0 0 auto; }
/* Marquee mode - switched on from app.js only once the cards actually overflow.
   The track holds two identical groups and slides exactly one group's width
   (plus the gap that follows it), so the clone arrives where the original
   started and the loop has no visible seam. Manual scrolling is turned off
   here: the strip is moving on its own, and a half-scrolled rail fighting the
   animation is worse than either alone. */
.due-soon-scroller.is-marquee { overflow: hidden; }
.due-soon-scroller.is-marquee .due-soon-rail {
  overflow-x: hidden;
  scroll-snap-type: none;
  animation: due-soon-marquee var(--marquee-duration, 20s) linear infinite;
  width: max-content;
}
/* Hold still while being looked at or touched, so a card can actually be read
   and tapped rather than sliding out from under the finger. */
.due-soon-scroller.is-marquee:hover .due-soon-rail,
.due-soon-scroller.is-marquee:focus-within .due-soon-rail,
.due-soon-scroller.is-marquee.is-held .due-soon-rail { animation-play-state: paused; }
/* The track is two groups plus the 8px gap between them, so -50% lands 4px
   short of the second group's start — hence the extra -4px (half the gap). */
@keyframes due-soon-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 4px)); }
}
@media (prefers-reduced-motion: reduce) {
  .due-soon-scroller.is-marquee .due-soon-rail { animation: none; overflow-x: auto; }
}
/* Two fixed rows per card - type/EF badge sits top-right beside "days left",
   maturity date sits bottom-right beside the amount. Nowrap + no min/max-width:
   a card with more to show (a longer date, an EF badge) grows WIDER instead of
   taller, so every card stays exactly two lines regardless of content. */
.due-soon-card {
  flex: 0 0 auto; scroll-snap-align: start;
  min-width: 118px;
  display: flex; flex-direction: column; gap: 4px;
  text-align: left; cursor: pointer; white-space: nowrap;
  background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 10px; padding: 8px 10px;
}
.due-soon-card:active { background: var(--card-2); }
.due-soon-card.is-urgent { border-left-color: var(--warn); }
.due-soon-card.is-div { border-left-color: #0d9488; }
.due-soon-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.due-soon-days { font-size: 0.68rem; font-weight: 700; color: var(--accent); }
.due-soon-card.is-urgent .due-soon-days { color: var(--warn); }
.due-soon-card.is-div .due-soon-days { color: #0d9488; font-size: 0.8rem; }
.due-soon-badges { display: flex; align-items: center; gap: 4px; }
.due-soon-amt { font-size: 0.95rem; font-weight: 700; }
.due-soon-date { font-size: 0.62rem; color: var(--muted); }
/* The dividend reminder's stock list - can legitimately be the widest thing in
   the rail (several stock names), which is fine: cards grow wider, not taller. */
.due-soon-names { font-size: 0.78rem; font-weight: 600; }
/* Instrument-type badges. These are the card's only identifier, so each reads
   as a clearly different colour rather than a shade of the others. */
.badge.due-badge-fd { color: var(--accent); border-color: rgba(14,165,233,0.45); background: rgba(14,165,233,0.12); font-weight: 700; }
.badge.due-badge-bond { color: #d97706; border-color: rgba(217,119,6,0.45); background: rgba(217,119,6,0.12); font-weight: 700; }
.badge.due-badge-div { color: #0d9488; border-color: rgba(13,148,136,0.45); background: rgba(13,148,136,0.12); font-weight: 700; }
@media (prefers-color-scheme: dark) {
  .badge.due-badge-bond { color: #fcd34d; }
  .badge.due-badge-div, .due-soon-card.is-div .due-soon-days { color: #5eead4; }
}

/* Allocation tracker (Expense → Allocation tab) */
.alloc-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.alloc-header h3 { margin: 0; font-size: 1rem; }
.alloc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 16px 0; }
/* Display-only now — editing is the single "Edit All Allocations" button
   below, not a per-card tap — so no cursor/hover-lift affordance. */
.alloc-card { background: var(--card-2); border: 1px solid var(--line); border-radius: 12px; padding: 14px; }
.alloc-cat-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.alloc-icon { font-size: 1.2rem; }
.alloc-label { font-size: 0.75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; }
.alloc-value { font-size: 1rem; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.alloc-stepup { font-size: 0.7rem; font-weight: 600; }
.alloc-stepup.step-up-pos { color: var(--good); }
.alloc-stepup.step-up-neg { color: var(--bad); }
.alloc-stepup.step-up-flat { color: var(--muted); }
.alloc-total { background: linear-gradient(135deg, var(--card) 0%, var(--card-2) 100%); border: 1px solid var(--accent); border-radius: 12px; padding: 16px; margin: 20px 0; text-align: center; }
.alloc-total-label { font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 6px; }
.alloc-total-value { font-size: 1.4rem; font-weight: 700; color: var(--accent); margin-bottom: 4px; }
.alloc-total-stepup { font-size: 0.85rem; color: var(--good); font-weight: 700; }
/* Monthly cash-flow sheet (Expense → Expense tab). Two tinted bands — green
   for what's available this month, red for what's already committed — so the
   split reads at a glance without needing a legend, then one emphasised
   closing balance underneath. Tints are alpha over the card so they hold up
   in both themes without a second set of tokens. */
.msheet-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 2px 0 12px; }
.msheet-stepper { display: flex; align-items: center; gap: 10px; }
.msheet-month-label { font-weight: 700; font-size: 0.95rem; min-width: 74px; text-align: center; }
.msheet-fetch { flex: 0 0 auto; white-space: nowrap; }
/* Committed rows stack their running-total headline over the box that holds
   it, right-aligned so both read down the same edge as the green rows' single
   figure. */
.msheet-stack { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
/* Wider than the plain-number boxes on the green rows: these hold an additive
   expression that grows a term on every Fetch, and the sum above is only
   trustworthy if you can see what's feeding it. */
.msheet-stack .msheet-input input { width: 146px; font-size: 0.82rem; }
.msheet { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.msheet-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.msheet-row:last-child { border-bottom: none; }
.msheet-credit { background: rgba(52, 211, 153, 0.16); }
.msheet-debit { background: rgba(248, 113, 113, 0.13); }
.msheet-label { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.msheet-label > span:first-child { font-weight: 600; font-size: 0.86rem; }
.msheet-note { font-size: 0.64rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.msheet-val { font-weight: 700; font-size: 0.92rem; white-space: nowrap; }
.msheet-input input { width: 104px; text-align: right; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--text); font-size: 0.88rem; font-weight: 700; }
/* Green rows: the headline figure is itself the field. Styled as the value
   (same weight and size as .msheet-val) rather than as an input, with a dashed
   rule underneath as the only hint that it takes typing — a full box here would
   read as a second, separate number next to the ones the red rows show. */
.msheet-val-input {
  width: 128px; text-align: right; font-weight: 700; font-size: 0.92rem;
  color: var(--text); background: transparent;
  border: none; border-bottom: 1px dashed var(--line);
  border-radius: 0; padding: 2px 2px 3px;
}
.msheet-val-input::placeholder { color: var(--text); opacity: 0.55; font-weight: 700; }
.msheet-val-input:focus { outline: none; border-bottom-color: var(--accent); }
.msheet-total { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 12px 0 4px; padding: 14px 16px; border-radius: 12px; background: linear-gradient(135deg, var(--card) 0%, var(--card-2) 100%); border: 1px solid var(--good); }
.msheet-total.is-neg { border-color: var(--bad); }
.msheet-total-label { font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; }
.msheet-total-val { font-size: 1.3rem; font-weight: 800; color: var(--good); }
.msheet-total.is-neg .msheet-total-val { color: var(--bad); }

.sheet-form h2 { margin: 0 0 8px; font-size: 1.2rem; font-weight: 700; }
.sheet-btns { display: flex; gap: 8px; margin-top: 20px; }
.sheet-btns button { flex: 1; }

/* Allocation form: editable year picker + compact single-column rows.
   (Cards were dropped — a 2-col card grid overflowed narrow phone widths
   with 60px+ padding baked into each card; rows are compact and never
   need to wrap horizontally.) */
.alloc-form-year-picker { display: flex; align-items: center; gap: 10px; margin: 4px 0 18px; padding: 10px 12px; background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; }
.alloc-form-year-picker label { font-size: 0.75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; flex: 0 0 auto; }
.alloc-form-year-input { width: 84px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--text); font-size: 1rem; font-weight: 700; text-align: center; flex: 0 0 auto; }
.alloc-form-year-badge { font-size: 0.7rem; color: var(--muted); font-weight: 600; }
.alloc-form-year-badge.is-existing { color: var(--accent); }

.alloc-form-sections { display: flex; flex-direction: column; gap: 18px; margin: 0 0 8px; }
.alloc-form-section { display: flex; flex-direction: column; gap: 6px; }
.alloc-form-section-header { display: flex; align-items: center; gap: 8px; padding: 0 2px; margin-bottom: 2px; }
.alloc-form-section-icon { font-size: 1rem; }
.alloc-form-section-title { margin: 0; font-size: 0.72rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.alloc-form-rows { display: flex; flex-direction: column; gap: 5px; }
.alloc-form-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; background: var(--card-2); border: 1px solid var(--line); border-radius: 8px; }
.alloc-form-row-left { display: flex; align-items: center; gap: 7px; min-width: 0; flex: 1 1 auto; }
.alloc-form-row-icon { font-size: 1rem; flex: 0 0 auto; }
.alloc-form-row-label { font-size: 0.82rem; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alloc-form-row-input-wrap { position: relative; flex: 0 0 110px; }
.alloc-form-row-input-wrap input { width: 100%; padding: 6px 22px 6px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--text); font-size: 0.85rem; font-weight: 600; text-align: right; }
.alloc-form-row-currency { position: absolute; right: 7px; top: 50%; transform: translateY(-50%); font-size: 0.7rem; color: var(--muted); font-weight: 600; pointer-events: none; }

/* ---- Daily spend tracker (Expense → Tracker tab) ---- */
/* Kitty / Spent / Left across one strip: three figures that only mean anything
   read together, so they get equal weight rather than a headline and footnotes. */
.trk-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 2px 0 10px; }
.trk-sum-cell { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 9px 10px; min-width: 0; }
.trk-sum-label { font-size: 0.62rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; }
.trk-sum-val { font-size: 1rem; font-weight: 800; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trk-sum-note { font-size: 0.6rem; color: var(--muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trk-left { border-color: var(--good); }
.trk-left .trk-sum-val { color: var(--good); }
.trk-left.is-neg { border-color: var(--bad); }
.trk-left.is-neg .trk-sum-val { color: var(--bad); }
/* How much of the kitty is gone, at a glance — turns red only once it's
   actually overspent, not merely close. */
.trk-bar { height: 6px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line); overflow: hidden; margin: 0 0 14px; }
.trk-bar-fill { height: 100%; background: var(--good); border-radius: 999px; transition: width 0.25s ease; }
.trk-bar-fill.is-over { background: var(--bad); }
.trk-cat-row { background: var(--card); }
.trk-entry { background: var(--card); }
.trk-entry-right { display: flex; align-items: center; gap: 6px; }
.trk-del { opacity: 0.5; font-size: 1rem; line-height: 1; }
.trk-del:hover { opacity: 1; color: var(--bad); }
/* Category picker: tap targets, not a dropdown. A dropdown hides the options
   behind an extra tap, and this form is opened several times a day. */
.spend-cat-group { margin-bottom: 10px; }
.spend-cat-group-label { font-size: 0.6rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; margin-bottom: 5px; }
.spend-cat-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.spend-cat-btn { font-size: 0.72rem; font-weight: 600; padding: 6px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--card-2); color: var(--text); cursor: pointer; }
.spend-cat-btn.active { border-color: var(--accent); background: var(--card); color: var(--accent); font-weight: 700; box-shadow: inset 0 0 0 1px var(--accent); }
.spend-method button { flex: 1; }
/* Card picker, shown only when the spend was paid by Card. Four across so a
   typical wallet fits without scrolling; the radio dot makes it read as a
   single choice rather than the multi-select the category chips above allow. */
.spend-card-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.spend-card-btn {
  display: flex; align-items: flex-start; gap: 5px; min-width: 0;
  padding: 7px 7px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--card-2); color: var(--text);
  font-size: 0.63rem; font-weight: 600; text-align: left; line-height: 1.2;
}
.spend-card-radio { flex: 0 0 auto; width: 11px; height: 11px; border-radius: 50%; border: 1.5px solid var(--muted); }
.spend-card-btn.active { border-color: var(--accent); background: var(--card); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.spend-card-btn.active .spend-card-radio { border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 2px var(--card); }
.spend-card-name { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 330px) { .spend-card-grid { grid-template-columns: repeat(2, 1fr); } }
/* Roll-up vs raw entries — two views of the same month, switched not stacked. */
.trk-seg { margin: 4px 0 12px; }
.trk-seg button { flex: 1; }
/* Entry rows open the editor; the delete × inside them stops the click. */
.trk-entry.is-tappable { cursor: pointer; }
.trk-entry.is-tappable:active { background: var(--card-2); }
/* An emoji FAB needs no bold/oversized glyph treatment the way "+" does. */
/* White with a lifted shadow rather than the accent fill the other FABs use:
   this one sits on Home over a pale background as well as inside the Expense
   section, and a single fixed white keeps it identical in both themes. */
.fab.fab-spend {
  background: #fff; color: #14203a;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 14px rgba(0,0,0,0.18), 0 12px 28px rgba(0,0,0,0.22);
}
.fab.fab-spend:active { transform: translateY(1px); box-shadow: 0 4px 10px rgba(0,0,0,0.2); }
.fab.fab-spend svg { width: 26px; height: 26px; display: block; }
.fab.fab-health {
  background: #fff; color: #14203a;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 14px rgba(0,0,0,0.18), 0 12px 28px rgba(0,0,0,0.22);
}
.fab.fab-health:active { transform: translateY(1px); box-shadow: 0 4px 10px rgba(0,0,0,0.2); }
.fab.fab-health img { width: 28px; height: 28px; display: block; }
/* Tracker timeline: three states that must be told apart at a glance —
   an empty month, a month with spends in it, and the one being viewed.
   Scoped to .trk-timeline so the Credit Card strip, which uses the same chip
   class for its own paid/unpaid meaning, is left alone. */
/* Empty: recedes. Nothing was spent, so there is nothing to come back to. */
.trk-timeline .cc-timeline-chip { color: var(--muted); background: transparent; border-color: var(--line); font-weight: 600; }
/* Filled: raised chip plus a dot under the label — the dot survives even when
   the chip is also the selected one, so "has spends" never gets overwritten. */
.trk-timeline .cc-timeline-chip.has-data { color: var(--text); background: var(--card-2); border-color: var(--line); padding-bottom: 9px; }
.trk-timeline .cc-timeline-chip.has-data::after {
  content: ''; position: absolute; left: 50%; bottom: 4px; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: var(--accent); opacity: 0.85;
}
/* Selected: an accent ring around the chip and accent text, rather than a
   solid fill — it has to outrank the filled state without shouting over the
   month labels either side of it. */
.trk-timeline .cc-timeline-chip.active,
.trk-timeline .cc-timeline-chip.has-data.active {
  background: var(--card); color: var(--accent); font-weight: 800;
  border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent);
}
/* Current month, while some other month is being viewed: a faint outline, so
   it can still be found without competing with the selection. */
.trk-timeline .cc-timeline-chip.is-current:not(.active) { border-color: var(--accent); border-style: dashed; }
.trk-timeline .cc-timeline-chip { position: relative; }
/* Insights: one observation per row, tinted by whether it is a rise or a fall.
   Kept to a flat list rather than cards — they are read top to bottom once,
   not compared against each other. */
.trk-insights { display: flex; flex-direction: column; gap: 6px; }
.trk-insight { display: flex; gap: 9px; align-items: flex-start; padding: 9px 11px; border-radius: 10px; background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--line); }
.trk-insight.is-warn { border-left-color: var(--bad); }
.trk-insight.is-good { border-left-color: var(--good); }
.trk-insight-ico { flex: 0 0 auto; font-size: 0.95rem; line-height: 1.25; }
.trk-insight-body { min-width: 0; }
.trk-insight-head { font-size: 0.8rem; font-weight: 700; }
.trk-insight.is-warn .trk-insight-head { color: var(--bad); }
.trk-insight.is-good .trk-insight-head { color: var(--good); }
.trk-insight-sub { font-size: 0.68rem; color: var(--muted); margin-top: 2px; }

/* ---- Tracker: grouped category roll-up ---- */
/* One hue per group, set as --g and inherited by everything inside it, so a
   group's header rule, dots and bars all move together from one declaration.
   Fixed hues rather than theme tokens: these have to stay distinguishable
   FROM EACH OTHER, which a palette that shifts with the theme cannot promise. */
.trk-g-fixed     { --g: #6366f1; }
.trk-g-home      { --g: #14b8a6; }
.trk-g-grocery   { --g: #f59e0b; }
.trk-g-lifestyle { --g: #a855f7; }
.trk-g-other     { --g: #64748b; }

.trk-groups { display: flex; flex-direction: column; gap: 10px; }
.trk-group { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--card); }
/* The group's colour appears as a rule down its left edge — present on every
   row of the group without repeating a swatch on each one. */
.trk-group-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 12px; background: var(--card-2);
  border-bottom: 1px solid var(--line); border-left: 3px solid var(--g);
}
.trk-group-name { flex: 1; min-width: 0; font-size: 0.66rem; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; color: var(--g); }
.trk-group-total { font-size: 0.86rem; font-weight: 800; }
.trk-group-pct { font-size: 0.62rem; font-weight: 700; color: var(--muted); min-width: 30px; text-align: right; }

.trk-cats { display: flex; flex-direction: column; }
.trk-cat { padding: 9px 12px 10px; border-bottom: 1px solid var(--line); border-left: 3px solid transparent; }
.trk-cat:last-child { border-bottom: none; }
.trk-cat-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.trk-cat-name { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 0.83rem; font-weight: 600; }
.trk-cat-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--g); }
.trk-cat-amt { font-size: 0.88rem; font-weight: 700; white-space: nowrap; }
/* Bar and its figure share a line, so a category costs two lines however long
   its name is — a list of fifteen stays the same height it would at five. */
.trk-cat-bottom { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.trk-cat-track { flex: 1; height: 4px; border-radius: 999px; background: var(--card-2); overflow: hidden; }
.trk-cat-fill { display: block; height: 100%; border-radius: 999px; background: var(--g); opacity: 0.85; }
.trk-cat-meta { flex: 0 0 auto; font-size: 0.6rem; font-weight: 600; color: var(--muted); min-width: 52px; text-align: right; }

/* ---- Reduce tab ---- */
.rvw-head { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin: 2px 0 12px; }
.rvw-head-fig { font-size: 1.15rem; font-weight: 800; }
.rvw-head-fig.is-over { color: var(--bad); }
.rvw-head-note { font-size: 0.68rem; color: var(--muted); margin-top: 3px; }
/* Says outright when there isn't the history to judge anything, rather than
   showing an empty panel that reads as "nothing to worry about". */
.rvw-thin { background: var(--card-2); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.rvw-thin-head { font-size: 0.82rem; font-weight: 700; }
.rvw-thin-sub { font-size: 0.7rem; color: var(--muted); margin-top: 4px; line-height: 1.45; }
.rvw-clear { display: flex; gap: 10px; align-items: flex-start; background: var(--card); border: 1px solid var(--good); border-radius: 12px; padding: 12px 14px; }
.rvw-clear-head { font-size: 0.84rem; font-weight: 700; color: var(--good); }
.rvw-clear-sub { font-size: 0.7rem; color: var(--muted); margin-top: 2px; }
/* One finding per card, tinted by its category group so the Reduce tab and the
   Tracker roll-up agree on what colour a category is. */
.rvw-list { display: flex; flex-direction: column; gap: 8px; }
.rvw-item { background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--g, var(--line)); border-radius: 10px; padding: 10px 12px; }
.rvw-item-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.rvw-item-name { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 0.86rem; font-weight: 700; }
.rvw-item-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--g, var(--muted)); }
.rvw-item-amt { font-size: 0.9rem; font-weight: 800; white-space: nowrap; }
.rvw-item-mid { font-size: 0.66rem; color: var(--muted); margin-top: 4px; }
.rvw-item-save { display: flex; align-items: baseline; gap: 6px; margin-top: 7px; padding-top: 7px; border-top: 1px dashed var(--line); flex-wrap: wrap; }
.rvw-save-amt { font-size: 0.8rem; font-weight: 800; color: var(--bad); }
.rvw-save-txt { font-size: 0.63rem; color: var(--muted); }
.rvw-total { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 12px 0 4px; padding: 13px 15px; border-radius: 12px; background: linear-gradient(135deg, var(--card) 0%, var(--card-2) 100%); border: 1px solid var(--good); }
.rvw-total.is-neg { border-color: var(--bad); }
.rvw-total-label { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; }
.rvw-total-val { font-size: 1.1rem; font-weight: 800; color: var(--good); }
.rvw-total.is-neg .rvw-total-val { color: var(--bad); }
/* Recurring items still to land. The day-of-month leads each row, since "when"
   is the thing being reported. */
.rvw-due { display: flex; flex-direction: column; gap: 6px; }
.rvw-due-row { display: flex; align-items: center; gap: 10px; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; }
.rvw-due-when { flex: 0 0 34px; display: flex; flex-direction: column; align-items: center; line-height: 1; }
.rvw-due-day { font-size: 1rem; font-weight: 800; color: var(--accent); }
.rvw-due-daylbl { font-size: 0.55rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.rvw-due-body { flex: 1; min-width: 0; }
.rvw-due-name { font-size: 0.82rem; font-weight: 600; }
.rvw-due-meta { font-size: 0.62rem; color: var(--muted); margin-top: 2px; }
.rvw-due-amt { flex: 0 0 auto; font-size: 0.85rem; font-weight: 700; white-space: nowrap; }
.rvw-flat { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.rvw-flat-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 8px 12px; background: var(--card); border-bottom: 1px solid var(--line); font-size: 0.78rem; }
.rvw-flat-row:last-child { border-bottom: none; }
.rvw-flat-meta { font-size: 0.64rem; color: var(--muted); white-space: nowrap; }
/* Review: creeping sequence, small-spend panel, payment split */
.rvw-seq { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.rvw-seq-step { display: flex; flex-direction: column; align-items: center; padding: 4px 8px; border-radius: 7px; background: var(--card-2); border: 1px solid var(--line); line-height: 1.2; }
.rvw-seq-mon { font-size: 0.55rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.rvw-seq-amt { font-size: 0.72rem; font-weight: 700; }
/* The last step is where it has got to, so it carries the group's colour. */
.rvw-seq-step:last-child { border-color: var(--g, var(--line)); }
.rvw-seq-step:last-child .rvw-seq-amt { color: var(--g, var(--text)); }
.rvw-panel { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.rvw-panel-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.rvw-panel-fig { font-size: 1.05rem; font-weight: 800; }
.rvw-panel-sub { font-size: 0.68rem; color: var(--muted); }
.rvw-mini { margin-top: 9px; padding-top: 8px; border-top: 1px dashed var(--line); display: flex; flex-direction: column; gap: 4px; }
.rvw-mini-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 0.74rem; }
.rvw-mini-meta { font-size: 0.64rem; color: var(--muted); white-space: nowrap; }
.rvw-meth { display: flex; flex-direction: column; gap: 7px; }
.rvw-meth-row { display: flex; align-items: center; gap: 8px; }
.rvw-meth-name { flex: 0 0 40px; font-size: 0.72rem; font-weight: 700; }
.rvw-meth-track { flex: 1; height: 6px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line); overflow: hidden; }
.rvw-meth-fill { display: block; height: 100%; border-radius: 999px; }
/* Card is the one that becomes a bill later, so it gets the warning hue. */
.rvw-meth-fill.is-card { background: var(--bad); }
.rvw-meth-fill.is-upi  { background: var(--accent); }
.rvw-meth-fill.is-cash { background: var(--good); }
.rvw-meth-amt { flex: 0 0 auto; font-size: 0.74rem; font-weight: 700; white-space: nowrap; }
.rvw-meth-pct { flex: 0 0 32px; font-size: 0.64rem; color: var(--muted); text-align: right; }
.rvw-note { font-size: 0.68rem; line-height: 1.5; margin: 8px 0 0; }
/* Kitty label shares its line with the emergency-draw badge when there is one. */
.trk-label-row { display: flex; align-items: center; justify-content: space-between; gap: 3px; }
.trk-draw-badge {
  flex: 0 0 auto; font-size: 0.5rem; font-weight: 800; white-space: nowrap;
  padding: 1px 4px; border-radius: 999px;
  background: rgba(248,113,113,0.16); border: 1px solid rgba(248,113,113,0.42);
  color: var(--bad); text-transform: none; letter-spacing: 0;
}
/* EF loan form: where an emergency draw is loaded. Two equal choices, so the
   segmented control matches the Paid-by row on the spend form. */
.ef-apply button { flex: 1; }
.ef-apply-why { font-size: 0.66rem; line-height: 1.4; }
/* EF loan: repayment plan boxes, one per month between the draw and its return */
.ef-plan { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.ef-plan-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ef-plan-mon { font-size: 0.58rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.ef-plan-cell input { width: 100%; text-align: right; padding: 6px 7px; font-size: 0.8rem; font-weight: 700; }
.ef-plan-foot { margin-top: 7px; text-align: right; }
/* Turns amber only when the plan and the amount lent disagree — a schedule
   that does not add up is worth noticing before it silently reduces months. */
.ef-plan-total { font-size: 0.66rem; font-weight: 700; color: var(--muted); }
.ef-plan-total.is-off { color: var(--warn); }
@media (max-width: 340px) { .ef-plan { grid-template-columns: repeat(2, 1fr); } }
/* Planned against repaid, on the Repayments tab */
.ef-sched { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; margin: 0 0 12px; }
.ef-sched-head { font-size: 0.6rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); padding: 7px 10px; background: var(--card-2); border-bottom: 1px solid var(--line); }
.ef-sched-row { display: flex; align-items: baseline; gap: 8px; padding: 7px 10px; border-bottom: 1px solid var(--line); font-size: 0.72rem; }
.ef-sched-row:last-child { border-bottom: none; }
.ef-sched-row.is-done { color: var(--muted); }
.ef-sched-mon { flex: 0 0 52px; font-weight: 700; }
.ef-sched-plan { flex: 0 0 auto; font-weight: 700; }
.ef-sched-got { flex: 1; color: var(--muted); font-size: 0.66rem; }
.ef-sched-left { flex: 0 0 auto; font-size: 0.66rem; font-weight: 700; }
.ef-sched-row.is-done .ef-sched-left { color: var(--good); }
/* A repayment earmark is a commitment, not an emergency — amber, not red. */
.trk-draw-badge.is-repay { background: rgba(245,158,11,0.16); border-color: rgba(245,158,11,0.45); color: #b45309; }

/* ---- Form sections (loan form; same shape as the Allocation form's) ---- */
/* A flat stack of a dozen fields gives no clue which of them belong together,
   so the loan form is grouped under quiet uppercase headings. The heading is
   part of the section, so hiding the section hides its label too. */
.form-secs { display: flex; flex-direction: column; gap: 18px; }
.form-sec { display: flex; flex-direction: column; gap: 10px; }
.form-sec-head { display: flex; align-items: center; gap: 8px; padding: 0 2px; }
.form-sec-icon { font-size: 0.95rem; }
.form-sec-title { margin: 0; font-size: 0.7rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
/* The sections already space themselves, so the fields inside drop their own
   bottom margins rather than compounding the gap. */
.form-sec .field { margin: 0; }

/* ---- The fund's lending rate, on the Loans tab ---- */
/* One rate for the whole fund, stated where the loans are listed. Editable in
   place: the Save button only appears once the figure has actually changed, so
   at rest this reads as a fact about the fund rather than an open form. */
.ef-rate-card { display: flex; align-items: center; gap: 10px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; margin: 0 0 10px; }
.ef-rate-icon { font-size: 1.15rem; flex: 0 0 auto; }
.ef-rate-body { flex: 1; min-width: 0; }
.ef-rate-label { font-size: 0.78rem; font-weight: 700; }
.ef-rate-sub { font-size: 0.62rem; color: var(--muted); margin-top: 1px; }
.ef-rate-edit { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.ef-rate-input { width: 56px; padding: 6px 7px; border: 1px solid var(--line); border-radius: 7px; background: var(--card-2); color: var(--text); font-size: 0.95rem; font-weight: 800; text-align: center; }
.ef-rate-pct { font-size: 0.8rem; font-weight: 700; color: var(--muted); }
.ef-rate-save { padding: 6px 10px; font-size: 0.7rem; }
/* Under ~330px the sub line and the input compete for the same row; the card
   stacks rather than squeezing the input to nothing. */
@media (max-width: 330px) {
  .ef-rate-card { flex-wrap: wrap; }
  .ef-rate-edit { width: 100%; justify-content: flex-end; }
}

/* ---- What counts as an emergency (Rules tab) ---- */
/* Rule 1 hinges on the word "genuine"; this is the agreed list behind it. Red
   accent because it belongs to the same idea as the fund's siren, and the
   catch-all sits in its own panel so it reads as the clause it is, not as a
   seventh reason. */
.ef-reasons { display: flex; flex-direction: column; gap: 2px; }
.ef-reason { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px; border-left: 3px solid var(--bad); background: var(--card-2); }
.ef-reason-ico { font-size: 0.95rem; flex: 0 0 auto; }
.ef-reason-text { font-size: 0.8rem; font-weight: 600; }
.ef-reason-note { margin: 10px 0 0; padding: 9px 11px; background: var(--card-2); border: 1px solid var(--line); border-radius: 8px; font-size: 0.68rem; line-height: 1.45; color: var(--muted); }

/* ---- Loan Rules: rules 9 and 10 in rupees (Rules tab) ---- */
/* The headline pair reads as one statement — what a quarter of the fund comes
   to, and how long it may be held — so they share a row and the figure gets
   the weight. */
.ef-lr-head { display: flex; align-items: stretch; gap: 10px; background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin: 0 0 8px; }
.ef-lr-head-cell { min-width: 0; flex: 1; }
.ef-lr-head-cell.is-side { flex: 0 0 auto; text-align: right; border-left: 1px solid var(--line); padding-left: 10px; display: flex; flex-direction: column; justify-content: center; }
.ef-lr-head-label { font-size: 0.6rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; line-height: 1.35; }
.ef-lr-head-big { font-size: 1.35rem; font-weight: 800; margin-top: 3px; }
.ef-lr-head-val { font-size: 0.82rem; font-weight: 700; margin-top: 3px; white-space: nowrap; }
/* One row per party, all showing the same cap. The share sits on the left as a
   fixed-width badge so the four rows line up and the repetition is the point
   being made: this is one allowance each, not a quarter divided up. */
.ef-lr-rows { display: flex; flex-direction: column; gap: 2px; }
.ef-lr-row { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px; background: var(--card-2); border-left: 3px solid var(--accent); }
.ef-lr-share { flex: 0 0 34px; font-size: 0.66rem; font-weight: 800; color: var(--accent); }
.ef-lr-who { flex: 1; min-width: 0; font-size: 0.8rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ef-lr-amt { flex: 0 0 auto; font-size: 0.82rem; font-weight: 800; }
@media (max-width: 330px) {
  .ef-lr-head { flex-direction: column; gap: 8px; }
  .ef-lr-head-cell.is-side { text-align: left; border-left: none; padding-left: 0; border-top: 1px solid var(--line); padding-top: 7px; }
}

/* ---- Review: where the month lands, and the shape it lands in ---- */
/* The heading carries a grade badge, so it becomes a row rather than a label. */
.div-group-head.rvw-head-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.rvw-grade { font-size: 0.58rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; padding: 3px 7px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); background: var(--card-2); white-space: nowrap; }
/* Graded from its own measured error, not from a feeling about the method. */
.rvw-grade.is-good { color: var(--good); border-color: rgba(52,211,153,0.5); }
.rvw-grade.is-fair { color: var(--warn); border-color: rgba(245,158,11,0.5); }
.rvw-grade.is-rough { color: var(--bad); border-color: rgba(248,113,113,0.45); }

.rvw-fc { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 13px 14px; }
.rvw-fc-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.rvw-fc-big { font-size: 1.5rem; font-weight: 800; line-height: 1.1; }
.rvw-fc-big.is-over { color: var(--bad); }
.rvw-fc-lbl { font-size: 0.62rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; margin-top: 2px; }
.rvw-fc-range { text-align: right; flex: 0 0 auto; }
.rvw-fc-range-lbl { font-size: 0.58rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; }
.rvw-fc-range-val { font-size: 0.76rem; font-weight: 700; margin-top: 2px; white-space: nowrap; }
/* Spent is settled, the remainder is an estimate — so the estimate is hatched
   rather than solid. The kitty is a line across it, because the question is
   which side of that line the month ends on. */
.rvw-fc-split { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; font-size: 0.66rem; color: var(--muted); font-weight: 600; }
.rvw-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 5px; vertical-align: baseline; }
.rvw-dot.is-spent { background: var(--accent); }
/* Dashed ring for the estimated part, matching the dashed line on the chart -
   a swatch should look like the thing it labels. */
.rvw-dot.is-proj { background: transparent; border: 2px dashed var(--accent); width: 9px; height: 9px; box-sizing: border-box; }

/* The lines that decide today. Marked rather than bulleted, so a "you are
   fine" and a "you are over" are told apart without reading them. */
.rvw-lines { display: flex; flex-direction: column; gap: 1px; margin: 9px 0 0; }
.rvw-line { display: flex; align-items: flex-start; gap: 8px; padding: 7px 10px; font-size: 0.74rem; line-height: 1.4; background: var(--card); border-radius: 8px; }
.rvw-line-mark { flex: 0 0 15px; text-align: center; font-weight: 800; font-size: 0.72rem; color: var(--muted); }
.rvw-line.is-ok .rvw-line-mark { color: var(--good); }
.rvw-line.is-no .rvw-line-mark { color: var(--bad); }
.rvw-line.is-up .rvw-line-mark { color: var(--warn); }
.rvw-line.is-down .rvw-line-mark { color: var(--good); }

/* Where you could keep money: the figure is the point, so it gets its own
   column and the "how" sits under the name as the instruction it is. */
.rvw-save-list { display: flex; flex-direction: column; gap: 5px; }
.rvw-save-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--g, var(--line)); border-radius: 10px; }
.rvw-save-body { flex: 1; min-width: 0; }
.rvw-save-name { font-size: 0.8rem; font-weight: 700; }
.rvw-save-how { font-size: 0.64rem; color: var(--muted); margin-top: 2px; line-height: 1.4; }
.rvw-save-fig { flex: 0 0 auto; text-align: right; }
.rvw-save-val { font-size: 0.95rem; font-weight: 800; color: var(--good); }
.rvw-save-unit { font-size: 0.55rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; }

/* The month in thirds: one bar, because the three shares are one month. */
.rvw-cyc { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 13px; margin-bottom: 8px; }
.rvw-cyc-bar { display: flex; height: 24px; border-radius: 7px; overflow: hidden; background: var(--card-2); }
.rvw-cyc-seg { display: flex; align-items: center; justify-content: center; font-size: 0.62rem; font-weight: 800; color: #0b1220; min-width: 2px; }
.rvw-cyc-seg.is-t0 { background: #60a5fa; }
.rvw-cyc-seg.is-t1 { background: #a78bfa; }
.rvw-cyc-seg.is-t2 { background: #f59e0b; }
.rvw-dot.is-t0 { background: #60a5fa; }
.rvw-dot.is-t1 { background: #a78bfa; }
.rvw-dot.is-t2 { background: #f59e0b; }
.rvw-cyc-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 9px; }
.rvw-cyc-key { display: flex; align-items: baseline; gap: 4px; font-size: 0.66rem; }
.rvw-cyc-key-name { font-weight: 700; }
.rvw-cyc-key-range { color: var(--muted); }

/* ---- Review: collapsible sections ---- */
/* Nine reports about one month read as a wall when all are open, so each is a
   section that remembers its own state. A CLOSED header still carries the
   section's headline figure — a collapsed section should answer its own
   question at a glance and only be opened for the working behind it. */
.rvw-sec { margin: 10px 0 0; }
.rvw-sec-head { display: flex; align-items: center; gap: 9px; width: 100%; padding: 11px 13px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.rvw-sec-head.is-open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: transparent; }
.rvw-sec-ico { font-size: 1rem; flex: 0 0 auto; }
.rvw-sec-title { flex: 1; min-width: 0; font-size: 0.82rem; font-weight: 700; }
/* The figure, not a restatement of the title: what the section would tell you
   if you opened it. */
.rvw-sec-sum { flex: 0 0 auto; font-size: 0.7rem; font-weight: 700; color: var(--muted); max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Drawn, not typed: the down-chevron glyph falls back to a caret in some
   fonts, which then points the wrong way half the time. */
.rvw-sec-chev { flex: 0 0 auto; width: 7px; height: 7px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); transition: transform 0.18s ease; margin: 0 3px 3px 0; }
.rvw-sec-head.is-open .rvw-sec-chev { transform: rotate(-135deg); margin: 3px 3px 0 0; }
.rvw-sec-body { padding: 11px 13px 13px; background: var(--card); border: 1px solid var(--line); border-top: none; border-radius: 0 0 12px 12px; }
.rvw-sec-body > .div-group-head:first-child { margin-top: 0; }
/* Inside a section the panels already sit on card, so they drop their own
   frame rather than boxing a box. */
.rvw-sec-body .rvw-fc, .rvw-sec-body .rvw-cyc { background: transparent; border: none; padding: 0; }
.rvw-sec-body > .rvw-note:last-child { margin-bottom: 0; }

/* The month as a picture: where it has got to, where a usual month would be,
   and where this one is heading. */
.rvw-chart { margin: 12px 0 9px; }
.rvw-dot.is-usual { background: #7c8db5; }

/* A category's recent months, revealed on tap. */
.rvw-item.is-tappable { cursor: pointer; }
.rvw-item.is-open { box-shadow: inset 0 0 0 1px var(--g, var(--line)); }
.rvw-item-detail { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }
.rvw-bars-wrap { display: flex; flex-direction: column; gap: 6px; }
.rvw-bars { display: flex; align-items: flex-end; gap: 5px; }
.rvw-bar-cell { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.rvw-bar-amt { font-size: 0.52rem; font-weight: 700; color: var(--muted); white-space: nowrap; }
.rvw-bar-cell.is-now .rvw-bar-amt { color: var(--text); }
.rvw-bar-track { width: 100%; height: 40px; display: flex; align-items: flex-end; background: var(--card-2); border-radius: 4px; overflow: hidden; }
.rvw-bar-fill { width: 100%; background: rgba(124,141,181,0.65); border-radius: 4px 4px 0 0; }
.rvw-bar-cell.is-now .rvw-bar-fill { background: var(--accent); }
.rvw-bar-mon { font-size: 0.55rem; font-weight: 700; color: var(--muted); text-transform: uppercase; }
.rvw-bars-foot { font-size: 0.62rem; color: var(--muted); text-align: right; font-weight: 600; }

/* Thirds of the month are tappable: the shape only becomes actionable once you
   know which bills sit in the hump. */
.rvw-cyc-bar .rvw-cyc-seg { border: none; font: inherit; font-size: 0.62rem; font-weight: 800; cursor: pointer; padding: 0; }
.rvw-cyc-detail { margin-top: 10px; padding: 9px 11px; background: var(--card-2); border: 1px solid var(--line); border-radius: 9px; }
.rvw-cyc-detail-head { font-size: 0.6rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); margin-bottom: 5px; }
.rvw-cyc-tap { font-size: 0.58rem; color: var(--muted); text-align: center; margin-top: 7px; font-weight: 600; }

/* The week as seven bars. A table of averages says the same thing but has to
   be read; the tall bar IS the answer. */
.rvw-dow { display: flex; align-items: flex-end; gap: 4px; margin: 12px 0 4px; }
.rvw-dow-cell { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.rvw-dow-amt { font-size: 0.5rem; font-weight: 700; color: var(--muted); white-space: nowrap; }
.rvw-dow-track { width: 100%; height: 46px; display: flex; align-items: flex-end; background: var(--card-2); border-radius: 4px; overflow: hidden; }
.rvw-dow-fill { width: 100%; background: rgba(96,165,250,0.55); border-radius: 4px 4px 0 0; }
.rvw-dow-cell.is-weekend .rvw-dow-fill { background: #a855f7; }
.rvw-dow-cell.is-weekend .rvw-dow-amt { color: var(--text); }
.rvw-dow-lbl { font-size: 0.55rem; font-weight: 700; color: var(--muted); }

/* ---- Note field ---- */
/* The panel IS the field: the textarea inside carries no frame of its own, so
   what would otherwise be a grey box with a label above it reads as one
   designed control. It grows with the text rather than scrolling inside three
   fixed lines, and lights its border on focus like the inputs around it. */
.note-field { background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px 10px; transition: border-color 0.15s ease; }
.note-field:focus-within { border-color: var(--accent); }
.note-field-head { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.note-field-ico { font-size: 0.82rem; }
.note-field-label { flex: 1; font-size: 0.68rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
/* Silent until the limit is near, then amber. */
.note-count { font-size: 0.58rem; font-weight: 700; color: var(--warn); }
textarea.note-input { display: block; width: 100%; min-height: 44px; background: transparent; border: none; padding: 0; color: var(--text); font-family: inherit; font-size: 0.9rem; line-height: 1.5; resize: none; outline: none; overflow-y: auto; }
textarea.note-input::placeholder { color: var(--muted); opacity: 0.7; }
.note-field-foot { font-size: 0.58rem; color: var(--muted); margin-top: 7px; }

/* ---- Personal Finance ---- */
/* Six groups of personal categories, coloured so the roll-up is scannable
   without reading it. Separate hues from the household set on purpose: the two
   trackers should not look like the same list at a glance. */
.pf-g-food     { --g: #fb7185; }
.pf-g-shopping { --g: #38bdf8; }
.pf-g-travel   { --g: #34d399; }
.pf-g-health   { --g: #a78bfa; }
.pf-g-fun      { --g: #f59e0b; }
.pf-g-other    { --g: #64748b; }
.rvw-dot.is-house { background: #60a5fa; }
.rvw-dot.is-personal { background: #f59e0b; }

/* Two allowances side by side, because half-checking one is how a month comes
   in "under" while the card is 3,000 over. */
.pf-lims { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 2px 0 8px; }
.pf-lim { background: var(--card); border: 1px solid var(--line); border-radius: 11px; padding: 9px 11px; min-width: 0; }
.pf-lim.is-over { border-color: var(--bad); }
.pf-lim-top { display: flex; align-items: baseline; gap: 5px; }
.pf-lim-ico { font-size: 0.8rem; flex: 0 0 auto; }
.pf-lim-name { font-size: 0.62rem; font-weight: 800; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; flex: 1; }
.pf-lim-fig { font-size: 0.72rem; font-weight: 800; white-space: nowrap; }
.pf-lim-track { height: 6px; border-radius: 999px; background: var(--card-2); overflow: hidden; margin: 7px 0 5px; }
.pf-lim-fill { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.pf-lim.is-over .pf-lim-fill { background: var(--bad); }
.pf-lim-foot { font-size: 0.6rem; color: var(--muted); font-weight: 600; }
.pf-lim.is-over .pf-lim-foot { color: var(--bad); }
/* The two read together, plus what a day can still take - the figure that
   actually changes a decision on the day. */
.pf-both { font-size: 0.68rem; font-weight: 700; color: var(--muted); text-align: center; padding: 8px 10px; background: var(--card); border: 1px solid var(--line); border-radius: 10px; margin: 0 0 10px; }
.pf-both.is-over { color: var(--bad); border-color: var(--bad); }

/* Limits tab: both figures editable, Save appearing only once one changes. */
.pf-lim-form { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 13px; }
.pf-lim-edit { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pf-lim-edit-cell { min-width: 0; }
.pf-lim-edit-lbl { font-size: 0.66rem; font-weight: 700; color: var(--muted); margin-bottom: 5px; }
input.pf-lim-input { width: 100%; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--card-2); color: var(--text); font-size: 1rem; font-weight: 800; }
.pf-lim-edit-sub { font-size: 0.56rem; color: var(--muted); margin-top: 4px; line-height: 1.35; }
.pf-lim-form-foot { display: flex; justify-content: flex-end; margin-top: 11px; }
.pf-lim-save { padding: 8px 14px; font-size: 0.76rem; }

/* Month by month against the limits: four columns, over months marked. */
.pf-hist { border: 1px solid var(--line); border-radius: 11px; overflow: hidden; }
.pf-hist-row { display: grid; grid-template-columns: 1.1fr 1fr 1fr 1fr; gap: 6px; padding: 8px 11px; border-bottom: 1px solid var(--line); font-size: 0.74rem; font-weight: 600; background: var(--card); }
.pf-hist-row:last-child { border-bottom: none; }
.pf-hist-row.is-head { background: var(--card-2); font-size: 0.6rem; font-weight: 800; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.pf-hist-row span:not(:first-child) { text-align: right; }
.pf-hist-row .is-bad { color: var(--bad); font-weight: 800; }
.pf-hist-row .is-good { color: var(--good); }

/* Card check: one bar per card, house and personal stacked inside the bill. */
.pf-card-check { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; margin-bottom: 8px; }
.pf-cc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pf-cc-name { font-size: 0.85rem; font-weight: 700; }
.pf-cc-billed { font-size: 0.7rem; font-weight: 700; color: var(--muted); white-space: nowrap; }
/* The track is the BILL; what the two trackers explain fills it from the left,
   so the empty remainder is literally the unaccounted part. */
.pf-cc-track { display: flex; height: 9px; border-radius: 999px; overflow: hidden; background: var(--card-2); margin: 9px 0 7px; }
.pf-cc-fill.is-house { background: #60a5fa; }
.pf-cc-fill.is-personal { background: #f59e0b; }
.pf-cc-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 0.64rem; color: var(--muted); font-weight: 600; }
.pf-cc-gap { margin-top: 8px; font-size: 0.66rem; font-weight: 700; color: var(--muted); line-height: 1.4; }
.pf-cc-gap.is-gap { color: var(--warn); }
.pf-cc-gap.is-overlogged { color: var(--bad); }
.pf-cc-gap.is-ok { color: var(--good); }

@media (max-width: 340px) {
  .pf-lims, .pf-lim-edit { grid-template-columns: 1fr; }
}

/* ---- Personal spend FAB ---- */
/* Black, where the household spend button is a white circle with an orange
   money bag — two buttons share the corner on Home and which money they log
   has to be obvious before the icon is read. A faint light ring keeps the
   circle visible against a dark background, where a black fill would
   otherwise disappear into it. Same 56px as its neighbour rather than the
   smaller secondary size: these are two peer actions, not a primary and its
   helper. */
.fab.fab-personal {
  background: #111318;
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 14px rgba(0,0,0,0.32), 0 12px 28px rgba(0,0,0,0.28), 0 0 0 1px rgba(255,255,255,0.14);
}
.fab.fab-personal:active { transform: translateY(1px); box-shadow: 0 4px 10px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.14); }
.fab.fab-personal svg, .fab.fab-personal img { width: 26px; height: 26px; display: block; object-fit: contain; }
/* On Home both live in the bottom-right corner, STACKED rather than spread
   along the bottom edge. The household one keeps the lower slot, being the
   one logged more often and so the one the thumb should find first. */
.fab.fab-personal.is-second { bottom: calc(78px + 56px + 12px + var(--safe-bottom)); }
/* The statement window under a card's name: the whole reason these figures
   differ from the Spends tab's, so it is stated rather than implied. */
.pf-cc-win { font-size: 0.6rem; font-weight: 700; color: var(--accent); margin-top: 3px; letter-spacing: 0.2px; }
.pf-cc-win.is-nocycle { color: var(--muted); }
/* What is logged against a card this cycle: household plus personal, beside
   the statement figure rather than added into it. Derived on every render, so
   it is always the sum of the entries and never a second copy of them. */
.cc-logged { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); font-size: 0.66rem; }
.cc-logged-label { font-size: 0.58rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); }
.cc-logged-split { flex: 1; min-width: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 2px 3px; color: var(--muted); font-weight: 600; }
.cc-logged-split .rvw-dot { margin: 0 2px 0 6px; }
.cc-logged-split .rvw-dot:first-child { margin-left: 0; }
.cc-logged-total { font-weight: 800; }

/* Home is the only screen without a bottom nav, so the 78px every other
   screen needs to clear one is just a gap underneath the buttons there. They
   drop to the same 18px inset they already keep from the right edge, which
   puts them squarely in the footer corner. */
body[data-mode="home"] .fab { bottom: calc(18px + var(--safe-bottom)); }
body[data-mode="home"] .fab.fab-personal.is-second { bottom: calc(18px + 56px + 12px + var(--safe-bottom)); }
/* Just air, not clearance for the whole button stack. The buttons are FIXED,
   so they take no page space; padding tall enough to sit under both of them
   only bought 160px of empty scroll below a page that already ended. What
   actually keeps the backup line off them is the padding-right below, which
   works whether the page scrolls or not. */
body[data-mode="home"] #homeView { padding-bottom: calc(20px + var(--safe-bottom)); }
/* The buttons are fixed, so on a short page that line can still end up beside
   them however much padding follows it. Keeping the button column clear makes
   it wrap early instead of running underneath. */

/* ---- Monthly sheet: is this row following its source, or set by hand? ---- */
/* A derived row is worth nothing if you cannot tell whether the figure in it
   is live. "auto" says it tracks its source; "set ↻" says someone typed it,
   and is a button that puts it back to following in one tap. */
.msheet-follow { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; padding: 1px 5px; border-radius: 999px; font-size: 0.5rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; border: 1px solid var(--line); background: var(--card-2); color: var(--muted); vertical-align: middle; }
button.msheet-follow { font-family: inherit; cursor: pointer; }
.msheet-follow.is-override { border-color: rgba(245,158,11,0.5); color: var(--warn); }
.msheet-follow.is-override:active { background: rgba(245,158,11,0.16); }
/* Deliberately muted - present on every field the sheet can save, but never
   competing with the label/value for attention. See historyBtn/saveField in
   renderExpenseSheet, and openSheetFieldHistory for what it opens. */
.msheet-history { display: inline-flex; vertical-align: middle; margin-left: 4px; padding: 2px; color: var(--muted); opacity: 0.45; }
.msheet-history .edit-ico { width: 13px; height: 13px; }
.msheet-history:active { opacity: 0.9; }
/* Which window each half of the allowance is counted over. Stated, because a
   September list can legitimately hold a spend dated 25 August. */
.pf-window-note { margin: -4px 0 10px; font-size: 0.6rem; line-height: 1.45; }

/* ---- Entries filter (Personal Finance -> Spends -> Entries) ---- */
/* Scrolls sideways rather than wrapping: the number of chips is the number of
   cards, and a wrapping row would change the page height every time a card is
   added. */
.pf-filter { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 2px 0 4px; margin: 6px 0 2px; }
.pf-filter::-webkit-scrollbar { display: none; }
.pf-filter-chip { flex: 0 0 auto; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--muted); font: inherit; font-size: 0.72rem; font-weight: 700; cursor: pointer; white-space: nowrap; }
.pf-filter-chip.active { background: var(--card-2); border-color: var(--accent); color: var(--text); box-shadow: inset 0 0 0 1px var(--accent); }
/* What the filter is showing, since the allowance strips above stay whole. */
.pf-filter-note { margin: 2px 0 8px; font-size: 0.62rem; font-weight: 600; }

/* ---- Tags on a spend ---- */
/* Chosen tags, a box to type a new one, and the tags already in use to tap.
   The panel is the field, same shape as the note field it replaces. */
.tag-field { background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px 10px; transition: border-color 0.15s ease; }
.tag-field:focus-within { border-color: var(--accent); }
.tag-field-head { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.tag-field-label { flex: 1; font-size: 0.68rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.tag-count { font-size: 0.58rem; font-weight: 700; color: var(--muted); }
/* A chosen tag is a button: the whole chip removes it, so there is no 8px
   target to hit on a phone. */
.tag-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 7px; }
.tag-chip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 8px; border-radius: 999px; border: 1px solid var(--accent); background: rgba(56,189,248,0.14); color: var(--text); font: inherit; font-size: 0.72rem; font-weight: 700; cursor: pointer; }
.tag-chip-x { font-style: normal; font-size: 0.8rem; line-height: 1; color: var(--muted); }
.tag-chip:active { background: rgba(56,189,248,0.26); }
input.tag-input { display: block; width: 100%; background: transparent; border: none; padding: 0; color: var(--text); font-family: inherit; font-size: 0.9rem; outline: none; }
input.tag-input::placeholder { color: var(--muted); opacity: 0.7; }
/* Already-used tags, most-used first. Scrolls sideways rather than growing the
   sheet as the vocabulary does. */
.tag-suggest { display: flex; gap: 5px; overflow-x: auto; scrollbar-width: none; margin-top: 9px; padding-bottom: 2px; }
.tag-suggest::-webkit-scrollbar { display: none; }
.tag-sugg { flex: 0 0 auto; padding: 4px 9px; border-radius: 999px; border: 1px dashed var(--line); background: transparent; color: var(--muted); font: inherit; font-size: 0.68rem; font-weight: 600; cursor: pointer; white-space: nowrap; }
.tag-sugg:active { border-style: solid; color: var(--text); }

/* Tags on an entry row, read-only. */
.tag-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.tag-pill { padding: 2px 7px; border-radius: 999px; background: var(--card-2); border: 1px solid var(--line); font-size: 0.58rem; font-weight: 700; color: var(--muted); letter-spacing: 0.2px; }
/* Payment method badge in heatmap cell modals - green to signal a positive
   marker (the channel through which money moved), distinct from narrative tags. */
.tag-pill.hm-payment-badge { background: rgba(52,211,153,0.2); color: var(--good); border-color: var(--good); }
/* Inside a section that already says "Tags", the panel drops its own label and
   keeps only the counter. */
.tag-field-head.is-bare { justify-content: flex-end; margin-bottom: 4px; min-height: 12px; }

/* ---- Heatmap: what the bookmarks would cost ---- */
/* Sits between the grid and the scale, because the grid is where a stock gets
   starred and this is the question that raises: one share of each, priced now. */
.hm-basket { margin: 12px 0 4px; }
.hm-basket-head { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 13px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.hm-basket-head.is-open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: transparent; }
.hm-basket-star { flex: 0 0 auto; font-size: 0.95rem; color: #f59e0b; }
.hm-basket-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hm-basket-count { font-size: 0.8rem; font-weight: 700; }
.hm-basket-sub { font-size: 0.6rem; color: var(--muted); font-weight: 600; }
.hm-basket-total { flex: 0 0 auto; font-size: 1rem; font-weight: 800; white-space: nowrap; }
/* Drawn, not typed - the same caret the Review sections use. */
.hm-basket-chev { flex: 0 0 auto; width: 7px; height: 7px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); transition: transform 0.18s ease; margin: 0 2px 3px 0; }
.hm-basket-head.is-open .hm-basket-chev { transform: rotate(-135deg); margin: 3px 2px 0 0; }
.hm-basket-list { background: var(--card); border: 1px solid var(--line); border-top: none; border-radius: 0 0 12px 12px; overflow: hidden; }
.hm-basket-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 8px 13px; border-top: 1px solid var(--line); font-size: 0.76rem; }
.hm-basket-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hm-basket-price { flex: 0 0 auto; font-weight: 700; }
/* A bookmark with no price is counted but not priced, and looks it. */
.hm-basket-price.is-none { color: var(--warn); font-weight: 600; font-size: 0.66rem; }
.hm-basket.is-empty .hm-basket-empty { padding: 11px 13px; background: var(--card); border: 1px dashed var(--line); border-radius: 12px; font-size: 0.68rem; color: var(--muted); line-height: 1.45; }

/* ---- Editing the category lists ---- */
/* The + beside a label. Small and quiet: it is an occasional action sitting
   next to the thing it adds to, not a call to action. */
.cat-add-btn { flex: 0 0 auto; width: 20px; height: 20px; margin-left: 6px; padding: 0; border-radius: 50%; border: 1px solid var(--line); background: var(--card-2); color: var(--muted); font: inherit; font-size: 0.85rem; line-height: 1; cursor: pointer; vertical-align: middle; }
.cat-add-btn:active { border-color: var(--accent); color: var(--accent); }
/* The "Category" title row in the personal form, which has no field label of
   its own to hang the + from. */
.cat-head-row { display: flex; align-items: center; margin-bottom: 8px; }
.cat-head-label { font-size: 0.78rem; color: var(--muted); }
/* A group label is a flex row now, so its + sits on the same line. */
.spend-cat-group-label { display: flex; align-items: center; }
.field > label { display: flex; align-items: center; }

/* The editor itself: one row per name, with what it is carrying. */
.cat-rows { display: flex; flex-direction: column; gap: 6px; }
.cat-row { display: flex; align-items: center; gap: 8px; }
input.cat-name { flex: 1; min-width: 0; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--card); color: var(--text); font-family: inherit; font-size: 0.9rem; }
/* How many entries a name carries, which is what decides whether it can go. */
.cat-used { flex: 0 0 auto; font-size: 0.58rem; font-weight: 700; color: var(--muted); text-align: right; min-width: 46px; }
.cat-row.is-used .cat-used { color: var(--warn); }
.cat-del { flex: 0 0 auto; }
.cat-row.is-used .cat-del { opacity: 0.45; }
.cat-add { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
.btn.small { padding: 8px 12px; font-size: 0.76rem; white-space: nowrap; }

/* The Overall chip sits with the portfolios but is not one of them, so it reads
   slightly apart - a divider before it and a quieter idle state. */
.ptab.is-overall { margin-left: 10px; }

/* ---- "For others" on a personal spend ---- */
/* A smaller switch, because it sits inside a list row rather than a form. */
.switch.switch-sm { width: 34px; height: 19px; }
.switch.switch-sm .switch-thumb { top: 2px; left: 2px; width: 15px; height: 15px; }
.switch.switch-sm input:checked + .switch-track .switch-thumb { transform: translateX(15px); }
/* Category on the left, its mark on the right, one line. The category keeps
   the weight `.msheet-label > span:first-child` used to give it - it is no
   longer a direct child - and ellipses rather than pushing the mark off the
   edge. */
/* The mark sits above the figure in the row's right column, so it is flush
   with the row's own edge rather than with wherever the category text
   happened to end. Only the rows that have one stack; the rest keep the
   single centred line every other list uses. */
.trk-entry-right.is-stacked { flex-direction: column; align-items: flex-end; gap: 3px; }
.trk-entry-money { display: flex; align-items: center; gap: 6px; }
/* The same badge shape a refund gets, in the accent colour rather than green:
   both say what a row IS, and the eye should read them as one kind of thing. */
.pf-others-tag {
  flex: 0 0 auto; display: inline-block; padding: 1px 7px; border-radius: 999px;
  font-size: 0.5rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;
  background: rgba(56,189,248,0.14); color: var(--accent); border: 1px solid rgba(56,189,248,0.38);
}
/* A row that is off the limits looks it, so a list can be read without
   checking every switch. */
.trk-entry.is-others { background: var(--card-2); }
.trk-entry.is-others .msheet-val { color: var(--muted); }

/* What the roll-up counts and the strips do not. */
.pf-others-note { margin: -4px 0 10px; font-size: 0.6rem; line-height: 1.45; color: var(--accent); }

/* ---- Allocation: the derived Balance card ---- */
/* Marked apart from the entered categories: it is the only one nobody types,
   and reading it as another allocation would be wrong. */
.alloc-card.alloc-card-balance { border-style: dashed; border-color: var(--accent); }
.alloc-card.alloc-card-balance .alloc-label { color: var(--accent); }
.alloc-card.alloc-card-balance.is-neg { border-color: var(--bad); }
.alloc-card.alloc-card-balance.is-neg .alloc-label,
.alloc-card.alloc-card-balance.is-neg .alloc-value { color: var(--bad); }
.alloc-balance-note { margin: 8px 0 0; font-size: 0.62rem; line-height: 1.45; }

/* ---- Itemised sheet rows: Virtual Bal and Other Expense ---- */
/* The headline is a total now, so it sits beside its + rather than being a box
   you can type into. */
.msheet-list { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.msheet-list-btn { width: 24px; height: 24px; margin-left: 0; font-size: 1rem; color: var(--accent); border-color: rgba(59,130,246,0.45); }

.vb-rows { display: flex; flex-direction: column; gap: 6px; }
.vb-row { display: flex; align-items: center; gap: 8px; }
input.vb-label { flex: 1 1 auto; min-width: 0; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--card); color: var(--text); font-family: inherit; font-size: 0.9rem; }
input.vb-amt { flex: 0 0 96px; width: 96px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--card); color: var(--text); font-family: inherit; font-size: 0.9rem; font-weight: 700; text-align: right; }
.vb-del { flex: 0 0 auto; }
.vb-add { display: flex; margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
/* The running total, so the figure the sheet will show is visible while the
   list is still being edited. */
.vb-total { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 14px; padding: 11px 13px; border-radius: 11px; background: var(--card-2); border: 1px solid var(--line); }
.vb-total-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted); }
.vb-total-val { font-size: 1.05rem; font-weight: 800; color: var(--text); }
.vb-total-val.is-credit { color: var(--good); }
.vb-total-val.is-debit { color: var(--bad); }

/* ---- Where the reimbursement figure came from ---- */
.cc-reimb-card h3 { display: flex; align-items: center; }
/* The two halves behind the total, so it is never a number to take on trust. */
.cc-reimb-split { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin: 8px 0 0; }
.cc-reimb-split b { margin-left: auto; font-weight: 800; color: var(--text); }

/* ---- Tags tab ---- */
.tag-an-scope { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.rvw-dot.is-flat { background: var(--line); }

/* Coverage first: how much of the scope the tags actually speak for. */
.tag-cover-bar { height: 10px; border-radius: 999px; background: var(--line); overflow: hidden; }
.tag-cover-fill { display: block; height: 100%; border-radius: 999px; background: var(--accent); }
.tag-cover-legend { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; font-size: 0.72rem; color: var(--muted); }
.tag-cover-legend b { margin-left: auto; color: var(--text); font-weight: 800; }

/* ---- Finding spends by tag ---- */
.tag-find { margin: 0 0 14px; }
.tag-find-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.tag-find-label {
  flex: 1; min-width: 0; font-size: 0.66rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted);
}
.tag-find-mode { display: flex; flex: 0 0 auto; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.tag-find-mode button {
  font-size: 0.64rem; font-weight: 600; padding: 4px 12px; cursor: pointer;
  border: 0; background: transparent; color: var(--muted); font-family: inherit;
}
.tag-find-mode button.active { background: var(--accent); color: #04222e; font-weight: 700; }
.tag-find-clear {
  flex: 0 0 auto; font-size: 0.68rem; font-weight: 600; color: var(--accent);
  background: none; border: 0; cursor: pointer; padding: 4px 2px; font-family: inherit;
}
/* Capped and scrollable: forty tags would otherwise push the results
   themselves off the screen. */
/* Two and a half rows. The half row peeking at the bottom is what says there
   is more below; a whole row would read as the end of the list. */
.tag-cloud {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  max-height: 98px; overflow-y: auto; scrollbar-width: thin;
}
/* --w is the tag's share of the heaviest, 0-100; --fs its font size. The flat
   background is declared first so a browser without color-mix gets a plain
   chip rather than none. */
.tag-cloud-chip {
  display: flex; align-items: baseline; gap: 6px; cursor: pointer; font-family: inherit;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--card); color: var(--text);
  background: color-mix(in srgb, var(--accent) calc(var(--w) * 0.20%), var(--card));
  border-color: color-mix(in srgb, var(--accent) calc(var(--w) * 0.45%), var(--line));
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.tag-cloud-chip:active { transform: scale(0.96); }
.tag-cloud-name { font-size: var(--fs, 0.8rem); font-weight: 700; line-height: 1.15; }
.tag-cloud-amt { font-size: 0.62rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
.tag-cloud-chip.active {
  background: var(--accent); border-color: var(--accent); color: #04222e;
  box-shadow: 0 2px 10px rgba(56,189,248,0.35);
}
.tag-cloud-chip.active .tag-cloud-amt { color: #04222e; opacity: 0.72; }

/* Sort, over the list it sorts. */
input.tag-search {
  flex: 1; min-width: 0; padding: 8px 12px; font-size: 0.8rem; font-family: inherit;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--text);
}
input.tag-search:focus { outline: none; border-color: var(--accent); }
.tag-find-note { margin: 7px 3px 0; font-size: 0.64rem; color: var(--muted); }

.tag-sortbar { display: flex; align-items: center; gap: 8px; margin: 0 0 9px; }

/* Twelve months of a tag, on its closed row. */
.tag-spark {
  display: flex; align-items: flex-end; gap: 3px; height: 17px; margin: 9px 0 1px;
  width: 100%; max-width: 250px;
}
.tag-spark-bar { flex: 1 1 0; min-width: 0; border-radius: 2px 2px 0 0; background: var(--accent); opacity: 0.34; }
.tag-spark-bar.is-zero { opacity: 0.12; }
.tag-spark-bar.is-now { opacity: 0.95; }

.tag-find-figs { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
.tag-find-fig-n { font-size: 1.1rem; font-weight: 800; line-height: 1.2; }
.tag-find-fig-l { font-size: 0.64rem; color: var(--muted); margin-top: 1px; }
.tag-find-sum h3 { overflow-wrap: anywhere; }

.tag-find-tags { margin-top: 4px; }
.tag-pill.is-hit { border-color: var(--accent); color: var(--accent); font-weight: 700; }
button.tag-pill.is-tappable { cursor: pointer; font-family: inherit; }

.tag-an-list { display: flex; flex-direction: column; gap: 8px; }
.tag-an-sec { border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); overflow: hidden; }
.tag-an-head {
  display: block; width: 100%; padding: 12px 34px 12px 13px; position: relative;
  background: transparent; border: none; color: var(--text); font-family: inherit; text-align: left; cursor: pointer;
}
.tag-an-top { display: flex; align-items: center; gap: 7px; }
.tag-an-total { margin-left: auto; font-weight: 800; font-size: 0.95rem; white-space: nowrap; }
.tag-an-cadence { padding: 1px 6px; border-radius: 999px; border: 1px solid var(--line); background: var(--card-2); color: var(--muted); font-size: 0.5rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; }
.tag-an-trend { font-size: 0.6rem; font-weight: 800; }
.tag-an-trend.is-up { color: var(--bad); }
.tag-an-trend.is-down { color: var(--good); }
/* Share of tagged spending, not of all spending - the foot note says why. */
.tag-an-track { display: block; height: 5px; margin: 9px 0 7px; border-radius: 999px; background: var(--line); overflow: hidden; }
.tag-an-fill { display: block; height: 100%; border-radius: 999px; background: var(--accent); }
.tag-an-meta { display: block; font-size: 0.66rem; color: var(--muted); line-height: 1.5; }
.tag-an-chev { position: absolute; right: 12px; top: 15px; }
.tag-an-body { padding: 0 13px 12px; border-top: 1px dashed var(--line); }
.tag-an-body > .rvw-bars-wrap { margin-top: 12px; }
.tag-an-split { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin: 10px 0 0; }
.tag-an-with { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.tag-an-with-label { font-size: 0.58rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted); }
.tag-an-entries { margin-top: 10px; }
.tag-an-entries .trk-entry { cursor: default; }
.tag-an-foot { margin: 14px 0 0; line-height: 1.55; }

/* ---- Refund: a personal spend that came back ---- */
/* Green wherever it appears, and shown as "+₹500" rather than a minus sign
   buried in a column of black figures. */
.spend-cat-btn.is-refund { border-color: rgba(52,211,153,0.55); color: var(--good); }
.spend-cat-btn.is-refund.active { background: var(--good); border-color: var(--good); color: #06281c; }
.field.is-refund > label { color: var(--good); }
.pf-refund-note { margin: -2px 0 10px; line-height: 1.5; color: var(--good); }

.trk-entry.is-refund .msheet-val { color: var(--good); }
.pf-refund-tag { flex: 0 0 auto; display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: 0.5rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; background: rgba(52,211,153,0.16); color: var(--good); border: 1px solid rgba(52,211,153,0.4); }
.pf-refund-line { margin: 6px 0 0; color: var(--good); line-height: 1.5; }

.trk-cat.is-refund .trk-cat-amt { color: var(--good); }
.trk-group-head.is-refund .trk-group-total, .trk-group-head.is-refund .trk-group-pct { color: var(--good); }
.trk-cat.is-refund .trk-cat-dot { background: var(--good); }
.trk-cat.is-refund .trk-cat-fill { background: var(--good); }
.tag-an-top.is-refund .tag-an-total { color: var(--good); }

/* The tag box doubles as a search over the tags already in use. */
.tag-sugg.is-exact { border-color: var(--accent); color: var(--accent); font-weight: 700; }
/* The only child when it shows, and it has to WRAP rather than scroll off
   the side of a strip built for short chips. */
.tag-sugg-none { flex: 1 1 auto; min-width: 0; white-space: normal; font-size: 0.66rem; color: var(--muted); line-height: 1.5; padding: 2px 0; }

/* ---- Card bill: ongoing / due / paid ---- */
/* Ongoing is information, so it stays quiet. Due is the one state that wants
   an action, so it IS the action - a filled button, not a badge. */
.cc-status-ongoing { background: var(--card-2); color: var(--muted); border: 1px solid var(--line); font-weight: 700; }
.cc-pay-btn {
  padding: 6px 13px; border-radius: 999px; border: none;
  background: var(--bad); color: #fff;
  font: inherit; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.2px;
  cursor: pointer; white-space: nowrap;
}
.cc-pay-btn:active { filter: brightness(0.9); }
.cc-pay-row { margin-top: 14px; }
.cc-pay-cancel { width: 100%; margin-top: 10px; }
/* Due date beside the Pay button - the date that matters, not the close date. */
.cc-due-wrap { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.cc-due-when { font-size: 0.58rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); }
.cc-due-when.is-overdue { color: var(--bad); }
.cc-pay-btn.is-overdue { box-shadow: 0 0 0 2px rgba(248,113,113,0.28); }

/* ---- Home: what a day still has in it ---- */
/* Shorter than the 52px icon beside it, so a card that carries one is exactly
   as tall as one that does not. */
.home-card-badge {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 50px; padding: 3px 7px; margin-right: 2px;
  border-radius: 8px; border: 1px solid transparent; line-height: 1.05;
  /* Pinned to the TOP of the row rather than centred, so it reads as the
     card's top-right corner. Still a flex item, not absolute, so it reserves
     its own width and the subtitle can never run underneath it. */
  align-self: flex-start; margin-top: -2px;
}
.home-card-badge-val { font-size: 0.72rem; font-weight: 800; letter-spacing: -0.2px; white-space: nowrap; }
.home-card-badge-cap { font-size: 0.44rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; opacity: 0.75; margin-top: 1px; }

.home-card-badge.is-ok  { background: rgba(52,211,153,0.14); border-color: rgba(52,211,153,0.42); color: var(--good); }
.home-card-badge.is-mid { background: rgba(245,158,11,0.14); border-color: rgba(245,158,11,0.45); color: var(--warn); }
.home-card-badge.is-low { background: rgba(248,113,113,0.16); border-color: rgba(248,113,113,0.5); color: var(--bad); }
/* Only the bottom band moves. A badge that always animates stops being read,
   and this one is meant to interrupt. */
@keyframes homePerDayPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
.home-card-badge.is-low { animation: homePerDayPulse 1.3s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .home-card-badge.is-low { animation: none; } }
/* Drawn wallet on the Personal Finance home card - sized like the metal bars,
   which is the other drawn icon in that row. */
.wallet-ico { width: 30px; height: 30px; display: block; }

/* ---- Month by month: a settled bill is struck through ---- */
.cc-grid td.is-paid { text-decoration: line-through; text-decoration-thickness: 1.5px; opacity: 0.55; }
.cc-grid td.is-paid.is-late { text-decoration-color: var(--warn); }

/* ---- Review: which month, since there is no strip to say so ---- */
.rvw-scope { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin: 2px 0 12px; }
.rvw-scope-ym { font-size: 1.02rem; font-weight: 800; letter-spacing: -0.2px; }
.rvw-scope-note { font-size: 0.66rem; color: var(--muted); }
.rvw-scope-why { margin: -6px 0 12px; line-height: 1.5; }

/* ---- An explanation, behind an i ---- */
.explain-row {
  display: flex; align-items: center; gap: 7px; width: 100%; margin-top: 10px;
  padding: 6px 0 0; border: none; border-top: 1px dashed var(--line);
  background: transparent; color: var(--muted); font: inherit; font-size: 0.66rem;
  text-align: left; cursor: pointer;
}
.explain-row:active { color: var(--text); }
.explain-i {
  flex: 0 0 auto; width: 15px; height: 15px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card-2);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.62rem; font-weight: 700; font-style: italic; font-family: Georgia, serif;
}
.info-para { margin: 0 0 12px; font-size: 0.82rem; line-height: 1.6; color: var(--muted); }
.info-para:last-of-type { margin-bottom: 4px; }
.info-close { width: 100%; margin-top: 8px; }

/* ---- Splitting the milk out of a shop run ---- */
.milk-split { padding: 10px 12px; border: 1px dashed var(--line); border-radius: 11px; background: var(--card-2); }
.milk-row { display: flex; align-items: center; gap: 9px; margin: 0; }
.milk-lbl { flex: 1; font-size: 0.82rem; font-weight: 600; }
/* The amount only appears once the box is ticked, so the row stays one line
   until it has something to say. */
.milk-amt-wrap { flex: 0 0 auto; display: flex; align-items: center; gap: 3px; padding: 4px 9px; border: 1px solid var(--line); border-radius: 9px; background: var(--card); }
.milk-amt-cur { font-size: 0.76rem; color: var(--muted); }
input.milk-amt { width: 68px; padding: 0; border: none; background: transparent; color: var(--text); font: inherit; font-size: 0.86rem; font-weight: 700; text-align: right; }
input.milk-amt:focus { outline: none; }
.milk-note { margin: 8px 0 0; line-height: 1.5; }

/* ---- Tracker heatmap: every month at once ---- */
/* The chip sits with the months but is not one of them, so it reads slightly
   apart - the same treatment the Overall chip gets on the stocks Overview. */
.trk-heat-chip { margin-right: 10px; font-weight: 800; }

.trk-heat td { text-align: right; font-variant-numeric: tabular-nums; }
/* A cell that actually holds a spend opens its entries directly - the dotted
   underline is the same tap cue the month header carries, so both read as
   "there's more here" without needing a second visual language. A cell with
   nothing in it (the em dash) gets neither the class nor the cursor. */
.trk-heat td.is-clickable { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; }
.trk-heat th.is-now { color: var(--accent); }
/* A month header opens the same sheet the entries list uses elsewhere, so
   only the cursor and a faint underline mark it as tappable - no bespoke
   list styling needed, .msheet-row carries all of that already. */
.trk-heat th.is-clickable { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
.trk-heat-kitty td { background: rgba(59,130,246,0.16); font-weight: 700; }
.trk-heat-quiet td { color: var(--muted); }

/* Spent, Left, Days left, Per day - a block, not four more category rows.
   The rows above say where the money went; these say whether the month
   worked, and they were styled identically, so the eye had to find them by
   reading labels.

   Banded, with a rule across the top and an accent edge down the labels. The
   band is declared HERE, above the h- rules, on purpose: a cell carrying a
   heat colour keeps it, because that colour is the answer and the band is
   only the frame around it. */
.trk-heat tr.cc-sum th.rowhead {
  color: var(--text); font-weight: 800;
  /* The tint over an opaque base, not instead of it: this cell is sticky, so
     a transparent band would let the scrolling columns show through it. The
     doubled gradient is how you get exactly the cells' tint, opaquely. */
  background: linear-gradient(rgba(148,163,184,0.22), rgba(148,163,184,0.22)), var(--bg-2);
  
}
/* `.trk-heat .cc-sum td`, not `.trk-heat tr.cc-sum td`: dropping the `tr`
   leaves this at exactly the weight of the `.trk-heat td.h-low2` rules below,
   so a summary cell with no band of its own still gets this one. With the
   `tr` in, this outranked them and painted the whole block flat. */
.trk-heat .cc-sum td { background: rgba(148,163,184,0.22); }
.trk-heat tr.trk-sum-top th, .trk-heat tr.trk-sum-top td { border-top: 2px solid var(--line); }

/* The same five bands, deepened, for the four rows that matter most.
   They sit on a grey band, so the lighter mixes the categories use would come
   out weaker down here than they do up there - the exact opposite of what
   this block is for. Three classes to a rule, so these beat the base bands
   whatever the source order. */
.trk-heat .cc-sum td.h-low2 { background: rgba(16,185,129,0.55); color: var(--text); }
.trk-heat .cc-sum td.h-low1 { background: rgba(16,185,129,0.30); }
.trk-heat .cc-sum td.h-mid  { background: rgba(148,163,184,0.22); }
.trk-heat .cc-sum td.h-hi1  { background: rgba(239,68,68,0.34); }
.trk-heat .cc-sum td.h-hi2  { background: rgba(239,68,68,0.62); color: var(--text); font-weight: 800; }

/* Category cells now colour via a continuous inline background (_heatCell in
   app.js, scaled by % change from the month before) rather than fixed bands -
   these three classes are the only cases that AREN'T on that scale. */
.trk-heat td.h-none { color: var(--muted); opacity: 0.45; }
/* Money coming back, not money going out at some rate against last month -
   the same green the refund badge uses elsewhere in the app, so the two read
   as one fact rather than two different colour languages. */
.trk-heat td.h-refund { background: rgba(52,211,153,0.16); color: var(--good); font-weight: 700; }
/* Neutral, not invisible: reserved for the one case with nothing earlier to
   compare against at all - every other real value gets a real green/red
   shade now, never a flat "about the same" grey. */
.trk-heat td.h-mid  { background: rgba(148,163,184,0.22); }

.trk-heat-avg { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin-top: 14px; padding: 10px 12px; background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; }
.trk-heat-avg-lbl { font-size: 0.8rem; font-weight: 700; }
.trk-heat-avg-val { font-size: 0.95rem; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.trk-heat-avg-note { font-size: 0.66rem; color: var(--muted); margin-left: auto; }

.trk-heat-key { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.trk-heat-key-lbl { font-size: 0.58rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted); margin-right: 3px; }
.trk-heat-swatch { padding: 2px 7px; border-radius: 6px; font-size: 0.58rem; font-weight: 700; color: var(--text); }
.trk-heat-swatch.h-low2 { background: rgba(52,211,153,0.34); }
.trk-heat-swatch.h-low1 { background: rgba(52,211,153,0.16); }
.trk-heat-swatch.h-mid  { background: var(--card-2); color: var(--muted); }
.trk-heat-swatch.h-hi1  { background: rgba(248,113,113,0.18); }
.trk-heat-swatch.h-hi2  { background: rgba(248,113,113,0.4); }
/* Legend gradient bars for the continuous vs-last-month scale (see _heatCell
   in app.js) - a border so the light end still reads against the page. */
.trk-heat-swatch-grad { border: 1px solid var(--line); color: var(--text); }


/* ---- My Passwords ---- */
.fab.fab-vault { background: #1e293b; color: #e2e8f0; font-size: 1.8rem; }

/* The gate. Deliberately plain: one field and one sentence, so nothing
   competes with the thing being typed. */
.vault-gate { max-width: 340px; margin: 8vh auto 0; text-align: center; }
.vault-gate-ico { font-size: 2.6rem; }
.vault-gate-h { margin: 10px 0 6px; font-size: 1.25rem; font-weight: 800; }
input.vault-master {
  width: 100%; margin-top: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 11px;
  background: var(--card); color: var(--text); font-family: inherit; font-size: 1rem;
  letter-spacing: 1px;
}
input.vault-master:focus { outline: none; border-color: var(--accent); }
.vault-note { margin: 10px 0 0; min-height: 1.1em; }
.vault-go { width: 100%; margin-top: 14px; }
.vault-warn { margin: 14px 0 0; line-height: 1.55; color: var(--warn); }

/* Strength, on search space rather than a checklist - see vault.js. */
.vault-meter { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.vault-meter-track { flex: 1; height: 5px; border-radius: 999px; background: var(--line); overflow: hidden; }
.vault-meter-fill { display: block; height: 100%; border-radius: 999px; width: 0; transition: width .15s ease; }
.vault-meter-fill.is-weak { background: var(--bad); }
.vault-meter-fill.is-fair { background: var(--warn); }
.vault-meter-fill.is-good { background: #38bdf8; }
.vault-meter-fill.is-strong { background: var(--good); }
.vault-meter-lbl { flex: 0 0 auto; font-size: 0.6rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); }

.vault-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
/* The paragraph under the vault's action list, indented to the same left
   edge as the names above it rather than to the sheet. */
.vault-opt-foot { margin: 14px 6px 4px; }
input.vault-search {
  flex: 1; min-width: 0; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 11px; background: var(--card); color: var(--text); font-family: inherit; font-size: 0.88rem;
}
input.vault-search:focus { outline: none; border-color: var(--accent); }

.vault-list { display: flex; flex-direction: column; gap: 7px; }

/* Two lines, one row. The icon and the two buttons sit either side of a
   middle column that is allowed to shrink, so a long title ellipses instead
   of pushing the buttons off the edge. Height is set by the 36px icon, which
   is the tallest thing in the card - nothing else can make it grow. */
.vault-card {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); padding: 8px 10px;
}
.vault-card.is-open { border-color: var(--accent); }
.vault-ico {
  flex: 0 0 36px; width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center; font-size: 1.05rem; line-height: 1;
  background: var(--card-2); border: 1px solid var(--line);
}
/* No emoji to show, so the first letter stands in - on a colour fixed by the
   title, which makes an unremarkable list of names findable at a glance. */
.vault-ico.is-letter {
  font-size: 0.95rem; font-weight: 800;
  color: hsl(var(--ico-h), 72%, 74%);
  background: hsl(var(--ico-h), 42%, 20%);
  border-color: hsl(var(--ico-h), 38%, 32%);
}
html[data-theme="light"] .vault-ico.is-letter {
  color: hsl(var(--ico-h), 55%, 30%);
  background: hsl(var(--ico-h), 70%, 93%);
  border-color: hsl(var(--ico-h), 45%, 80%);
}
.vault-card-main { flex: 1; min-width: 0; cursor: pointer; }
.vault-title {
  font-size: 0.92rem; font-weight: 700; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vault-sub {
  font-size: 0.7rem; color: var(--muted); margin-top: 1px; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Monospace when it is the password, so it can be read character by
   character - which is the only reason to have revealed it. */
.vault-sub.is-pw {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.76rem; letter-spacing: 0.6px; color: var(--text);
  white-space: normal; overflow-wrap: anywhere;
}
.vault-acts { display: flex; flex-direction: column; align-items: flex-end; gap: 0; flex: 0 0 auto; }
.vault-act-row { display: flex; align-items: center; gap: 1px; }
.vault-acts .icon-btn { padding: 4px 6px; }
.vault-when { font-size: 0.58rem; color: var(--muted); white-space: nowrap; padding-right: 5px; line-height: 1.2; }

/* How the list is read, not what it contains - so a segmented control rather
   than another icon in the toolbar. */
/* How the list is read on the left, whose it is on the right, one line. The
   people strip scrolls sideways rather than wrapping, so adding a fifth name
   never pushes the A-Z control onto a line of its own. */
.vault-filters { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; min-width: 0; }
.vault-modes {
  display: flex; width: fit-content; flex: 0 0 auto; overflow: hidden;
  border: 1px solid var(--line); border-radius: 999px; background: var(--card);
}
.vault-people {
  display: flex; align-items: center; gap: 5px; flex: 1 1 auto; min-width: 0;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.vault-people::-webkit-scrollbar { display: none; }
.vault-who {
  flex: 0 0 auto; font-size: 0.7rem; font-weight: 600; padding: 6px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--muted); font-family: inherit; white-space: nowrap;
}
.vault-who.active { border-color: var(--accent); color: var(--accent); font-weight: 700; box-shadow: inset 0 0 0 1px var(--accent); }

/* ---- The people sheet ---- */
.vp-list { margin: 14px 0 4px; }
.vp-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
input.vp-name {
  flex: 1; min-width: 0; padding: 9px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--card); color: var(--text);
  font-family: inherit; font-size: 0.88rem;
}
input.vp-name:focus { outline: none; border-color: var(--accent); }
.vp-count { flex: 0 0 auto; font-size: 0.64rem; color: var(--muted); white-space: nowrap; }
.vp-del { flex: 0 0 auto; font-size: 1.1rem; line-height: 1; color: var(--muted); padding: 4px 8px; }
.vp-del:hover, .vp-del:active { color: var(--bad); }
.vp-add { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.vp-add .btn { flex: 0 0 auto; }
.vault-mode-btn {
  font-size: 0.7rem; font-weight: 600; padding: 6px 15px; cursor: pointer;
  border: 0; background: transparent; color: var(--muted); font-family: inherit;
}
.vault-mode-btn.active { background: var(--accent); color: #04222e; font-weight: 700; }
.vault-group {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--muted); margin: 13px 3px 1px;
}
.vault-list > .vault-group:first-child { margin-top: 1px; }
.vault-group-n { font-weight: 600; opacity: 0.7; letter-spacing: 0; }
.vault-eye { font-size: 0.9rem; }
/* Sized here rather than by the font, and coloured by the button so it dims
   with the rest of the row and lights up when pressed. */
.vault-copy { color: var(--muted); }
.vault-copy:hover, .vault-copy:active { color: var(--accent); }
.copy-ico { display: block; width: 14px; height: 14px; }
.edit-ico { display: block; width: 17px; height: 17px; }

/* ---- Reading one entry ---- */
.vd-head { display: flex; align-items: center; gap: 11px; margin-bottom: 4px; }
.vault-ico.vd-ico { flex: 0 0 42px; width: 42px; height: 42px; font-size: 1.3rem; }
.vd-head-text { flex: 1; min-width: 0; }
h2.vd-title { margin: 0; font-size: 1.05rem; overflow-wrap: anywhere; }
.vd-cat { font-size: 0.68rem; color: var(--muted); margin-top: 2px; }
.vd-edit { flex: 0 0 auto; color: var(--accent); padding: 7px; }

/* Label and value on one line while the value is short, because scanning six
   labelled lines is the whole point of this screen. The value wraps under its
   own label rather than pushing the buttons off the edge. */
.vd-rows { margin: 14px 0 4px; border-top: 1px solid var(--line); }
.vd-row {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 2px; border-bottom: 1px solid var(--line);
}
.vd-label {
  flex: 0 0 72px; font-size: 0.62rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--muted);
}
.vd-value { flex: 1; min-width: 0; font-size: 0.86rem; overflow-wrap: anywhere; }
.vd-acts { flex: 0 0 auto; display: flex; align-items: center; gap: 1px; align-self: center; }
.vd-acts .icon-btn { padding: 3px 5px; }
.vd-pw { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 1px; color: var(--muted); }
.vd-pw.is-open { color: var(--text); letter-spacing: 0.5px; }
a.vd-link { color: var(--accent); text-decoration: none; }
a.vd-link:hover { text-decoration: underline; }
.vd-notes-row { flex-direction: column; align-items: stretch; gap: 4px; }
.vd-notes-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.vd-notes { white-space: pre-wrap; font-size: 0.82rem; }
.vd-when { margin: 10px 2px 0; font-size: 0.66rem; }
/* History icon beside the current password (openVaultDetail) - opens the
   dedicated timeline below. Back arrow on that timeline's own header. */
.vault-history { color: var(--accent); }
.vd-back { font-size: 1.3rem; line-height: 1; padding: 2px 8px; }

/* Password history timeline (openVaultPasswordHistory) - a vertical line
   with one dot per entry, "Current" first, superseded passwords below it in
   the order they stopped being current. */
.vh-timeline { position: relative; margin: 14px 4px 4px; padding-left: 20px; }
.vh-timeline::before {
  content: ''; position: absolute; left: 4px; top: 5px; bottom: 5px; width: 2px; background: var(--line);
}
.vh-item { position: relative; padding-bottom: 20px; }
.vh-item:last-child { padding-bottom: 0; }
.vh-dot {
  position: absolute; left: -20px; top: 3px; width: 10px; height: 10px; border-radius: 50%;
  background: var(--card-2); border: 2px solid var(--muted);
}
.vh-current .vh-dot { background: var(--accent); border-color: var(--accent); }
.vh-when { font-size: 0.68rem; font-weight: 700; color: var(--muted); margin-bottom: 5px; }
.vh-current-badge {
  display: inline-block; padding: 1px 7px; border-radius: 999px; background: var(--accent);
  color: #fff; font-size: 0.62rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;
}
.vh-pw-row { display: flex; align-items: center; gap: 2px; }
.vh-pw-val { flex: 1; }
/* The accumulating boxes' own terms (Loan..Metal, see _sheetExprBreakdown in
   app.js) - a quieter second line under the total, not a second figure
   fighting the main one for attention. */
.vh-expr { font-size: 0.68rem; color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; }

/* ---- Icon picker in the form ---- */
.vault-ico-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.vault-ico-prev { flex: 0 0 40px; width: 40px; height: 40px; font-size: 1.2rem; }
.vault-ico-note { flex: 1 1 100%; margin: 0; font-size: 0.68rem; }
.vault-ico-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
  gap: 5px; margin-top: 9px;
}
.vault-ico-pick {
  height: 38px; font-size: 1.1rem; line-height: 1; cursor: pointer;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--card-2); color: var(--text);
}
.vault-ico-pick.active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
/* The way out of the palette, marked as an opening rather than a choice. */
.vault-ico-pick.is-more { font-size: 1.25rem; font-weight: 700; color: var(--muted); border-style: dashed; }
.vault-ico-custom-wrap { display: flex; flex-direction: column; gap: 3px; margin-top: 9px; }
.vault-ico-custom-wrap .hint { margin: 0; font-size: 0.66rem; }
input.vault-ico-custom {
  width: 100%; padding: 9px 12px; font-size: 1.15rem; line-height: 1.2;
  border: 1px solid var(--accent); border-radius: 10px;
  background: var(--card); color: var(--text); font-family: inherit;
}
input.vault-ico-custom:focus { outline: none; }

/* Labels inside the master-password sheet, where the inputs carry no field() */
.vault-lbl { display: block; font-size: 0.7rem; color: var(--muted); margin: 12px 2px 5px; }

.vault-pw-field { display: flex; gap: 8px; align-items: center; }
.vault-pw-field input { flex: 1; min-width: 0; }
.vault-suggest { white-space: nowrap; }
textarea.vault-notes { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--card); color: var(--text); font-family: inherit; font-size: 0.88rem; resize: vertical; }
textarea.vault-notes:focus { outline: none; border-color: var(--accent); }

/* ---------- Health Check ---------- */
.hc-avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--card-2); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; font-size: 1.3rem; flex-shrink: 0; }
/* Person badges + gear on one row. The tabs live in their own scrolling
   wrapper so a mask can fade their trailing edge without touching the gear
   button beside it - a long people list signals "more" instead of getting
   visually cut against the gear. */
.hc-toprow { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.hc-tabs-wrap { flex: 1; min-width: 0; overflow: hidden; -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%); mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%); }
.hc-gear { flex-shrink: 0; }
.hc-tabs { display: flex; gap: 8px; overflow-x: auto; padding: 2px 28px 2px 2px; scrollbar-width: none; -ms-overflow-style: none; }
.hc-tabs::-webkit-scrollbar { display: none; }
.hc-tab { padding: 9px 16px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--muted); cursor: pointer; white-space: nowrap; font-weight: 500; font-size: 0.9rem; display: inline-flex; align-items: center; gap: 6px; }
.hc-tab.active { background: var(--accent); color: #0e1726; border-color: var(--accent); font-weight: 700; }
/* Family Health isn't a person, so its badge stands apart from a selected
   person tab's own colors (background var(--accent) / text #0e1726) with a
   solid blue gradient of its own - white text for contrast - and runs the
   fill/outline relationship in reverse: full-strength at rest, softening to
   a tint once selected, so it's always visibly framed rather than blending
   into the page's own background. */
.hc-tab.hc-tab-family { background: linear-gradient(135deg, #38bdf8, #0284c7); color: #fff; border: 1.5px solid #0284c7; font-weight: 700; }
.hc-tab.hc-tab-family.active { background: linear-gradient(135deg, rgba(56, 189, 248, 0.32), rgba(14, 165, 233, 0.14)); color: var(--accent); border: 1.5px solid var(--accent); }
/* Selected person, shown below the badge row - emoji + name + age. */
.hc-selected { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; margin-bottom: 18px; position: sticky; top: 0; z-index: 15; background: var(--bg); padding: 10px 0; }
.hc-selected-info { display: flex; align-items: center; gap: 10px; min-width: 0; }
.hc-selected-name { font-size: 1.2rem; font-weight: 700; }
.hc-selected-age { font-size: 0.82rem; color: var(--muted); }
.hc-filter-btn { flex-shrink: 0; display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--muted); font-size: 0.78rem; font-weight: 600; cursor: pointer; white-space: nowrap; }
/* Dark orange gradient + white text - deliberately fixed (not var(--warn),
   which is a lighter amber tuned for text-on-dark, not a filled button) so
   "some parameters need attention" reads as a warning in both themes. */
.hc-filter-btn.active { background: linear-gradient(135deg, #f97316, #c2410c); color: #fff; border-color: #c2410c; box-shadow: 0 2px 8px rgba(194, 65, 12, 0.35); }
/* Solid, not tied to the button's own state - reads the same whether the
   button is at rest (grey) or active (the orange gradient above), rather
   than needing a second variant for each background it can sit on. */
.hc-filter-count { display: inline-flex; align-items: center; justify-content: center; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 999px; background: #c2410c; color: #fff; font-size: 0.7rem; font-weight: 800; }
/* Nothing out of range - a status label rather than a control, since
   filtering to an empty list is not something worth being able to press. */
.hc-filter-btn-clear { background: linear-gradient(135deg, #34d399, #059669); color: #fff; border-color: #059669; cursor: default; }
.hc-selected-actions { flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.hc-share-btn { flex-shrink: 0; width: 34px; height: 34px; padding: 0; border: none; background: none; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.hc-share-btn img { width: 100%; height: 100%; display: block; }
.hc-share-btn-sm { width: 22px; height: 22px; }
.hc-share-btn:active { opacity: 0.75; }
/* BMI indicator on the person's own header row (see calcBmi in health.js) -
   the middle of 3 segments (name/age, BMI, Out of Range), stacked score-on-
   top so the number reads first, coloured by band. */
.hc-bmi {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 4px 12px; border-radius: 12px; border: 1px solid var(--line); background: var(--card);
  white-space: nowrap;
}
.hc-bmi-val { font-size: 0.82rem; font-weight: 800; }
.hc-bmi-cat { font-size: 0.64rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; }
.hc-bmi-delta { font-size: 0.64rem; color: var(--muted); }
.hc-bmi-good { border-color: rgba(52,211,153,0.4); background: rgba(52,211,153,0.1); }
.hc-bmi-good .hc-bmi-cat { color: var(--good); }
.hc-bmi-low { border-color: rgba(251,191,36,0.4); background: rgba(251,191,36,0.1); }
.hc-bmi-low .hc-bmi-cat { color: #fbbf24; }
.hc-bmi-high { border-color: rgba(248,113,113,0.4); background: rgba(248,113,113,0.1); }
.hc-bmi-high .hc-bmi-cat { color: var(--bad); }
.hc-empty { padding: 48px 20px; text-align: center; color: var(--muted); }

/* Family Health: one row per parameter, one column per person, each cell a
   traffic-light dot for their latest reading (no value text - see
   renderFamilyTable) so columns stay narrow enough to fit at least 4 people
   on screen without horizontal scroll. Scrolls horizontally on its own past
   that; the parameter column stays put through that scroll since it's what
   every row's cells are read against. */
.hc-family-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; -webkit-overflow-scrolling: touch; }
.hc-family-table { table-layout: fixed; border-collapse: collapse; font-size: 0.68rem; }
.hc-family-table th, .hc-family-table td { padding: 5px 3px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-bottom: 1px solid var(--line); }
.hc-family-table th { background: var(--bg-2); font-weight: 700; color: var(--text); font-size: 0.6rem; }
.hc-family-table tr:last-child td { border-bottom: none; }
.hc-family-table th:first-child, .hc-family-table td.hc-family-param { width: 52px; text-align: left; position: sticky; left: 0; background: var(--card-2); z-index: 1; }
.hc-family-table th:not(:first-child), .hc-family-table td.hc-dot-cell { width: 58px; }
.hc-family-param { font-weight: 600; }
/* (i) info icon beside a test's name on its card - tap or hover shows the
   reference range, which used to sit on a permanent chip beside the name.
   Filled with the page's own text colour rather than a literal black, so it
   inverts to a light dot on a dark card instead of vanishing into it. */
.hc-param-info { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 12px; height: 12px; margin-left: 6px; vertical-align: 2px; border-radius: 50%; background: var(--text); color: var(--bg); font-size: 0.5rem; font-style: italic; font-weight: 700; line-height: 1; cursor: pointer; }
.hc-dot-cell { cursor: pointer; }
.hc-dot-cell:active { background: var(--bg-2); }
.hc-dot-wrap { position: relative; display: inline-flex; }
.hc-dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; }
.hc-dot-blank { background: transparent; border: 1.5px dashed var(--line); }
.hc-dot-med { position: absolute; top: -3px; right: -3px; font-size: 8px; line-height: 1; filter: drop-shadow(0 0 1px var(--bg)); }
.hc-empty-cta { margin-top: 14px; padding: 11px 22px; background: var(--good); color: #fff; border: none; border-radius: 10px; cursor: pointer; font-weight: 700; font-size: 0.95rem; }
html[data-theme="light"] .hc-empty-cta { color: #fff; }
.hc-card { background: var(--card-2); border: 1px solid var(--line); border-radius: 16px; padding: 16px; box-shadow: 0 2px 10px rgba(0,0,0,0.12); }
.hc-card + .hc-card { margin-top: 14px; }
.hc-card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.hc-card-title { font-weight: 700; font-size: 0.98rem; }
.hc-badge { display: inline-block; min-width: 26px; text-align: center; padding: 3px 9px; border-radius: 8px; font-weight: 700; font-size: 0.85rem; }

/* One reading: a calendar-chip date, the value + check-type badge, and the
   status badge. Used both for the single latest reading a param card shows
   by default and for the older readings revealed by "N more". */
.hc-entry-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; }
.hc-entry-row + .hc-entry-row { border-top: 1px solid var(--line); }
.hc-entry-row.clickable { cursor: pointer; }
.hc-cal { width: 52px; flex-shrink: 0; border-radius: 7px; overflow: hidden; text-align: center; box-shadow: 0 1px 4px rgba(0,0,0,0.18); }
.hc-cal-top { color: #fff; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.02em; padding: 4px 0; text-transform: uppercase; }
.hc-cal-year { background: var(--card); color: var(--muted); font-size: 0.6rem; padding: 2px 0; }
.hc-entry-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.hc-entry-sub { display: flex; align-items: center; gap: 6px; }
.hc-entry-value { flex-shrink: 0; text-align: right; font-weight: 700; font-size: 0.98rem; padding-right: 2px; white-space: nowrap; }
.hc-type-badge { display: inline-block; flex-shrink: 0; padding: 2px 8px; border-radius: 999px; font-size: 0.66rem; font-weight: 700; white-space: nowrap; }
.hc-lab-tag { font-size: 0.66rem; color: var(--muted); background: var(--bg-2); padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.hc-med-pill { font-size: 0.9rem; line-height: 1; }
.hc-entry-status { display: flex; flex-direction: column; align-items: center; gap: 3px; flex-shrink: 0; }
.hc-more-caption { font-size: 0.6rem; color: var(--muted); font-weight: 600; white-space: nowrap; }
.hc-trend { display: flex; align-items: flex-end; gap: 8px; padding: 6px 8px 5px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; }
.hc-trend-bars { flex: 1; min-width: 0; height: 42px; display: flex; align-items: flex-end; gap: 6px; }
.hc-trend-bar { flex: 1; max-width: 18px; border-radius: 3px 3px 0 0; min-height: 4px; }
.hc-trend-ago { flex-shrink: 0; align-self: center; font-size: 0.66rem; color: var(--muted); background: var(--card); border: 1px solid var(--line); padding: 3px 8px; border-radius: 999px; white-space: nowrap; }

/* Gear icon's action sheet */
.hc-settings-btn { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 16px; text-align: left; background: var(--card-2); border: 1px solid var(--line); border-radius: 12px; font-size: 0.98rem; font-weight: 600; color: var(--text); cursor: pointer; }
.hc-settings-btn + .hc-settings-btn { margin-top: 10px; }
.hc-settings-icon { font-size: 1.3rem; }

/* Family Members / Parameters manager modals: an Add tab (default) and a
   List tab carrying the count, so the form is what you land on but the
   existing set is one tap away rather than always taking up scroll space. */
.hc-mgr-tabs { display: flex; gap: 8px; margin-bottom: 18px; }
.hc-mgr-tab { flex: 1; padding: 10px; text-align: center; border-radius: 10px; border: 1px solid var(--line); background: var(--card); color: var(--muted); cursor: pointer; font-weight: 600; font-size: 0.92rem; }
.hc-mgr-tab.active { background: var(--accent); color: #0e1726; border-color: var(--accent); }
.hc-list-row { display: flex; align-items: center; gap: 10px; padding: 12px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; }
.hc-list-row + .hc-list-row { margin-top: 8px; }
.hc-icon-btn { width: 36px; height: 36px; flex-shrink: 0; border-radius: 9px; border: 1px solid var(--line); background: var(--card-2); color: var(--text); font-size: 1.05rem; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.hc-icon-btn.danger { color: var(--bad); }
.hc-list-empty { color: var(--muted); text-align: center; padding: 30px 10px; }

/* Me·US Holdings/Trend/Overview - $→₹ display switch (see _usCurToggle in app.js).
   iOS-style: a pill track with a round thumb that slides right and carries
   the active currency symbol - $ off/default (left), ₹ on (right). */
.us-cur-switch {
  flex: 0 0 auto; position: relative; width: 34px; height: 20px; margin: 0 8px;
  padding: 0; border-radius: 999px; border: 1px solid var(--line);
  background: var(--card-2); cursor: pointer;
}
.us-cur-switch.active { background: var(--accent); border-color: var(--accent); }
.us-cur-thumb {
  position: absolute; top: 1px; left: 1px; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; color: var(--text); font-size: 0.62rem; font-weight: 800; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.35); transition: left 0.15s ease;
}
.us-cur-switch.active .us-cur-thumb { left: 15px; color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .us-cur-thumb { transition: none; } }

/* ---------- First-run onboarding / feature picker (full page) ---------- */
.onboard {
  position: fixed; inset: 0; z-index: 9000; background: var(--bg); color: var(--text);
  display: flex; flex-direction: column;
  padding-top: var(--safe-top);
}
.onboard-scroll { flex: 1; overflow-y: auto; padding: 24px 18px 16px; max-width: 720px; width: 100%; margin: 0 auto; box-sizing: border-box; }
.onboard-welcome { display: flex; flex-direction: column; justify-content: center; text-align: center; }
.onboard-logo { width: 96px; height: 96px; border-radius: 22px; margin: 0 auto 18px; display: block; }
.onboard-h { font-size: 1.7rem; margin: 0 0 8px; line-height: 1.2; }
.onboard-sub { color: var(--muted); font-size: 1.02rem; margin: 0 0 20px; }
.onboard-points { display: flex; flex-direction: column; gap: 14px; text-align: left; margin-top: 8px; }
.onboard-point { display: flex; gap: 14px; align-items: flex-start; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; }
.onboard-point > span { font-size: 1.6rem; line-height: 1; }
.onboard-point div div { color: var(--muted); font-size: 0.9rem; margin-top: 2px; }
.onboard-tools { display: flex; gap: 16px; margin-bottom: 10px; }
.onboard-link { background: none; border: none; color: var(--accent); font-weight: 600; font-size: 0.9rem; padding: 4px 0; cursor: pointer; }
.onboard-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
@media (min-width: 640px) { .onboard-grid { grid-template-columns: repeat(3, 1fr); } }
.onboard-opt {
  position: relative; text-align: left; background: var(--card); color: var(--text);
  border: 2px solid var(--line); border-radius: var(--radius); padding: 14px 12px 12px;
  display: flex; flex-direction: column; gap: 4px; cursor: pointer; min-height: 118px;
}
.onboard-opt.on { border-color: var(--accent); background: var(--card-2); }
.onboard-opt-ico { font-size: 1.7rem; line-height: 1; }
/* An image icon matches the emoji next to it: 1em square, same baseline. */
.mod-ico-img { width: 1em; height: 1em; display: block; object-fit: contain; }
.onboard-opt-name { font-weight: 700; font-size: 0.98rem; }
.onboard-opt-desc { color: var(--muted); font-size: 0.78rem; line-height: 1.3; }
.onboard-opt-tick {
  position: absolute; top: 8px; right: 8px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #06243a; font-size: 0.8rem; font-weight: 800;
  display: none; align-items: center; justify-content: center;
}
.onboard-opt.on .onboard-opt-tick { display: flex; }
.onboard-bar {
  display: flex; align-items: center; gap: 10px; padding: 12px 18px calc(12px + var(--safe-bottom));
  background: var(--bg-2); border-top: 1px solid var(--line);
  max-width: none; box-sizing: border-box;
}
.onboard-bar .btn { max-width: 320px; }
.onboard-bar .btn.primary { margin-left: auto; }
.onboard-count { color: var(--muted); font-size: 0.9rem; white-space: nowrap; }
.onboard-bar .btn.primary:only-child { margin: 0 auto; max-width: 420px; }
.onboard-bar .btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---------- Update available popup ---------- */
.update-pop {
  position: fixed; left: 12px; right: 12px; bottom: calc(16px + var(--safe-bottom)); z-index: 9500;
  max-width: 480px; margin: 0 auto; padding: 14px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border-radius: 18px; color: #fff;
  background: linear-gradient(135deg, #ff7a00 0%, #ff2e63 52%, #7b2ff7 100%);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.18) inset;
  animation: update-pop-in 0.35s ease-out;
}
@keyframes update-pop-in { from { transform: translateY(30px); opacity: 0; } to { transform: none; opacity: 1; } }
.update-pop-ico { font-size: 1.9rem; line-height: 1; }
.update-pop-body { flex: 1; min-width: 150px; }
.update-pop-title { font-weight: 800; font-size: 1rem; }
.update-pop-sub { font-size: 0.82rem; opacity: 0.92; margin-top: 2px; }
.update-pop-actions { display: flex; gap: 8px; margin-left: auto; }
.update-pop-btn { border: none; border-radius: 10px; padding: 9px 16px; font-weight: 700; font-size: 0.9rem; cursor: pointer; }
.update-pop-btn.go { background: #fff; color: #b3123f; }
.update-pop-btn.later { background: rgba(255, 255, 255, 0.2); color: #fff; }
@media (prefers-reduced-motion: reduce) { .update-pop { animation: none; } }

/* ---------- Onboarding: backup step ---------- */
.onboard-shield { font-size: 72px; line-height: 1; text-align: center; margin-bottom: 10px; animation: onboard-pulse 2.4s ease-in-out infinite; }
@keyframes onboard-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }
.onboard-risk-label { text-align: left; color: var(--muted); font-size: 0.82rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; margin: 16px 0 8px; }
.onboard-risks { display: flex; flex-direction: column; gap: 8px; }
.onboard-risk {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; column-gap: 12px; text-align: left;
  background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; cursor: pointer; width: 100%;
}
.onboard-risk-ico { font-size: 1.5rem; }
.onboard-risk-t { font-weight: 700; }
.onboard-risk-more { color: var(--accent); font-size: 1.3rem; font-weight: 700; transition: transform 0.2s; }
.onboard-risk-d { grid-column: 1 / -1; max-height: 0; overflow: hidden; opacity: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.4; transition: max-height 0.25s, opacity 0.25s, margin 0.25s; }
.onboard-risk.open { border-color: var(--warn); }
.onboard-risk.open .onboard-risk-d { max-height: 90px; opacity: 1; margin-top: 8px; }
.onboard-risk.open .onboard-risk-more { transform: rotate(45deg); }
.onboard-steps { display: flex; flex-direction: column; gap: 8px; text-align: left; }
.onboard-step { display: flex; gap: 12px; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; font-size: 0.92rem; }
.onboard-step-n { flex: 0 0 26px; height: 26px; border-radius: 50%; background: var(--accent); color: #06243a; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.onboard-warn { margin-top: 14px; text-align: left; border: 1px solid var(--warn); border-radius: var(--radius); padding: 12px 14px; background: rgba(251, 191, 36, 0.1); }
.onboard-warn > div { color: var(--muted); font-size: 0.88rem; margin: 4px 0 10px; }
.onboard-warn .onboard-warn-btns { display: flex; gap: 8px; margin: 0; }
.onboard-done-tick { width: 84px; height: 84px; margin: 0 auto 18px; border-radius: 50%; background: var(--good); color: #fff; font-size: 3rem; font-weight: 800; display: flex; align-items: center; justify-content: center; animation: onboard-pop 0.4s ease-out; }
@keyframes onboard-pop { from { transform: scale(0.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .onboard-shield, .onboard-done-tick { animation: none; } }

/* ---------- In-app confirm / alert dialog ---------- */
.app-dialog-back {
  position: fixed; inset: 0; z-index: 9800; background: rgba(4, 8, 18, 0.66);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  animation: app-dialog-fade 0.15s ease-out;
}
.app-dialog {
  width: 100%; max-width: 380px; background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-radius: 18px; padding: 20px 18px 16px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
}
.app-dialog-msg { white-space: pre-line; line-height: 1.45; font-size: 0.98rem; margin-bottom: 18px; overflow-wrap: anywhere; }
.app-dialog-btns { display: flex; gap: 10px; justify-content: flex-end; }
.app-dialog-btns .btn { flex: 1; max-width: 200px; }
.btn.danger-fill { background: var(--bad); color: #fff; }
@keyframes app-dialog-fade { from { opacity: 0; } to { opacity: 1; } }

.onboard-opt-need { display: none; color: var(--muted); opacity: 0.75; font-size: 0.72rem; font-weight: 500; font-style: italic; margin-top: 2px; }
.onboard-opt.locked { opacity: 0.5; cursor: not-allowed; border-style: dashed; }
.onboard-opt.locked .onboard-opt-need { display: block; }

/* Home has no bottom nav, so no space is reserved for one (the reserve made the page scroll even when it fit). */
body[data-mode="home"] { padding-bottom: 0; }

/* ---------- Feature picker: membership banner ---------- */
.onboard-pro {
  margin: 4px 0 16px; padding: 14px 16px; border-radius: 16px; color: #fff; text-align: left;
  background: linear-gradient(135deg, #f59e0b 0%, #ef4444 55%, #8b5cf6 100%);
  box-shadow: 0 8px 22px rgba(239, 68, 68, 0.25);
}
.onboard-pro-badge { display: inline-block; font-size: 0.7rem; font-weight: 800; letter-spacing: 0.08em; background: rgba(255, 255, 255, 0.22); padding: 3px 9px; border-radius: 999px; }
.onboard-pro-title { font-size: 1.15rem; font-weight: 800; margin: 8px 0 4px; }
.onboard-pro-text { font-size: 0.88rem; line-height: 1.4; opacity: 0.95; }
.onboard-pro-btn { margin-top: 12px; width: 100%; border: none; border-radius: 10px; padding: 11px; font-weight: 800; font-size: 0.95rem; background: #fff; color: #b3123f; cursor: pointer; }

/* ---------- Home: end-of-page backup caution ---------- */
/* Soft tinted panel, no border: reads as a gentle reminder, not an alert box. */
.home-caution { margin: 22px 0 6px; padding: 0; border-radius: 18px; background: rgba(52, 211, 153, 0.08); }
.home-caution.is-overdue { background: rgba(251, 191, 36, 0.1); }
.home-caution-head { display: flex; align-items: center; gap: 12px; width: 100%; padding: 11px 14px; background: none; border: none; color: inherit; text-align: left; cursor: pointer; font: inherit; }
.home-caution-ico { flex: 0 0 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1rem; line-height: 1; background: rgba(52, 211, 153, 0.18); }
.home-caution.is-overdue .home-caution-ico { background: rgba(251, 191, 36, 0.22); }
.home-caution-title { flex: 1; font-weight: 600; font-size: 0.9rem; }
.home-caution-chev { font-size: 1.3rem; line-height: 1; color: var(--muted); transition: transform 0.2s; }
.home-caution.open .home-caution-chev { transform: rotate(90deg); }
.home-caution-body { display: none; padding: 0 14px 14px 58px; }
.home-caution.open .home-caution-body { display: block; }
.home-caution-text { margin: 0 0 12px; color: var(--muted); font-size: 0.82rem; line-height: 1.55; }
.home-caution-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.home-caution-status { font-size: 0.76rem; font-weight: 600; padding: 4px 10px; border-radius: 999px; color: var(--good); background: rgba(52, 211, 153, 0.14); }
.home-caution.is-overdue .home-caution-status { color: var(--warn); background: rgba(251, 191, 36, 0.16); }
.home-caution-btn { background: rgba(56, 189, 248, 0.16); color: var(--accent); }
body[data-mode="home"] #homeView.has-fabs { padding-bottom: calc(92px + var(--safe-bottom)); }

/* ---------- Behave like an app, not a web page ----------
   Long-pressing or dragging on labels used to select text and pop up the
   browser's copy / "web search" bar. Selection stays on for anything you type
   into. */
html, body {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
input, textarea, select, [contenteditable="true"], .allow-select, .allow-select * {
  -webkit-user-select: text; user-select: text;
}

/* ---------- Website landing page (not installed) ---------- */
.landing { position: fixed; inset: 0; z-index: 9900; background: var(--bg); color: var(--text); display: flex; flex-direction: column; }
.landing-scroll { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 0 18px 0; scroll-snap-type: y mandatory; overscroll-behavior-y: contain; }
.landing-scroll > * { max-width: 720px; margin-left: auto; margin-right: auto; }

/* hero */
/* Every section fills the visible screen and centres its content, with air above and below. */
.landing-hero { text-align: center; min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: calc(32px + var(--safe-top)) 0 32px; scroll-snap-align: start; scroll-snap-stop: always; }
.lp-kicker { display: inline-block; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.03em; padding: 6px 13px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); color: var(--muted); }
.landing-hero h1 { font-size: 2.1rem; line-height: 1.18; margin: 16px 0 10px; }
.lp-grad { background: linear-gradient(100deg, #f59e0b, #ef4444 45%, #8b5cf6); -webkit-background-clip: text; background-clip: text; color: transparent; }
.landing-lead { color: var(--muted); line-height: 1.55; margin: 0 auto 20px; max-width: 520px; }
.landing-btn { border: none; border-radius: 12px; padding: 14px 24px; font-weight: 800; font-size: 1rem; cursor: pointer; }
.landing-btn.primary { background: var(--accent); color: #06243a; box-shadow: 0 8px 20px rgba(56, 189, 248, 0.22); }
.landing-btn.ghost { background: transparent; color: var(--muted); font-weight: 700; padding: 10px 14px; }
.landing-btn-wide { display: block; width: 100%; max-width: 340px; margin: 16px auto 0; }
.landing-note { margin: 12px auto 0; color: var(--good); font-weight: 700; }
.landing-badges { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 20px; }
.landing-badges span { font-size: 0.76rem; padding: 6px 12px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); color: var(--muted); }

/* sections */
.landing-sec { min-height: 100%; display: flex; flex-direction: column; justify-content: center; padding: 40px 0; scroll-snap-align: start; scroll-snap-stop: always; }
.landing-sec h2 { font-size: 1.4rem; margin: 0 0 8px; text-align: center; }
.landing-sec .landing-sub { text-align: center; }
.landing-sec p { color: var(--muted); line-height: 1.6; margin: 0 0 14px; }
.lp-reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.5s ease-out, transform 0.5s ease-out; }
.lp-reveal.in { opacity: 1; transform: none; }

/* demo phone */
.lp-tabs { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 12px; }
.lp-tabs::-webkit-scrollbar { display: none; }
.lp-tab { flex: 0 0 auto; border: 1px solid var(--line); background: var(--card); color: var(--muted); border-radius: 999px; padding: 8px 15px; font-size: 0.84rem; font-weight: 700; cursor: pointer; }
.lp-tab.on { background: var(--accent); border-color: var(--accent); color: #06243a; }
.lp-phone { max-width: 330px; margin: 0 auto; border: 1px solid var(--line); border-radius: 26px; background: var(--bg-2); padding: 8px; box-shadow: 0 18px 44px rgba(0, 0, 0, 0.42); }
.lp-phone-bar { display: flex; justify-content: center; padding: 4px 0 8px; }
.lp-notch { width: 74px; height: 5px; border-radius: 999px; background: var(--line); }
.lp-phone-head { display: flex; align-items: center; gap: 9px; padding: 0 10px 10px; }
.lp-phone-logo { width: 26px; height: 26px; border-radius: 7px; }
.lp-phone-title { font-weight: 800; flex: 1; }
.lp-phone-dots { color: var(--muted); }
.lp-screen { height: 330px; overflow: hidden; padding: 4px 10px 10px; display: flex; flex-direction: column; gap: 9px; }
.lp-screen.is-in { animation: lp-fade 0.4s ease-out; }
.lp-screen.is-in.dir-next { animation: lp-next 0.35s ease-out; }
.lp-screen.is-in.dir-prev { animation: lp-prev 0.35s ease-out; }
@keyframes lp-next { from { opacity: 0; transform: translateX(36px); } to { opacity: 1; transform: none; } }
@keyframes lp-prev { from { opacity: 0; transform: translateX(-36px); } to { opacity: 1; transform: none; } }
.lp-phone { touch-action: pan-y; cursor: grab; -webkit-user-select: none; user-select: none; }
.lp-dots { display: flex; justify-content: center; gap: 8px; margin-top: 16px; }
.lp-dot-nav { width: 8px; height: 8px; border-radius: 999px; background: var(--line); cursor: pointer; transition: width 0.2s, background 0.2s; }
.lp-dot-nav.on { width: 22px; background: var(--accent); }
.lp-swipe-hint { text-align: center; color: var(--muted); font-size: 0.74rem; margin-top: 8px; opacity: 0.8; }
@keyframes lp-fade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.lp-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.lp-stat { background: var(--card); border-radius: 13px; padding: 11px; display: flex; flex-direction: column; gap: 5px; }
.lp-stat-l { color: var(--muted); font-size: 0.68rem; }
.lp-stat-v { font-weight: 800; font-size: 0.98rem; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lp-pill { font-size: 0.62rem; font-weight: 800; padding: 2px 7px; border-radius: 999px; }
.lp-pill.good { background: rgba(52, 211, 153, 0.18); color: var(--good); }
.lp-pill.bad { background: rgba(248, 113, 113, 0.18); color: var(--bad); }
.lp-due { display: flex; align-items: center; gap: 9px; padding: 9px 11px; border-radius: 12px; background: rgba(52, 211, 153, 0.1); }
.lp-due-badge { font-size: 0.64rem; font-weight: 800; color: var(--good); white-space: nowrap; }
.lp-due-text { font-size: 0.72rem; }
.lp-card { display: flex; align-items: center; gap: 11px; padding: 11px; border-radius: 13px; background: var(--card); }
.lp-card-ico { font-size: 1.3rem; }
.lp-card-t { display: block; font-weight: 700; font-size: 0.85rem; }
.lp-card-s { display: block; color: var(--muted); font-size: 0.68rem; margin-top: 2px; }
.lp-card-arrow { margin-left: auto; color: var(--muted); }
.lp-list { background: var(--card); border-radius: 13px; padding: 4px 12px; }
.lp-row { display: flex; justify-content: space-between; gap: 10px; padding: 9px 0; font-size: 0.78rem; border-bottom: 1px solid var(--line); }
.lp-row:last-child { border-bottom: none; }
.lp-row-l { color: var(--muted); }
.lp-row-r { font-weight: 700; }
.lp-row-r.good { color: var(--good); }
.lp-row-r.bad { color: var(--bad); }
.lp-budget { background: var(--card); border-radius: 13px; padding: 12px; }
.lp-budget-top { display: flex; justify-content: space-between; font-size: 0.78rem; color: var(--muted); }
.lp-budget-top b { color: var(--text); font-size: 0.95rem; }
.lp-bar { height: 7px; border-radius: 999px; background: var(--card-2); margin: 9px 0 7px; overflow: hidden; }
.lp-bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--good), var(--accent)); }
.lp-budget-foot { font-size: 0.68rem; color: var(--muted); }
.lp-person { display: flex; align-items: center; gap: 11px; background: var(--card); border-radius: 13px; padding: 11px; }
.lp-avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--card-2); display: flex; align-items: center; justify-content: center; font-size: 1.1rem; }

/* try-it picker */
.lp-pick-count { display: flex; align-items: center; gap: 6px; margin-bottom: 12px; }
.lp-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); transition: background 0.2s, transform 0.2s; }
.lp-dot.on { background: var(--accent); transform: scale(1.25); }
.lp-pick-n { margin-left: 6px; font-size: 0.78rem; color: var(--muted); font-weight: 700; }
.lp-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
@media (min-width: 560px) { .lp-tiles { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 760px) { .lp-tiles { grid-template-columns: repeat(5, 1fr); } }
.lp-tile { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; text-align: center; min-height: 92px; padding: 12px 6px; background: var(--card); color: var(--text); border: 2px solid var(--line); border-radius: 16px; cursor: pointer; transition: transform 0.15s, border-color 0.15s, background 0.15s; }
.lp-tile:active { transform: scale(0.96); }
.lp-tile.on { border-color: var(--accent); background: var(--card-2); }
.lp-tile-ico { font-size: 1.8rem; line-height: 1; }
.lp-tile-name { font-weight: 700; font-size: 0.75rem; line-height: 1.25; }
.lp-tile-tick { position: absolute; top: 6px; right: 6px; width: 20px; height: 20px; border-radius: 50%; background: var(--accent); color: #06243a; font-size: 0.72rem; font-weight: 800; display: none; align-items: center; justify-content: center; }
.lp-tile.on .lp-tile-tick { display: flex; }
.lp-pick-msg { margin: 14px 0 0; font-size: 0.86rem; color: var(--muted); min-height: 20px; }
.lp-pick-msg.is-full { color: var(--good); font-weight: 700; }

/* steps */
.lp-steps { display: grid; gap: 10px; }
.lp-step { display: flex; gap: 14px; align-items: flex-start; background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 14px; }
.lp-step-n { flex: 0 0 28px; height: 28px; border-radius: 50%; background: var(--accent); color: #06243a; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.lp-step div div { color: var(--muted); font-size: 0.86rem; margin-top: 3px; line-height: 1.45; }

/* points */
.landing-points { display: grid; gap: 10px; }
.landing-point { display: flex; gap: 14px; align-items: flex-start; background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 14px; }
.landing-point-ico { font-size: 1.5rem; line-height: 1; }
.landing-point div div { color: var(--muted); font-size: 0.88rem; margin-top: 3px; line-height: 1.45; }

/* faq */
.lp-faq { display: grid; gap: 8px; }
.lp-faq-item { background: var(--card); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.lp-faq-q { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; padding: 14px; background: none; border: none; color: inherit; font: inherit; font-weight: 700; text-align: left; cursor: pointer; }
.lp-faq-plus { color: var(--accent); font-size: 1.25rem; font-weight: 800; transition: transform 0.2s; }
.lp-faq-item.open .lp-faq-plus { transform: rotate(45deg); }
.lp-faq-a { display: none; padding: 0 14px 14px; color: var(--muted); font-size: 0.88rem; line-height: 1.55; }
.lp-faq-item.open .lp-faq-a { display: block; }

/* install guides */
.landing-guides { display: grid; gap: 10px; margin-top: 16px; text-align: left; }
.landing-guide { background: var(--card); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.landing-guide.is-yours { border-color: var(--accent); }
.landing-guide-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%; padding: 13px 15px; background: none; border: none; color: inherit; font: inherit; font-weight: 800; text-align: left; cursor: pointer; }
.landing-yours { font-size: 0.68rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; background: var(--accent); color: #06243a; }
.landing-guide ol { display: none; margin: 0; padding: 0 16px 14px 34px; color: var(--muted); line-height: 1.7; font-size: 0.9rem; }
.landing-guide.open ol { display: block; }
.landing-fine { font-size: 0.8rem; margin-top: 14px; }
.landing-install-logo { display: block; width: 88px; height: 88px; border-radius: 20px; margin: 0 auto 14px; box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4); }
.landing-foot { text-align: center; color: var(--muted); font-size: 0.78rem; padding: 24px 0 28px; scroll-snap-align: end; }

/* sticky bar */
.landing-bar { display: flex; align-items: center; gap: 12px; padding: 10px 18px calc(10px + var(--safe-bottom)); background: var(--bg-2); border-top: 1px solid var(--line); }
.landing-bar-text { flex: 1; min-width: 0; line-height: 1.3; }
.landing-bar-text b { display: block; font-size: 0.86rem; }
.landing-bar-text span { display: block; color: var(--muted); font-size: 0.72rem; }
.landing-bar .landing-btn { flex: 0 0 auto; padding: 12px 20px; }
@media (prefers-reduced-motion: reduce) {
  .lp-reveal { opacity: 1; transform: none; transition: none; }
  .lp-screen.is-in, .lp-screen.is-in.dir-next, .lp-screen.is-in.dir-prev { animation: none; }
}

/* Backup tip: keep a second copy off the phone */
.backup-tip { margin: 0 0 12px; padding: 10px 12px; border-radius: 12px; background: rgba(56, 189, 248, 0.1); color: var(--muted); font-size: 0.8rem; line-height: 1.5; text-align: left; }

/* SGB tab: the rule that puts a stock on this page */
.sgb-rule { display: flex; gap: 12px; align-items: flex-start; margin: 2px 0 12px; padding: 12px 14px; border-radius: 14px; background: rgba(251, 191, 36, 0.09); }
.sgb-rule-ico { font-size: 1.3rem; line-height: 1.2; }
.sgb-rule b { font-size: 0.9rem; }
.sgb-rule div div { color: var(--muted); font-size: 0.82rem; line-height: 1.5; margin-top: 3px; }
.sgb-rule .sgb-rule-eg { font-style: italic; opacity: 0.85; }

/* Emergency Fund > Targets: the ladder explainer and the last-achieved note share a line */
.ef-ladder-foot { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px 12px; margin-top: 10px; padding-top: 6px; border-top: 1px dashed var(--line); font-size: 0.66rem; }
.ef-ladder-foot .explain-row { width: auto; margin: 0; padding: 0; border: none; }
.ef-ladder-last { color: var(--muted); font-size: 0.66rem; white-space: nowrap; }

/* Stock-only sections can never show on another screen, whatever JS timing does.
   (The "Prices updated Nd ago" line used to leak onto unrelated pages.) */
body:not([data-mode="stocks"]) :is(#summary, #price-status, #toolbar, #stockList, #monthlyView, #heatmapView, #trendView, #feedView, #portfolioTabs, #bottomNav, #addBtn, #ocrBtn) { display: none !important; }

/* (i) beside a label: tap for a plain-language meaning */
.help-dot { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; margin-left: 6px; padding: 0; border-radius: 50%; border: 1px solid var(--line); background: var(--card-2); color: var(--muted); font: italic 700 0.62rem Georgia, serif; vertical-align: middle; cursor: pointer; }
.help-dot:active { color: var(--text); }

/* Advanced fields behind "More options" */
.more-opts { margin: 10px 0 4px; border-top: 1px dashed var(--line); padding-top: 8px; }
.more-opts > summary { cursor: pointer; color: var(--accent); font-weight: 700; font-size: 0.86rem; padding: 4px 0 8px; list-style: none; }
.more-opts > summary::-webkit-details-marker { display: none; }
.more-opts > summary::before { content: '▸  '; }
.more-opts[open] > summary::before { content: '▾  '; }

.empty-cta { margin-top: 12px; min-width: 200px; flex: none; }

/* Home: Get started checklist */
.home-start { margin: 14px 0 6px; padding: 12px 14px 8px; border-radius: 18px; background: linear-gradient(135deg, rgba(245, 158, 11, 0.12), rgba(139, 92, 246, 0.12)); }
.home-start-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.home-start-title { font-weight: 800; font-size: 0.95rem; }
.home-start-count { font-size: 0.72rem; color: var(--muted); font-weight: 700; }
.home-start-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 0; background: none; border: none; border-top: 1px solid var(--line); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.home-start-row:first-of-type { border-top: none; }
.home-start-box { flex: 0 0 20px; height: 20px; border-radius: 50%; border: 2px solid var(--accent); }
.home-start-label { flex: 1; font-size: 0.9rem; font-weight: 600; }
.home-start-go { color: var(--muted); font-size: 1.2rem; }
.home-start-more { font-size: 0.72rem; color: var(--muted); padding: 2px 0 6px 32px; }

.onboard-bar-legal { flex-direction: column; align-items: stretch; gap: 8px; padding-top: 10px; }
.onboard-bar-legal .btn, .onboard-bar-legal .btn.primary { width: 100%; max-width: none; margin-left: 0; }
.legal-consent { margin: 0; font-size: 0.72rem; line-height: 1.35; color: var(--muted); text-align: center; }
.legal-consent a { color: var(--accent, #f97316); text-decoration: underline; }
.legal-sheet { max-height: 85vh; overflow-y: auto; }
.legal-sheet h3 { margin: 16px 0 4px; font-size: 1rem; }
.legal-sheet ul { margin: 4px 0; padding-left: 18px; } .legal-sheet li { margin: 4px 0; font-size: 0.9rem; }
.legal-acts { margin-top: 16px; }
.legal-date { color: var(--muted); font-size: 0.8rem; margin: 0; }
.landing-foot a { color: inherit; text-decoration: underline; }

.onboard-name-wrap { display: flex; flex-direction: column; gap: 6px; text-align: left; margin: 14px 0 6px; font-size: 0.9rem; color: var(--muted); }
.onboard-name { padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--bg-2); color: inherit; font-size: 1rem; }
.home-tag-name { background: none; border: 0; padding: 0; font: inherit; text-align: left; cursor: pointer; }
.onboard-field-note { color: var(--muted); font-size: 0.72rem; }
.onboard-demo { margin: 14px 0 6px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 14px; background: var(--bg-2); text-align: left; }
.onboard-demo-h { font-size: 0.86rem; }
.onboard-demo-sub { margin: 4px 0 10px; color: var(--muted); font-size: 0.74rem; line-height: 1.4; }
.onboard-demo-row { display: flex; gap: 10px; }
.onboard-demo-row label { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 5px; font-size: 0.74rem; color: var(--muted); }
.onboard-demo-row select { width: 100%; padding: 10px 6px 10px 9px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); color: inherit; font-size: 0.84rem; }

.onboard-about-ico { font-size: 3rem; margin-top: 24px; }
.onboard-demo-page { margin-top: 18px; }
.onboard-about-skip { text-align: center; margin-top: 14px; }
.usage-share-row { display: flex; align-items: center; gap: 10px; margin: 12px 0; font-size: 0.95rem; }
.usage-share-row input { width: 20px; height: 20px; }

.legal-stop { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); }

body.locked .modal-host { z-index: 9100; }
.legal-sheet { padding-top: 14px; }
.legal-sheet h2 { margin-bottom: 4px; }
.legal-sheet h3 { margin: 12px 0 2px; font-size: 0.95rem; }
.legal-sheet li { margin: 3px 0; font-size: 0.86rem; line-height: 1.4; }
.legal-sheet ul { margin: 2px 0; padding-left: 16px; }

.pro-badge-btn {
  flex: 0 0 auto;
  width: 28px; height: 28px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--warn);
  background: color-mix(in srgb, var(--warn) 16%, transparent);
  cursor: pointer;
}
.pro-badge-btn img { width: 20px; height: 20px; display: block; pointer-events: none; }
.pro-badge-btn:active { background: color-mix(in srgb, var(--warn) 32%, transparent); }
.pro-title-star { width: 1.15em; height: 1.15em; vertical-align: -0.2em; margin-right: 6px; }
.pro-sheet h3 { margin: 14px 0 2px; font-size: 0.95rem; }
.pro-badge { display: inline-block; margin: 0 0 8px; padding: 3px 9px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); color: var(--muted); font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em; }
.pro-list { margin: 6px 0; padding-left: 18px; }
.pro-list li { margin: 4px 0; font-size: 0.9rem; line-height: 1.4; }

.usage-json { margin: 8px 0; padding: 10px 12px; background: var(--bg); border: 1px solid var(--line); border-radius: 10px; font-size: 0.78rem; line-height: 1.45; overflow-x: auto; white-space: pre; }

.pro-pill { display: inline-flex; align-items: center; gap: 4px; margin-left: 9px; padding: 2px 9px 2px 6px; vertical-align: middle;
  border-radius: 999px; border: 1px solid var(--warn); background: color-mix(in srgb, var(--warn) 20%, transparent);
  color: var(--warn); font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em; line-height: 1.4; }
.pro-pill-star { width: 15px; height: 15px; display: block; }
body[data-plan="paid"] .pro-badge-btn { background: color-mix(in srgb, var(--warn) 42%, transparent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--warn) 30%, transparent); }
.pro-badge.is-member { border-color: var(--warn); color: var(--warn); }

.onboard-groups { display: flex; flex-direction: column; gap: 18px; }
.onboard-cat-h { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 0.98rem; font-weight: 800; letter-spacing: 0.01em; color: var(--text); }
.onboard-cat-ico { font-size: 1.1rem; line-height: 1; }
.onboard-kakeibo { border-color: color-mix(in srgb, var(--accent) 50%, var(--line)); background: color-mix(in srgb, var(--accent) 7%, var(--card)); }
.onboard-kakeibo b { display: block; margin-bottom: 3px; }

.onboard-demo .onboard-name-wrap { margin: 0 0 14px; }

/* Welcome screen: every card is icon tile + title + text, so the rows align; safe centring stops the top clipping on short screens */
.onboard-welcome { justify-content: safe center; }
.onboard-welcome .onboard-logo { width: 84px; height: 84px; border-radius: 20px; margin-bottom: 14px; }
.onboard-welcome .onboard-h { font-size: 1.55rem; margin-bottom: 4px; }
.onboard-welcome .onboard-sub { margin: 0 auto 4px; max-width: 320px; font-size: 0.98rem; line-height: 1.4; }
.onboard-welcome .onboard-points { gap: 10px; margin-top: 20px; }
.onboard-point { align-items: center; padding: 12px 14px; border-radius: 14px; }
.onboard-point > .onboard-point-ico { flex: 0 0 44px; width: 44px; height: 44px; display: grid; place-items: center; font-size: 1.45rem; border-radius: 12px; background: color-mix(in srgb, var(--accent) 12%, transparent); }
.onboard-point-body { min-width: 0; }
.onboard-point-body b { display: block; font-size: 0.97rem; line-height: 1.3; }
.onboard-point-body p { margin: 3px 0 0; color: var(--muted); font-size: 0.85rem; line-height: 1.45; }
.onboard-kakeibo .onboard-point-body b { color: var(--accent); }
.onboard-kakeibo .onboard-point-body p { color: var(--text); opacity: 0.88; }

.onboard-bar-note { flex-wrap: wrap; row-gap: 8px; }
.onboard-bar-hint { flex: 1 1 100%; margin: 0; text-align: center; font-size: 0.78rem; line-height: 1.35; color: var(--muted); }
.onboard-h + .onboard-pro { margin-top: 14px; }

.onboard-pro + .onboard-groups { margin-top: 18px; }

.bottom-nav button.is-locked { opacity: 0.55; }
#ccBottomNav button { font-size: 0.72rem; }
.cc-cardchips { flex-wrap: wrap; padding: 4px 0 8px; gap: 6px; }
.cc-locked { padding-top: 48px; }

/* Get started as sliding cards, one step at a time */
.home-start { padding: 12px 0 10px 14px; }
.home-start-head { padding-right: 14px; }
.home-start-track { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; padding: 6px 14px 4px 0; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.home-start-track::-webkit-scrollbar { display: none; }
.home-start-card { flex: 0 0 84%; scroll-snap-align: start; display: flex; align-items: center; gap: 12px; padding: 14px; border-radius: 16px; border: 1px solid var(--line); background: var(--card); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.home-start-card:only-child { flex-basis: 100%; }
.home-start-ico { flex: 0 0 46px; height: 46px; display: grid; place-items: center; font-size: 1.5rem; border-radius: 13px; background: color-mix(in srgb, var(--accent) 14%, transparent); }
.home-start-ico .mod-ico-img { width: 28px; height: 28px; }
.home-start-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.home-start-step { font-size: 0.68rem; font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: 0.04em; }
.home-start-card .home-start-label { font-size: 0.98rem; font-weight: 700; }
.home-start-hint { font-size: 0.78rem; color: var(--muted); line-height: 1.35; }
.home-start-dots { display: flex; justify-content: center; gap: 6px; padding: 8px 14px 0 0; }
.home-start-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line); transition: width 0.2s, background 0.2s; }
.home-start-dot.on { width: 16px; background: var(--accent); }

/* The three-dot menu is Home-only; every other screen shows its Pro star in that slot, breathing slowly */
body:not([data-mode="home"]) #menuBtn { display: none; }
#proBtn { grid-column: 3; justify-self: center; }
.pro-badge-btn, body[data-plan="paid"] .pro-badge-btn { width: 40px; height: 40px; border: none; background: transparent; box-shadow: none; border-radius: 10px; }
.pro-badge-btn:active { background: var(--card); }
.pro-badge-btn img { width: 26px; height: 26px; animation: pro-beat 2.8s ease-in-out infinite; }
@keyframes pro-beat { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.22); } }
@media (prefers-reduced-motion: reduce) { .pro-badge-btn img { animation: none; } }

.alloc-shared-toggle { display: flex; align-items: center; gap: 10px; padding: 10px 4px 4px; font-size: 0.9rem; cursor: pointer; }
.alloc-shared-toggle input { width: 20px; height: 20px; }
.alloc-shared-sub { margin-top: 6px; margin-left: 14px; }

.home-title-ico.is-pro { border-radius: 22%; }

/* Pro popup: what Pro gives on this screen stands out; upcoming ideas sit at the bottom, quiet */
.pro-now { list-style: none; padding: 10px 12px; margin: 6px 0; border-radius: 12px; background: color-mix(in srgb, var(--warn) 14%, transparent); border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); }
.pro-now li { font-weight: 700; font-size: 0.95rem; margin: 3px 0; }
.pro-now li::before { content: '\2713  '; color: var(--warn); }
.pro-free-line { margin: 4px 2px 0; font-size: 0.82rem; color: var(--muted); }
.pro-soon-head { margin: 16px 0 2px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); opacity: 0.8; }
.pro-soon { margin: 0 0 8px; padding-left: 18px; font-size: 0.8rem; color: var(--muted); opacity: 0.85; }
.pro-soon li { margin: 2px 0; }

/* Pro badge: beside the title (not under it), on a warm gradient so it stands out */
.home-title.has-pro { display: flex; align-items: center; flex-wrap: nowrap; white-space: nowrap; font-size: clamp(1.6rem, 7vw, 2.4rem); }
.home-title.has-pro .pro-pill { margin-left: 7px; padding: 2px 8px 2px 5px; gap: 3px; font-size: 0.66rem; color: #fff; border: none; text-shadow: 0 1px 2px rgba(0,0,0,0.35);
  background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 45%, #ea580c 100%); box-shadow: 0 2px 8px rgba(234,88,12,0.45), inset 0 1px 0 rgba(255,255,255,0.35); }
.home-title.has-pro .pro-pill-star { width: 13px; height: 13px; filter: drop-shadow(0 0 2px rgba(255,255,255,0.7)); }

/* Pro yearly plan setup */
.ps-scroll { padding-bottom: 24px; }
.ps-stepno { margin: 4px 0 0; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); }
.ps-h { margin: 4px 0 14px; font-size: 1.5rem; }
.ps-foot { text-align: center; margin-top: 14px; }
.ps-field { margin: 0 0 16px; }
.ps-field-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.ps-field-head label { font-weight: 700; font-size: 0.95rem; }
.ps-input-wrap { position: relative; }
.ps-input-wrap input { width: 100%; box-sizing: border-box; padding: 14px 40px 14px 14px; font-size: 1.15rem; border-radius: 12px; border: 1px solid var(--line); background: var(--card); color: var(--text); }
.ps-cur { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.ps-hint { margin: 6px 2px 0; }
.ps-check { display: flex; align-items: center; gap: 10px; margin: 6px 0 4px; font-size: 0.92rem; cursor: pointer; }
.ps-check input { width: 20px; height: 20px; }
.ps-block-note { min-height: 1.2em; margin: 8px 2px; font-size: 0.85rem; color: var(--warn); }
.ps-bar { flex-direction: column; align-items: stretch; gap: 10px; }
.ps-buttons { display: flex; gap: 10px; justify-content: flex-end; }
.ps-buttons .btn { min-width: 110px; }
.ps-balance { display: flex; align-items: baseline; justify-content: space-between; min-height: 1.4em; }
.ps-bal-label { font-size: 0.8rem; color: var(--muted); font-weight: 700; }
.ps-bal-val { font-size: 1.15rem; font-weight: 800; color: var(--good); }
.ps-bal-val.is-neg { color: var(--bad, #f87171); }
.ps-summary { margin-top: 10px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.ps-sum-row { display: flex; justify-content: space-between; padding: 9px 12px; font-size: 0.9rem; border-top: 1px solid var(--line); }
.ps-sum-row:first-child { border-top: none; }
.ps-diff { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.ps-diff-row { display: grid; grid-template-columns: 1fr auto auto auto; gap: 8px; align-items: center; padding: 10px 12px; border-radius: 12px; background: var(--card); border: 1px solid var(--line); font-size: 0.9rem; }
.ps-diff-old { color: var(--muted); text-decoration: line-through; }
.ps-diff-arrow { color: var(--muted); }
.ef-split-card .seg { flex: 0 0 auto; }

/* Pro setup intro: minimal text, one idea per block */
.ps-buttons .btn.primary { flex: 1; }
.ps-hero { text-align: center; padding: 18px 0 6px; }
.ps-hero-badge { display: inline-block; padding: 3px 12px; border-radius: 999px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.08em; color: #fff; background: linear-gradient(135deg, #fbbf24, #f59e0b 45%, #ea580c); box-shadow: 0 2px 8px rgba(234,88,12,0.4); }
.ps-hero-h { margin: 14px 0 6px; font-size: 2.1rem; line-height: 1.1; font-weight: 800; }
.ps-hero-sub { margin: 0; font-size: 1.05rem; color: var(--muted); }
.ps-privacy { display: flex; align-items: center; gap: 12px; width: 100%; margin: 20px 0 6px; padding: 12px 14px; text-align: left; font: inherit; color: inherit; cursor: pointer; border-radius: 14px; border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.ps-privacy-ico { font-size: 1.4rem; }
.ps-privacy-txt { flex: 1; font-size: 0.9rem; line-height: 1.35; }
.ps-privacy-txt b { display: block; }
.ps-privacy-txt span { color: var(--muted); }
.ps-privacy-i { flex: 0 0 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--muted); color: var(--muted); font-style: italic; font-size: 0.8rem; }
.ps-rhythm-head { margin: 18px 2px 8px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.ps-rhythm { display: flex; flex-direction: column; gap: 10px; }
.ps-r-card { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; text-align: left; font: inherit; color: inherit; cursor: pointer; border-radius: 14px; border: 1px solid var(--line); background: var(--card); animation: ps-in 0.5s ease both; }
.ps-r-card.is-here { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.ps-r-ico { flex: 0 0 44px; height: 44px; display: grid; place-items: center; font-size: 1.5rem; border-radius: 12px; background: color-mix(in srgb, var(--accent) 14%, transparent); }
.ps-r-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ps-r-when { font-size: 0.7rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }
.ps-r-body b { font-size: 1rem; }
.ps-r-more { max-height: 0; overflow: hidden; opacity: 0; font-size: 0.82rem; color: var(--muted); line-height: 1.35; transition: max-height 0.3s ease, opacity 0.3s ease, margin 0.3s ease; }
.ps-r-card.open .ps-r-more { max-height: 4.5em; opacity: 1; margin-top: 3px; }
.ps-r-chev { color: var(--muted); font-size: 1.3rem; transition: transform 0.25s ease; }
.ps-r-card.open .ps-r-chev { transform: rotate(90deg); }
.ps-r-here { flex: 0 0 auto; padding: 3px 9px; border-radius: 999px; font-size: 0.68rem; font-weight: 800; color: #fff; background: var(--accent); animation: ps-pulse 2s ease-in-out infinite; }
@keyframes ps-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes ps-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .ps-r-card, .ps-r-here { animation: none; } }

/* Welcome: four compact cards, two lines each, no page scroll */
.onboard-welcome .onboard-logo { width: 68px; height: 68px; margin-bottom: 8px; }
.onboard-welcome .onboard-h { font-size: 1.4rem; }
.onboard-welcome .onboard-sub { font-size: 0.92rem; }
.onboard-welcome .onboard-points { gap: 8px; margin-top: 14px; }
.onboard-welcome .onboard-point { padding: 9px 12px; }
.onboard-welcome .onboard-point > .onboard-point-ico { flex: 0 0 40px; width: 40px; height: 40px; font-size: 1.3rem; }
.onboard-welcome .onboard-point-body b { font-size: 0.93rem; }
.onboard-welcome .onboard-point-body p { font-size: 0.8rem; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.onboard-pro-star { width: 26px; height: 26px; display: block; }
/* The Pro card reads like the others; only its star shines, so nothing shouts on the welcome screen. */
.onboard-pro-card .onboard-point-ico { background: color-mix(in srgb, var(--warn) 14%, transparent); }
.onboard-pro-star { animation: pro-beat 2.8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .onboard-pro-star { animation: none; } }

/* Landing: Free Plan vs Pro Plan */
.lp-cmp { margin: 14px auto 0; max-width: 560px; border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: var(--card); }
.lp-cmp-row { display: grid; grid-template-columns: 1fr 78px 78px; align-items: center; gap: 8px; padding: 11px 12px; border-top: 1px solid var(--line); text-align: left; }
.lp-cmp-row:first-child { border-top: none; }
.lp-cmp-head { background: var(--bg-2); font-size: 0.78rem; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; }
.lp-cmp-l { font-size: 0.88rem; line-height: 1.3; }
.lp-cmp-l small { display: block; margin-top: 2px; font-size: 0.72rem; color: var(--muted); }
.lp-cmp-c { text-align: center; font-size: 0.82rem; font-weight: 700; }
.lp-cmp-c.yes { color: var(--good); font-size: 1rem; }
.lp-cmp-c.no { color: var(--muted); }
.lp-cmp-c.is-pro { color: var(--warn); }
.lp-cmp-head .is-pro { display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.lp-cmp-star { width: 14px; height: 14px; display: block; }
.lp-cmp-row:not(.lp-cmp-head) .is-pro { background: color-mix(in srgb, var(--warn) 10%, transparent); border-radius: 8px; padding: 4px 0; }
@media (max-width: 380px) { .lp-cmp-row { grid-template-columns: 1fr 64px 64px; padding: 10px 9px; } .lp-cmp-l { font-size: 0.82rem; } }

.lp-cmp-head .lp-cmp-c { line-height: 1.15; }

/* Comparison rows are tappable: the meaning slides open under the row */
.lp-cmp-item { width: 100%; font: inherit; color: inherit; background: none; border: none; border-top: 1px solid var(--line); cursor: pointer; grid-template-areas: "l f p" "d d d"; }
.lp-cmp-item .lp-cmp-l { grid-area: l; }
.lp-cmp-item .lp-cmp-l + .lp-cmp-c { grid-area: f; }
.lp-cmp-item .lp-cmp-c + .lp-cmp-c { grid-area: p; }
.lp-cmp-detail { grid-area: d; max-height: 0; overflow: hidden; opacity: 0; font-size: 0.8rem; line-height: 1.4; color: var(--muted); transition: max-height 0.3s ease, opacity 0.3s ease, margin 0.3s ease; }
.lp-cmp-item.open { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.lp-cmp-item.open .lp-cmp-detail { max-height: 8em; opacity: 1; margin-top: 4px; }
.lp-cmp-tip { margin: 0; padding: 8px 12px 10px; text-align: center; font-size: 0.72rem; color: var(--muted); border-top: 1px solid var(--line); }
.plan-compare-sheet .lp-cmp { margin-top: 10px; }
.plan-compare-close { width: 100%; margin-top: 14px; }

/* Free Plan: the rates strip is typed in, not fetched */
.home-rates-row.is-editable { cursor: pointer; }
.home-rate-edit { background: none; border: none; color: var(--muted); font-size: 0.95rem; padding: 2px 6px; border-radius: 8px; cursor: pointer; }
.home-rate-edit:active { background: var(--card-2); }
.home-rates.is-manual .home-rate-val { color: var(--text); }

/* Plan comparison sheet: fixed title and Close, the table scrolls between them */
.plan-compare-sheet { max-height: 88vh; }
.plan-compare-head { flex: 0 0 auto; padding: 16px 16px 8px; }
.plan-compare-head h2 { margin: 0 0 6px; }
.plan-compare-head .hint { margin: 0; }
.plan-compare-sheet .plan-compare-body { padding: 0 16px 8px; }
.plan-compare-sheet .lp-cmp { margin: 0; }
.plan-compare-sheet .lp-cmp-head { position: sticky; top: 0; z-index: 1; }
.plan-compare-close { width: 100%; margin: 0; }

/* Smaller type and narrower columns; the column titles are pinned above the scrolling rows and stay on one line */
.lp-cmp-row { grid-template-columns: 1fr 72px 72px; gap: 6px; padding: 9px 10px; }
.lp-cmp-l { font-size: 0.8rem; }
.lp-cmp-l small { font-size: 0.68rem; }
.lp-cmp-c { font-size: 0.74rem; }
.lp-cmp-c.yes { font-size: 0.9rem; }
.lp-cmp-head { font-size: 0.66rem; }
.lp-cmp-head .lp-cmp-c { white-space: nowrap; }
.lp-cmp-head .is-pro { display: inline-flex; align-items: center; justify-content: center; gap: 3px; flex-wrap: nowrap; }
.lp-cmp-star { width: 12px; height: 12px; flex: 0 0 auto; }
.plan-compare-thead { flex: 0 0 auto; padding: 4px 16px 0; }
.plan-compare-thead .lp-cmp-head { border: 1px solid var(--line); border-bottom: none; border-radius: 14px 14px 0 0; background: var(--bg-2); }
.plan-compare-sheet .lp-cmp.is-split { border-top-left-radius: 0; border-top-right-radius: 0; border-top: none; }
.plan-compare-sheet .plan-compare-body { padding-top: 0; }
@media (max-width: 380px) { .lp-cmp-row { grid-template-columns: 1fr 66px 66px; padding: 9px 8px; } }

/* Free Plan: the one-tap NAV button is greyed out (it still answers a tap, with the reason) */
.fab.is-locked { opacity: 0.4; filter: grayscale(1); box-shadow: none; }

#ocrBtn.is-locked { opacity: 0.4; filter: grayscale(1); box-shadow: none; }

/* Comparison: a narrower feature column, so the Free Plan / Pro Plan values get more room */
.lp-cmp-row { grid-template-columns: minmax(0, 1fr) 90px 90px; }
.lp-cmp-l { font-size: 0.76rem; }
.lp-cmp-l small { font-size: 0.64rem; }
@media (max-width: 380px) { .lp-cmp-row { grid-template-columns: minmax(0, 1fr) 80px 80px; } }

/* Pro Plan: Get started folds down to its first row */
.home-start-head.is-toggle { width: 100%; background: none; border: none; color: inherit; font: inherit; cursor: pointer; text-align: left; padding-top: 0; padding-bottom: 0; }
.home-start-right { display: inline-flex; align-items: center; gap: 8px; }
.home-start-arrows { display: inline-flex; color: var(--muted); transition: transform 0.3s ease; }
.home-start.open .home-start-arrows { transform: rotate(180deg); }
.home-start.is-collapsible:not(.open) .home-start-bodywrap { display: none; }
.home-start.is-collapsible:not(.open) { padding-bottom: 12px; }
.home-start.is-collapsible:not(.open) .home-start-head { margin-bottom: 0; }
@media (prefers-reduced-motion: reduce) { .home-start-arrows { transition: none; } }

/* Existing loans list: a Paid button on each entry */
.vb-row.has-paid input.vb-amt { flex: 0 0 84px; width: 84px; }
.vb-paid { border: 1px solid var(--line); background: var(--card-2); color: var(--muted); border-radius: 10px; padding: 7px 10px; font: inherit; font-size: 0.78rem; font-weight: 700; cursor: pointer; white-space: nowrap; }
.vb-paid.is-paid { border-color: var(--good); color: var(--good); background: color-mix(in srgb, var(--good) 14%, transparent); }
/* Get started: a step card is a tappable block with a small Skip on optional steps */
.home-start-card { position: relative; }
.home-start-skip { position: absolute; top: 8px; right: 12px; font-size: 0.72rem; font-weight: 700; color: var(--muted); padding: 2px 6px; border-radius: 8px; cursor: pointer; }
.home-start-skip:active { background: var(--card-2); }

.ef-equal-tip { margin: 2px 2px 10px; font-size: 0.78rem; }

/* Existing loans: settled loans sit below, struck through, with the date they were paid */
.vb-prev-head { margin: 12px 0 2px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.vb-row.vb-prev { opacity: 0.75; font-size: 0.86rem; }
.vb-prev-name, .vb-prev-amt { text-decoration: line-through; color: var(--muted); }
.vb-prev-name { flex: 1 1 auto; min-width: 0; }
.vb-prev-date { color: var(--good); font-size: 0.74rem; font-weight: 700; white-space: nowrap; }
.vb-prev-undo { font-size: 0.74rem; padding: 4px 8px; }

.alloc-shared-note { margin: 4px 2px 0; }

/* Yearly plan: the others' contribution is a sub point inside the House Exp card */
.alloc-sub { display: flex; justify-content: space-between; gap: 8px; margin-top: 8px; padding-top: 6px; border-top: 1px dashed var(--line); font-size: 0.72rem; color: var(--muted); }
.alloc-sub-v { font-weight: 700; color: var(--good); }

/* Cash flow: Available Balance, the loans taken off, and the Actual Balance with a short reminder */
.msheet-loan-line { display: flex; justify-content: space-between; margin: 2px 4px 0; padding: 4px 12px; font-size: 0.85rem; color: var(--muted); }
.msheet-actual { margin-top: 2px; }
.msheet-loan-note { margin: 4px 6px 10px; font-size: 0.78rem; text-align: center; }

/* Personal Spending: what is left per remaining day */
.pf-perday { display: flex; align-items: center; gap: 12px; margin: 8px 0; padding: 12px 14px; border-radius: 14px; border: 1px solid var(--line); background: var(--card); }
.pf-perday-ico { font-size: 1.4rem; }
.pf-perday-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pf-perday-label { font-weight: 700; font-size: 0.92rem; }
.pf-perday-sub { font-size: 0.74rem; color: var(--muted); }
.pf-perday-val { font-size: 1.15rem; font-weight: 800; color: var(--good); white-space: nowrap; }

.onboard-ver { margin-top: 6px; font-size: 0.66rem; opacity: 0.6; letter-spacing: 0.04em; }

/* The wizard footer sizes its own buttons: a sibling margin rule was inset-ing the primary when Back is hidden */
.ps-buttons .btn, .ps-buttons .btn.primary { margin: 0; max-width: none; }

/* Existing loans: each entry keeps a repayment box, a tally and its history */
.vb-loan { border: 1px solid var(--line); border-radius: 12px; padding: 10px; background: var(--card-2); display: flex; flex-direction: column; gap: 8px; }
.vb-loan-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.vb-loan-tally { font-size: 0.78rem; color: var(--muted); }
.vb-loan-hist { flex: 0 0 auto; padding: 2px 6px; }
.vb-loan-pay { display: flex; align-items: center; gap: 8px; }
input.loan-pay { flex: 1 1 auto; width: auto; }
.vb-loan-pay .btn.small { flex: 0 0 auto; }
.loan-hist { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.loan-hist-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
.loan-hist-date { flex: 1; font-size: 0.85rem; color: var(--muted); }
.loan-hist-amt { font-weight: 700; }

/* Help us improve: tighter, so the whole page is readable at a glance */
.onboard-about-ico { font-size: 1.9rem; margin-bottom: 2px; }
.onboard-demo-page .onboard-field-note { display: block; margin-top: 5px; }
.onboard-about-skip { margin-top: 12px; }

/* Pro popup: the supported apps read as a footnote to the benefit above them */
.pro-works { margin: 2px 2px 0; padding-left: 2px; font-size: 0.78rem; line-height: 1.4; color: var(--muted); }
.pro-free-line { margin-top: 12px; }
.pro-sheet .pro-now { margin-bottom: 2px; }

/* Free to Pro while the app is open: the icon crossfades, the badge pops in */
.home-title-ico { transition: opacity 0.26s ease, transform 0.26s ease; }
.home-title-ico.is-swapping { opacity: 0; transform: scale(0.82) rotate(-6deg); }
body.plan-flipped .home-title.has-pro .pro-pill { animation: pro-pop 0.7s cubic-bezier(0.2, 0.9, 0.3, 1.3) both; }
@keyframes pro-pop { from { opacity: 0; transform: scale(0.55); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .home-title-ico { transition: none; } body.plan-flipped .home-title.has-pro .pro-pill { animation: none; } }

/* Pro to Free: the badge fades out ahead of the icon swap */
.pro-pill { transition: opacity 0.24s ease, transform 0.24s ease; }
.pro-pill.is-leaving { opacity: 0; transform: scale(0.7); }
@media (prefers-reduced-motion: reduce) { .pro-pill { transition: none; } }

/* Pro setup intro v3: four equal, closed cards; the privacy note is a quiet line, not a panel */
.ps-hero-h { font-size: clamp(1.7rem, 7.4vw, 2.1rem); }
.ps-rhythm { margin-top: 20px; }
.ps-r-card.is-here { border-color: var(--line); box-shadow: none; }
.ps-privacy-quiet { margin: 14px 0 4px; padding: 10px 12px; background: none; border: 1px dashed var(--line); }
.ps-privacy-quiet .ps-privacy-txt { font-size: 0.82rem; }
.ps-privacy-quiet .ps-privacy-txt span { display: inline; }
.ps-privacy-quiet .ps-privacy-txt b { display: inline; }

/* Pro setup intro v4: the original hero, then "Your input rhythm", then a smaller privacy block underneath */
.ps-hero-h { font-size: 2.1rem; }
.ps-rhythm { margin-top: 0; }
.ps-privacy.ps-privacy-small { margin: 16px 0 4px; padding: 9px 12px; gap: 10px; background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); }
.ps-privacy-small .ps-privacy-ico { font-size: 1.1rem; }
.ps-privacy-small .ps-privacy-txt { font-size: 0.78rem; line-height: 1.3; }
.ps-privacy-small .ps-privacy-txt b { display: block; font-size: 0.82rem; }
.ps-privacy-small .ps-privacy-i { flex: 0 0 18px; height: 18px; font-size: 0.7rem; }
/* Keep the whole intro on one screen on smaller phones */
.ps-hero { padding: 8px 0 2px; }
.ps-hero-h { margin: 10px 0 4px; }
.ps-rhythm-head { margin: 14px 2px 6px; }
.ps-rhythm { gap: 8px; }
.ps-r-card { padding: 9px 12px; }
.ps-r-ico { flex-basis: 40px; height: 40px; }
.ps-privacy.ps-privacy-small { margin-top: 12px; }

/* Pro setup intro spacing that grows with the screen: the tight values are for a 750px-tall phone (no scroll),
   and every gap loosens as the screen gets taller, so a normal phone is not cramped. */
.ps-hero { padding: clamp(8px, calc(8px + (100vh - 750px) * 0.12), 40px) 0 2px; }
.ps-hero-h { margin: clamp(10px, calc(10px + (100vh - 750px) * 0.05), 26px) 0 clamp(4px, calc(4px + (100vh - 750px) * 0.03), 14px); }
.ps-hero-sub { margin-bottom: clamp(0px, calc((100vh - 750px) * 0.05), 14px); }
.ps-rhythm-head { margin: clamp(14px, calc(14px + (100vh - 750px) * 0.09), 36px) 2px clamp(6px, calc(6px + (100vh - 750px) * 0.04), 16px); }
.ps-rhythm { gap: clamp(8px, calc(8px + (100vh - 750px) * 0.04), 16px); }
.ps-r-card { padding: clamp(9px, calc(9px + (100vh - 750px) * 0.03), 16px) 14px; }
.ps-privacy.ps-privacy-small { margin-top: clamp(12px, calc(12px + (100vh - 750px) * 0.08), 32px); padding: clamp(9px, calc(9px + (100vh - 750px) * 0.02), 14px) 14px; }
.ps-foot { margin-top: clamp(10px, calc(10px + (100vh - 750px) * 0.05), 24px); }

.pf-lim-pool { margin: 8px 2px 4px; font-size: 0.78rem; line-height: 1.4; }

.badge.due-badge-sip { color: #16a34a; border-color: rgba(22,163,74,0.45); background: rgba(22,163,74,0.12); font-weight: 700; }
@media (prefers-color-scheme: dark) { .badge.due-badge-sip { color: #86efac; } }

/* The Coming Up strip now drifts by script: the rail itself scrolls, so it can be dragged and scrolled by hand */
.due-soon-scroller.is-marquee .due-soon-rail { animation: none; overflow-x: auto; width: auto; scroll-snap-type: none;
  cursor: grab; user-select: none; -webkit-user-select: none; touch-action: pan-x pan-y; }
.due-soon-scroller.is-marquee .due-soon-rail:active { cursor: grabbing; }

.badge.mf-sip-badge { color: #16a34a; border-color: rgba(22,163,74,0.45); background: rgba(22,163,74,0.12); font-weight: 700; }
@media (prefers-color-scheme: dark) { .badge.mf-sip-badge { color: #86efac; } }

/* The strip no longer carries a second copy of the cards, so there is nothing to hide. */

/* Comparison table: each column heading is its plan's app icon with the plan name beneath */
.lp-cmp-head .lp-cmp-c { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; }
.lp-cmp-ico { width: 30px; height: 30px; border-radius: 8px; object-fit: contain; display: block; }

/* Pro popup v2: each benefit is a card with an icon; upcoming ideas are quiet chips */
.pro-cards { display: flex; flex-direction: column; gap: 10px; margin: 10px 0 4px; }
.pro-card { display: flex; gap: 12px; align-items: flex-start; padding: 12px 12px; border-radius: 14px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--warn) 16%, transparent), color-mix(in srgb, var(--warn) 6%, transparent));
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent); }
.pro-card-ico { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px; display: flex; align-items: center; justify-content: center;
  font-size: 1.25rem; background: var(--card); box-shadow: 0 1px 4px rgba(0,0,0,0.12); color: var(--warn); font-weight: 800; }
.pro-card-body { min-width: 0; }
.pro-card-body b { display: block; font-size: 0.95rem; line-height: 1.3; }
.pro-card-body p { margin: 3px 0 0; font-size: 0.8rem; line-height: 1.4; color: var(--muted); }
.pro-card-tag { display: inline-block; margin-top: 7px; padding: 2px 9px; border-radius: 999px; font-size: 0.68rem; font-weight: 700;
  background: var(--card); border: 1px solid var(--line); color: var(--muted); }
.pro-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 10px; }
.pro-chip { padding: 4px 10px; border-radius: 999px; font-size: 0.74rem; color: var(--muted); background: var(--bg); border: 1px dashed var(--line); }

/* SIP done, from Home: a centred popup listing the fund, then two boxes */
.sip-sheet h2 { display: flex; align-items: center; gap: 10px; }
.sip-ico { display: inline-flex; width: 34px; height: 34px; align-items: center; justify-content: center; border-radius: 10px; background: color-mix(in srgb, #16a34a 16%, transparent); font-size: 1.15rem; }
.sip-details { margin: 10px 0 6px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.sip-row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 12px; font-size: 0.88rem; border-bottom: 1px solid var(--line); }
.sip-row:last-child { border-bottom: 0; }
.sip-row span { color: var(--muted); }
.sip-row b { text-align: right; font-variant-numeric: tabular-nums; }
.sip-form { margin-top: 12px; }
.sip-form[hidden] { display: none; }

/* Landing bottom bar once the app is installed: the message lives here, not in the page body */
.landing-bar .landing-bar-ico { width: 38px; height: 38px; border-radius: 10px; flex: 0 0 auto; }
.landing-bar.is-installed { background: color-mix(in srgb, var(--good) 12%, var(--bg-2)); border-top-color: color-mix(in srgb, var(--good) 45%, var(--line)); animation: bar-in 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2) both; }
.landing-bar.is-installed .landing-bar-text b { color: var(--good); }
.landing-bar-tick { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--good); color: #052e1a; font-size: 1.15rem; font-weight: 800; }
.landing-bar-tick[hidden], .landing-bar-ico[hidden] { display: none; }
@keyframes bar-in { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .landing-bar.is-installed { animation: none; } }
