/* Pass 1 migration note: this file is a straight relocation of index.html's original <style> block
   (lines 16-1255) plus its JS-injected "mobile adaptive CSS" block (formerly created at runtime via
   document.createElement('style') at the bottom of the old inline <script>) and the PIN-lock shake
   keyframes (formerly injected the same way). No selectors, values, or rules were changed — only
   moved into a real stylesheet and merged in file order. Do not reorganize into components yet;
   that's a later pass once behavior parity is confirmed. */

/* ── ATLAS DAYLIGHT TOKENS (Replacing CDS) ── */
:root {
  color-scheme: light;
  
  /* Typography */
  --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: var(--font-serif);

  /* Light Theme Core */
  --bg: #f1f3f7;
  --card: #fff;
  --card-2: #f6f8fb;
  --rail: #fff;
  --line: #e4e7ee;
  --line-2: #eef1f6;
  --fg: #15171c;
  --fg-2: #474c57;
  --fg-3: #666c79;
  
  --track: #dbe0e9;
  /* Ring / donut background track — Atlas tuned this to ~1.70:1 against --card and
     explicitly rejected the flatter --track value (which "reads as a broken arc
     floating in space" on a ring). Do not fold this back into --track — the two
     serve different jobs (bar/progress-strip fill vs. donut background). */
  --ring-track: #c4bfb3;
  --ink-tile: #15171c;
  --board-bg: var(--ink-tile);

  /* Atlas Pastel Palette */
  --mint: #cdf3e0;  --mint-on: #0a6a45;   --mint-mark: #0a6a45;
  --sky: #d5e6ff;   --sky-on: #12508f;    --sky-mark: #12508f;
  --lav: #e3dbff;   --lav-on: #543099;    --lav-mark: #543099;
  --blush: #ffdfd8; --blush-on: #9e3418;  --blush-mark: #9e3418;
  --butter: #ffeec4;--butter-on: #82590a; --butter-mark: #82590a;
  /* Dense P&L text (Holdings table, mover chips) — deliberately separate from
     --mint-mark/--blush-mark, which are tuned to work as pastel chip BACKGROUNDS.
     Used directly as small running text on a dark card, that same pastel reads as
     glare rather than a readable green/red. Values are "Option B" from the chart
     color mockup — muted teal/warm amber — kept identical to the chart line colors
     in renderChartInto() so the numbers and the chart next to them read as one
     palette, not two competing color languages. */
  --pl-pos: #0f766e; --pl-neg: #b45309;

  --mint-ink: var(--mint-on);
  --sky-ink: var(--sky-on);
  --lav-ink: var(--lav-on);
  --blush-ink: var(--blush-on);
  --butter-ink: var(--butter-on);

  /* Geometry & Elevation */
  --r: 20px;
  --r-s: 14px;
  --radius: var(--r);
  --radius-xs: var(--r-s);
  --shadow: 0 2px 4px rgba(21,23,28,.03), 0 12px 32px rgba(21,23,28,.06);
  --shadow-2: 0 4px 8px rgba(21,23,28,.05), 0 20px 48px rgba(21,23,28,.08);
  --shadow-flat: var(--shadow);

  /* ── LEGACY CDS TOKEN MAPPINGS (for unmigrated screens) ── */
  --surface-0: var(--bg);
  --surface-1: var(--card);
  --border: var(--line);
  --border-strong: var(--line-2);
  --text-primary: var(--fg);
  --text-secondary: var(--fg-2);
  --text-muted: var(--fg-3);
  
  --bg-success: var(--mint);
  --text-success: var(--mint-on);
  --bg-danger: var(--blush);
  --text-danger: var(--blush-on);
  --bg-warning: var(--butter);
  --text-warning: var(--butter-on);
  --bg-accent: var(--sky);
  --text-accent: var(--sky-on);

  --fill-accent: var(--fg);
  --on-accent: var(--bg);

  --btn-primary-bg: var(--fg);
  --btn-primary-text: var(--bg);
  --btn-muted-bg: var(--card-2);
  --btn-muted-text: var(--fg);

  --color-mint-bg: var(--mint);
  --color-mint-text: var(--mint-on);
  --color-mint-shadow: rgba(11, 56, 30, 0.08);
  
  --color-gold-bg: var(--butter);
  --color-gold-text: var(--butter-on);
  --color-gold-shadow: rgba(113, 63, 18, 0.12);

  --color-danger-bg: var(--blush);
  --color-danger-text: var(--blush-on);
  --color-danger-shadow: rgba(127, 29, 29, 0.08);
  
  --track-fallback: var(--track);

  /* Chart colors — point at the -mark tokens, not -on. In light mode -mark == -on
     (dark ink on white cards, unchanged from before); in dark mode -mark flips to
     the BRIGHT pastel while -on stays a near-black ink, which is what made dark-mode
     rings and bars read as muddy. Atlas separates -on (text ink on a pastel chip) from
     -mark (chart mark on a neutral card) for exactly this reason. See
     /root/.claude/plans/first-of-all-i-squishy-crown.md. */
  --chart-mint: var(--mint-mark);
  --chart-sky: var(--sky-mark);
  --chart-coral: var(--blush-mark);
  --chart-gold: var(--butter-mark);
  --chart-lav: var(--lav-mark);
  /* Dedicated to the dashboard Income/Expenses trend chart's bars only (2026-08-18) — that chart
     was using --chart-gold (= --butter-on, #82590a), an "ink" tone picked to stay text-legible on
     a light --butter chip background, not a solid-fill chart color. As a bar fill it read as a
     muddy brown, which is what the owner flagged. A real amber, not an ink token repurposed.
     Butter/gold is the one hue where -mark in light also = the muddy ink, so this hand-pick
     survives the -on → -mark re-point below. */
  --chart-expense: #c2660a;

  /* Atlas's 10-hue project-identity accent set (ported from pos-atlas/Deploy/css/tokens.css,
     2026-08-21). Used only for the Investments screen's per-stock logo monogram — a symbol gets
     a deterministic hue so the same stock always shows the same colour, standing in until real
     logo files are added (see v2/js/modules/assets.js's img-then-monogram fallback). */
  --accent-sage: #86ab92; --accent-blue: #759ad0; --accent-lilac: #ac9fd2; --accent-coral: #dd8170; --accent-amber: #c9a04a;
  --accent-forest: #5c9e72; --accent-indigo: #4078cb; --accent-plum: #8169c5; --accent-rust: #db5036; --accent-bronze: #b78a2b;

  --trophy-mint-bg: var(--mint);
  --trophy-gold-bg: var(--butter);
  --trophy-red-bg: var(--blush);

  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 24px;
  --space-2xl: 32px;
  --space-3xl: 48px;

  --transition-button: transform 150ms cubic-bezier(0.16, 1, 0.3, 1), background-color 150ms ease;
  --transition-card: transform .3s cubic-bezier(.34,1.56,.64,1), box-shadow .3s ease;
  --transition-panel: right 175ms cubic-bezier(0.16, 1, 0.3, 1);
  --transition-sidebar: width 280ms cubic-bezier(0.25, 1, 0.5, 1), padding 280ms cubic-bezier(0.25, 1, 0.5, 1);

  /* Atlas's calm ease-out, ported 2026-08-20 — used by the dashboard card hover above and the
     .mo-enter/.mo-leave motion primitives below. Named to match Atlas 1:1 (tokens.css) so future
     ports don't need renaming. */
  --dur-fast: 100ms;
  --dur-base: 180ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  
  /* Makeover tokens (2026-10) */
  --dl-alert: var(--blush);   --dl-alert-on: var(--blush-on);
  --dl-done: var(--mint);     --dl-done-on: var(--mint-on);
  --dl-task: var(--sky);      --dl-task-on: var(--sky-on);
  --dl-project: var(--lav);   --dl-project-on: var(--lav-on);
  --dl-skip: var(--card-2);   --dl-skip-on: var(--fg-2);
  --nec-ess: var(--accent-blue); --nec-non: var(--accent-amber); --nec-extra: var(--accent-coral);
  --nec-grow: var(--accent-plum); --nec-kept: var(--accent-forest);
  --ok: var(--accent-forest); --warn: var(--accent-amber); --over: var(--accent-rust);
  --ink-fg: #f4f5f8; --ink-fg-2: #a9afbd; --ink-line: #2a2d36;
  --fs-title: 30px; --fs-card-title: 14px; --fs-label: 14px; --fs-body: 16px;
  --fs-fig-xl: 40px; --fs-fig-l: 28px; --fs-fig-m: 24px; --fs-fig-s: 16px;

  /* Legacy aliases for backward compatibility */
  --text: var(--text-primary);
  --text2: var(--text-secondary);
  --accent: var(--fill-accent);
  --green: var(--text-success);
  --red: var(--text-danger);
  --amber: var(--text-danger);
  --purple: var(--text-success);
  --font: var(--font-sans);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-appearance="light"]) {
    color-scheme: dark;
    --bg:#101116; --card:#191b21; --card-2:#20232b; --rail:#16171c;
    --line:#272a33; --line-2:#20232a;
    --fg:#edeff4; --fg-2:#a9afbd; --fg-3:#8a91a0;
    --mint:#b6ecd2; --mint-on:#0a5c3c;  --mint-mark:#b6ecd2;
    --sky:#c3dcff;  --sky-on:#0f4680;   --sky-mark:#c3dcff;
    --lav:#d8ccff;  --lav-on:#4a2a8a;   --lav-mark:#d8ccff;
    --blush:#ffd0c6;--blush-on:#8d2d13; --blush-mark:#ffd0c6;
    --butter:#ffe6ac;--butter-on:#6f4b06;--butter-mark:#ffe6ac;
    --pl-pos: #2dd4bf; --pl-neg: #fbbf5e;
    --ink-tile:#13151a;
    --board-bg:#0b0c10;
    --track:#2f333d;
    --ring-track:#454545;
    --shadow:0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.35);
    --shadow-2:0 4px 8px rgba(0,0,0,.45), 0 20px 48px rgba(0,0,0,.4);
    --shadow-flat: var(--shadow);
    --chart-expense: #e8993d;
    /* Makeover tokens (2026-10) */
    --dl-alert: var(--blush);   --dl-alert-on: var(--blush-on);
    --dl-done: var(--mint);     --dl-done-on: var(--mint-on);
    --dl-task: var(--sky);      --dl-task-on: var(--sky-on);
    --dl-project: var(--lav);   --dl-project-on: var(--lav-on);
    --dl-skip: var(--card-2);   --dl-skip-on: var(--fg-2);
    --nec-ess: var(--accent-blue); --nec-non: var(--accent-amber); --nec-extra: var(--accent-coral);
    --nec-grow: var(--accent-plum); --nec-kept: var(--accent-forest);
    --ok: var(--accent-forest); --warn: var(--accent-amber); --over: var(--accent-rust);
    --ink-fg: #f4f5f8; --ink-fg-2: #a9afbd; --ink-line: #23262e;
    --fs-title: 30px; --fs-card-title: 14px; --fs-label: 14px; --fs-body: 16px;
    --fs-fig-xl: 40px; --fs-fig-l: 28px; --fs-fig-m: 24px; --fs-fig-s: 16px;
    --accent-sage:#6f8f65; --accent-blue:#5e7fb0; --accent-lilac:#8776a8; --accent-coral:#b56b5d; --accent-amber:#b89a44;
    --accent-forest:#4c6e42; --accent-indigo:#38598a; --accent-plum:#5d4886; --accent-rust:#8f4436; --accent-bronze:#8c722a;
  }
}

[data-appearance="dark"] {
  color-scheme: dark;
  --bg:#101116; --card:#191b21; --card-2:#20232b; --rail:#16171c;
  --line:#272a33; --line-2:#20232a;
  --fg:#edeff4; --fg-2:#a9afbd; --fg-3:#8a91a0;
  --mint:#b6ecd2; --mint-on:#0a5c3c;  --mint-mark:#b6ecd2;
  --sky:#c3dcff;  --sky-on:#0f4680;   --sky-mark:#c3dcff;
  --lav:#d8ccff;  --lav-on:#4a2a8a;   --lav-mark:#d8ccff;
  --blush:#ffd0c6;--blush-on:#8d2d13; --blush-mark:#ffd0c6;
  --butter:#ffe6ac;--butter-on:#6f4b06;--butter-mark:#ffe6ac;
  --pl-pos: #2dd4bf; --pl-neg: #fbbf5e;
  --ink-tile:#13151a;
  --board-bg:#0b0c10;
  --track:#2f333d;
  --ring-track:#454545;
  --shadow:0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.35);
  --shadow-2:0 4px 8px rgba(0,0,0,.45), 0 20px 48px rgba(0,0,0,.4);
  --shadow-flat: var(--shadow);
  --chart-expense: #e8993d;
  /* Makeover tokens (2026-10) */
  --dl-alert: var(--blush);   --dl-alert-on: var(--blush-on);
  --dl-done: var(--mint);     --dl-done-on: var(--mint-on);
  --dl-task: var(--sky);      --dl-task-on: var(--sky-on);
  --dl-project: var(--lav);   --dl-project-on: var(--lav-on);
  --dl-skip: var(--card-2);   --dl-skip-on: var(--fg-2);
  --nec-ess: var(--accent-blue); --nec-non: var(--accent-amber); --nec-extra: var(--accent-coral);
  --nec-grow: var(--accent-plum); --nec-kept: var(--accent-forest);
  --ok: var(--accent-forest); --warn: var(--accent-amber); --over: var(--accent-rust);
  --ink-fg: #f4f5f8; --ink-fg-2: #a9afbd; --ink-line: #23262e;
  --fs-title: 30px; --fs-card-title: 14px; --fs-label: 14px; --fs-body: 16px;
  --fs-fig-xl: 40px; --fs-fig-l: 28px; --fs-fig-m: 24px; --fs-fig-s: 16px;
  --accent-sage:#6f8f65; --accent-blue:#5e7fb0; --accent-lilac:#8776a8; --accent-coral:#b56b5d; --accent-amber:#b89a44;
  --accent-forest:#4c6e42; --accent-indigo:#38598a; --accent-plum:#5d4886; --accent-rust:#8f4436; --accent-bronze:#8c722a;
}

[data-appearance="light"] {
  color-scheme: light;
  --bg: #f1f3f7; --card: #fff; --card-2: #f6f8fb; --rail: #fff;
  --line: #e4e7ee; --line-2: #eef1f6;
  --fg: #15171c; --fg-2: #474c57; --fg-3: #666c79;
  --mint: #cdf3e0;  --mint-on: #0a6a45;   --mint-mark: #0a6a45;
  --sky: #d5e6ff;   --sky-on: #12508f;    --sky-mark: #12508f;
  --lav: #e3dbff;   --lav-on: #543099;    --lav-mark: #543099;
  --blush: #ffdfd8; --blush-on: #9e3418;  --blush-mark: #9e3418;
  --butter: #ffeec4;--butter-on: #82590a; --butter-mark: #82590a;
  --pl-pos: #0f766e; --pl-neg: #b45309;
  --ink-tile: #15171c;
  --board-bg: var(--ink-tile);
  --track: #dbe0e9;
  --shadow: 0 2px 4px rgba(21,23,28,.03), 0 12px 32px rgba(21,23,28,.06);
  --shadow-2: 0 4px 8px rgba(21,23,28,.05), 0 20px 48px rgba(21,23,28,.08);
  --shadow-flat: var(--shadow);
  --chart-expense: #c2660a;
  /* Makeover tokens (2026-10) */
  --dl-alert: var(--blush);   --dl-alert-on: var(--blush-on);
  --dl-done: var(--mint);     --dl-done-on: var(--mint-on);
  --dl-task: var(--sky);      --dl-task-on: var(--sky-on);
  --dl-project: var(--lav);   --dl-project-on: var(--lav-on);
  --dl-skip: var(--card-2);   --dl-skip-on: var(--fg-2);
  --nec-ess: var(--accent-blue); --nec-non: var(--accent-amber); --nec-extra: var(--accent-coral);
  --nec-grow: var(--accent-plum); --nec-kept: var(--accent-forest);
  --ok: var(--accent-forest); --warn: var(--accent-amber); --over: var(--accent-rust);
  --ink-fg: #f4f5f8; --ink-fg-2: #a9afbd; --ink-line: #2a2d36;
  --fs-title: 30px; --fs-card-title: 14px; --fs-label: 14px; --fs-body: 16px;
  --fs-fig-xl: 40px; --fs-fig-l: 28px; --fs-fig-m: 24px; --fs-fig-s: 16px;
}

* { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
body { font-family:var(--font-sans); background:var(--surface-0); color:var(--text-primary); min-height:100vh; padding-bottom:90px; font-size:15px; line-height: 1.6; transition:background 0.3s,color 0.3s; overflow-x: hidden; }
@media (min-width:900px) { body { padding-bottom:0; overflow:hidden; height:100vh; } }
#app { max-width:600px; margin:0 auto; padding:0 16px; }
@media (min-width:900px) { #app { max-width:none; margin:0; padding:0; display:flex; height:100vh; overflow:hidden; } }

/* ── Sidebar (Edge Rail) ── */
#sidebar {
  width: 240px;
  flex-shrink: 0;
  background: var(--surface-1);
  border-right: 1px solid var(--border);
  display: none;
  flex-direction: column;
  height: 100vh;
  position: relative;
  transition: var(--transition-sidebar);
}
@media (min-width:900px) { #sidebar { display:flex; } .bottom-nav { display:none; } }

.sb-brand {
  padding: 24px 16px 16px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  transition: padding 200ms cubic-bezier(0.16, 1, 0.3, 1);
}





.sb-brand-text {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.3;
}


/* Photo, then name underneath, then the nav — a vertical block rather than the
   old avatar-beside-name row. */
.sb-user {
  padding: 6px 16px 16px;
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  flex-shrink: 0;
  text-align: center;
}
.sb-user-name { font-size: 13px; font-weight: 600; color: var(--text-primary); line-height: 1.2; }

.sb-avatar {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--bg-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-accent);
  flex-shrink: 0;
  overflow: hidden;
  /* A ring rather than a border: it reads as deliberate framing at any photo
     crop, and keeps the circle clean against both light and dark surfaces. */
  box-shadow: 0 0 0 1px var(--border), 0 0 0 4px var(--surface-1), 0 2px 8px rgba(0,0,0,0.10);
  transition: width 150ms ease, height 150ms ease, font-size 150ms ease;
}
/* Sits over the initials rather than replacing them, so a missing or
   still-loading photo never leaves an empty circle. `loaded` only lands on a
   successful decode; onerror removes the element entirely. */



.sb-nav { padding: 12px 8px; flex: 1; overflow-y: auto; }
.sb-section-label {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 12px 8px 4px;
}
.sb-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 2px;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  transition: background 0.15s, color 0.15s, transform 0.15s;
  font-family: var(--font-sans);
}
.sb-nav-item i { font-size: 16px; flex-shrink: 0; opacity: 0.65; color: inherit; }
.sb-nav-item svg.lucide { width: 16px; height: 16px; flex-shrink: 0; opacity: 0.65; stroke-width: 1.5; }
.sb-nav-item:hover svg.lucide { opacity: 1; }
.sb-nav-item.active svg.lucide { opacity: 1; }
svg.lucide { width: 16px; height: 16px; stroke-width: 1.5; vertical-align: middle; }
.hdr-icon-btn svg.lucide { width: 16px; height: 16px; }
.hdr-primary-btn svg.lucide { width: 14px; height: 14px; }
.hdr-search svg.lucide { width: 14px; height: 14px; flex-shrink: 0; color: var(--text-muted); }

.badge svg.lucide { width: 10px; height: 10px; }
.nav-btn svg.lucide { width: 20px; height: 20px; }
.sb-nav-item:hover {
  background: var(--surface-0);
  color: var(--text-primary);
  transform: translateX(3px);
}
.sb-nav-item:hover i { opacity: 1; }
.sb-nav-item.active { background: var(--bg-accent); color: var(--text-accent); font-weight: 600; }
.sb-nav-item.active i { opacity: 1; }



.sb-label {
  transition: opacity 150ms ease;
  white-space: nowrap;
}



/*.sb-footer*/ .sb-footer { padding: 12px 16px; border-top: 1px solid var(--border); flex-shrink: 0; transition: padding 200ms ease; }
.sb-footer-sync { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--text-secondary); margin-bottom: 4px; }
.sb-sync-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-muted); flex-shrink: 0; transition: background 0.4s; }
.sb-sync-dot.online { background: var(--text-success); }
.sb-sync-dot.syncing { background: var(--text-accent); animation: pulse 1.5s infinite; }
.sb-sync-dot.offline { background: var(--text-danger); }
.sb-footer-ver { font-size: 9px; color: var(--text-muted); opacity: 0.65; }

/* ── Manual Collapsed Sidebar ── */
.sb-collapse-btn {
  width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line); background: var(--card);
  color: var(--fg-3); display: flex; align-items: center; justify-content: center; cursor: pointer;
  margin: 0 0 12px 8px; flex-shrink: 0; transition: all 0.15s;
}
.sb-collapse-btn:hover { color: var(--fg); border-color: var(--track); }
.sb-collapse-btn svg.lucide { width: 15px; height: 15px; }
#sidebar.collapsed .sb-collapse-btn { margin: 0 0 12px; }
#sidebar.collapsed {
  width: 76px;
}
#sidebar.collapsed .sb-label, #sidebar.collapsed .sb-brand-text, #sidebar.collapsed .sb-user-name, #sidebar.collapsed .sb-section-label, #sidebar.collapsed #sb-sync-text, #sidebar.collapsed .sb-footer-ver {
  display: none !important;
  opacity: 0 !important;
  pointer-events: none;
}
#sidebar.collapsed .sb-nav-item {
  padding: 8px 14px;
  justify-content: center;
}
#sidebar.collapsed .sb-brand {
  padding: 24px 14px 16px;
  justify-content: center;
}
#sidebar.collapsed .side-top {
  justify-content: center;
}
#sidebar.collapsed .sb-user {
  padding: 6px 14px 14px;
  justify-content: center;
}
/* Collapsed, the photo shrinks back to an icon-rail size — a 64px circle in a
   ~60px rail would overflow it. */
#sidebar.collapsed .sb-avatar {
  margin: 0;
  width: 34px;
  height: 34px;
  font-size: 12px;
  box-shadow: 0 0 0 1px var(--border);
}

#sidebar.collapsed .sb-footer {
  padding: 12px 14px;
}
#sidebar.collapsed .sb-footer-sync {
  justify-content: center;
}

/* ── Tablet Collapsed Sidebar ── */
@media (min-width: 900px) and (max-width: 960px) {
  #sidebar { width: 76px; }
  #sidebar .sb-label, #sidebar .sb-brand-text, #sidebar .sb-user-name, #sidebar .sb-section-label, #sidebar #sb-sync-text, #sidebar .sb-footer-ver {
    opacity: 0;
    pointer-events: none;
    display: none;
  }
  #sidebar .sb-nav-item { padding: 8px 14px; }
  #sidebar .sb-brand { padding: 24px 14px 16px; }
  #sidebar .sb-user { padding: 6px 14px 14px; }
  #sidebar .sb-footer { padding: 12px 14px; }
  /* Same reason as the collapsed rail: a 64px circle does not fit a 76px
     sidebar once padding is taken off. */
  #sidebar .sb-avatar {
    width: 34px; height: 34px; font-size: 12px;
    box-shadow: 0 0 0 1px var(--border);
  }
  
}

/* ── Main Area & Header ── */
.main-area { flex:1; display:flex; flex-direction:column; overflow:hidden; min-width:0; }
.content-area { flex:1; overflow-y:auto; padding:20px 24px 28px; }

#app-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px;
  height: 54px;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  transition: background 0.3s;
}
.hdr-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 900;
  letter-spacing: -0.05em;
  line-height: 1.05;
  color: var(--text-primary);
  white-space: nowrap;
}
.hdr-spacer { flex:1; }
.hdr-month { font-size: 12px; color: var(--text-secondary); white-space: nowrap; }
.hdr-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0 12px;
  height: 34px;
  width: 220px;
  flex-shrink: 0;
}
.hdr-search input {
  background: none;
  border: none;
  outline: none;
  font-size: 12px;
  color: var(--text-primary);
  width: 100%;
  font-family: var(--font-sans);
}
.hdr-search input::placeholder { color: var(--text-muted); }
.hdr-search i { font-size: 14px; color: var(--text-muted); flex-shrink:0; }

.hdr-icon-btn {
  height: 34px;
  width: 34px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 150ms cubic-bezier(0.16, 1, 0.3, 1), background-color 150ms ease;
  flex-shrink: 0;
}
.hdr-icon-btn:hover { background: var(--surface-0); transform: scale(1.08); }
.hdr-icon-btn:active { transform: scale(0.95); }




.hdr-primary-btn {
  height: 34px;
  padding: 0 16px;
  border: none;
  border-radius: 12px;
  background: var(--btn-primary-bg);
  color: var(--btn-primary-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-sans);
  flex-shrink: 0;
  transition: transform 150ms cubic-bezier(0.16, 1, 0.3, 1), background-color 150ms ease;
}
.hdr-primary-btn:hover { transform: scale(1.05); box-shadow: var(--shadow); }
.hdr-primary-btn:active { transform: scale(0.97); }
.hdr-primary-btn i { font-size: 14px; }

.sync-badge {
  font-size: 10px;
  padding: 0 8px;
  border-radius: 12px;
  height: 30px;
  background: var(--surface-0);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  transition: all 0.3s;
  border: 1px solid var(--border);
}
.sync-badge.syncing { background: var(--bg-accent); color: var(--text-accent); animation: pulse 1.5s infinite; }
.sync-badge.offline { background: var(--bg-danger); color: var(--text-danger); }
.sync-badge.online { background: var(--bg-success); color: var(--text-success); }

/* "Back up everything" pill in the top bar (2 Oct 2026). Quiet when this month's backup is done;
   amber (the --butter chip tokens, so it reads in light and dark) when one is due or has never been
   made. The pulse runs three times, then stops. */
.backup-pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 12px; border-radius: 16px;
  font: inherit; font-size: 12px; font-weight: 600; white-space: nowrap;
  background: var(--surface-0); color: var(--text-secondary);
  border: 1px solid var(--border); cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.backup-pill svg.lucide { width: 14px; height: 14px; }
.backup-pill:hover { color: var(--text-primary); }
.backup-pill.is-due {
  background: var(--butter); color: var(--butter-on); border-color: transparent;
  animation: backupPillPulse 1.6s ease-out 3;
}
@keyframes backupPillPulse {
  0%   { box-shadow: 0 0 0 0 var(--butter-mark); }
  70%  { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .backup-pill.is-due { animation: none; }
}
@media (max-width: 1100px) {
  .backup-pill:not(.is-due) .bp-label { display: none; }
}
/* The pill made the top bar ~120px wider; on a 1280px laptop that pushed "Add transaction" off the edge.
   Let the search box give up width instead (it was fixed at 220px and never shrank). */
#app-header .hdr-search { flex: 0 1 220px; width: auto; min-width: 110px; }

/* ── Physical Depth Containers (Cards) ── */
.card, .cmd-card, .kpi-card {
  background: var(--surface-1);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow) !important;
  /* Calm by default — the bouncy overshoot curve is reserved for the Dashboard (see below), where
     cards are for glancing/visuals. Everywhere else (Transactions, Reports, Documents, Settings,
     Goals) is for editing/entering data, so hover here is a quiet affordance, not an attention-grab. */
  transition: transform 150ms ease, box-shadow 150ms ease, background-color 150ms ease, border-color 150ms ease !important;
}
.kpi-card {
  padding: 24px 20px;
}
.card:hover, .cmd-card:hover, .kpi-card:hover {
  box-shadow: 0 4px 14px -2px rgba(0,0,0,0.06) !important;
  cursor: pointer;
}
.card:active, .cmd-card:active, .kpi-card:active {
  transform: scale(0.99) !important;
}

/* Dashboard used to keep a bouncy, attention-grabbing scale(1.02) hover here, restored at higher
   specificity over the calm default above. Replaced (2026-08-20) with the same lift-plus-shadow
   hover Atlas uses (primitives.css .tile:hover) — the scale jittered sibling cards in the same
   stretched grid row and read as busy next to the rest of the redesigned dashboard. */
#screen-dashboard .card, #screen-dashboard .cmd-card, #screen-dashboard .kpi-card {
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), background-color 150ms ease !important;
}
#screen-dashboard .card:hover, #screen-dashboard .cmd-card:hover, #screen-dashboard .kpi-card:hover {
  transform: none !important;
  box-shadow: var(--shadow-2) !important;
  border-color: var(--ring-track) !important;
}

/* ── Motion primitives, ported from Atlas (primitives.css), 2026-08-20 ──
   Applied via JS: add the base class + the -start class, force a reflow, then swap
   -start for -end (see toggleWithMotion() in app.js). Leaving is deliberately FASTER
   than arriving — waiting for something to go away feels like lag, waiting for it to
   arrive feels like polish. Reduced-motion users get instant show/hide because the
   transition itself is skipped by the browser's prefers-reduced-motion handling
   already present elsewhere in this file — no local override needed here either. */








/* ── Trophy Card (Component C) Styles ── */


/* ── Flat trophy assets (Design Bible — no gradients, hierarchy via tint + type) ── */







/* Dashboard KPI row is review-only (no navigation) — remove the clickable-affordance hover/cursor.
   Shadow is reset to each card type's own resting value (kpi-card is elevated, trophy-card is flat). */




/* ── Hero Card (flat, primary emphasis via stronger border + padding, not gradient) ── */



.summary-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 20px; }











/* Collapsible Accordion & Panels */
.collapsible-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 250ms cubic-bezier(0.16, 1, 0.3, 1);
  overflow: hidden;
}
.collapsible-panel.expanded {
  grid-template-rows: 1fr;
}
.collapsible-inner {
  min-height: 0;
}

/* ── Standard Utility Rows (Component B) ── */
.txn-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 16px;
  min-height: 48px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  transition: background 0.12s;
}
.txn-row:last-child { border-bottom: none; }
.txn-row:hover { background: var(--surface-0); }
.txn-row .left { display: flex; align-items: center; gap: 12px; }
.txn-row .icon { font-size: 18px; width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; background: var(--surface-0); color: var(--text-primary); }
.txn-row .name { font-weight: 600; font-size: 14px; color: var(--text-primary); }
.txn-row .meta { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.txn-row .amount { font-family: var(--font-sans); font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
.amount.income { color: var(--text-success); }
.amount.expense { color: var(--text-primary); }

/* ── Padded 3D Trophy Cards (Component C) ── */







/* ── Flyover Overlay Detail Panel (Chapter 08) ── */
#txnDetailModal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.14);
  z-index: 1000;
  display: flex !important;
  justify-content: flex-end;
  align-items: stretch;
  opacity: 0;
  pointer-events: none;
  transition: opacity 175ms linear;
}
#txnDetailModal.show {
  opacity: 1;
  pointer-events: auto;
}
#txnDetailModal .modal {
  width: 100%;
  max-width: 400px;
  height: 100%;
  max-height: 100vh;
  margin: 0;
  border-radius: 0;
  border-left: 1px solid var(--border);
  background: var(--surface-1);
  box-shadow: -10px 0 25px -5px rgba(0,0,0,0.04);
  display: flex;
  flex-direction: column;
  position: relative;
  right: -400px;
  transition: right 175ms cubic-bezier(0.16, 1, 0.3, 1);
  padding: 24px;
}
#txnDetailModal.show .modal {
  right: 0;
}
#txnDetailModal .modal-header h2 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
}

/* ── Buttons (Interactive States) ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  min-height: 40px;
  border-radius: 12px;
  border: none;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  background: var(--btn-primary-bg);
  color: var(--btn-primary-text);
  font-family: var(--font-sans);
  transition: transform 150ms cubic-bezier(0.16, 1, 0.3, 1), background-color 150ms ease, box-shadow 150ms ease;
}
.btn:hover {
  transform: scale(1.04);
  box-shadow: var(--shadow);
}
.btn:active {
  transform: scale(0.97);
}
.btn.green {
  background: var(--bg-success);
  color: var(--text-success);
  border: 1px solid var(--border);
}
.btn.green:hover {
  background: var(--bg-success);
}
.btn.red {
  background: var(--bg-danger);
  color: var(--text-danger);
  border: 1px solid var(--border);
}
.btn.red:hover {
  background: var(--bg-danger);
}
.btn.full { width: 100%; }
/* Was defined as CSS variables (--btn-muted-bg/text) but never actually wired to a .btn-muted rule,
   so every button already marked btn-muted in the markup (Modify, Cancel, etc.) was silently
   rendering as the solid-black primary button instead of this intended soft neutral gray/beige. */
.btn.btn-muted {
  background: var(--btn-muted-bg);
  color: var(--btn-muted-text);
}
.btn.btn-muted:hover {
  background: var(--btn-muted-bg);
}
/* Smaller, calmer variant for card-level actions (Update Numbers, Modify Target, Save forms in
   Documents/Settings) — same soft neutral tokens as .btn-muted, just compact and not a full-width
   bar, per the "small button, soothing color" request. */
.btn-soft {
  background: var(--btn-muted-bg);
  color: var(--btn-muted-text);
  padding: 7px 16px;
  font-size: 12px;
  min-height: 34px;
  border-radius: 10px;
  font-weight: 600;
}
.btn-soft:hover { background: var(--btn-muted-bg); }

.input-group { margin-bottom:16px; }
.input-group label { display:block; font-size:10px; font-weight:600; color:var(--text-secondary); margin-bottom:6px; text-transform:uppercase; letter-spacing:0.05em; }
.input-group input, .input-group select, .input-group textarea { width:100%; padding:12px 14px; border-radius:12px; border:1px solid var(--border); background:var(--surface-0); color:var(--text-primary); font-size:14px; font-family:var(--font-sans); transition: border-color 0.2s, box-shadow 0.2s; }
.input-group input:focus, .input-group select:focus, .input-group textarea:focus { outline:none; border-color:var(--text-accent); box-shadow:0 0 0 3px var(--bg-accent); }
.amount-input { font-size:32px !important; font-weight:900; font-family:var(--font-sans); font-variant-numeric: tabular-nums; text-align:center; }

.toggle-group { display:flex; gap:8px; margin-bottom:20px; }
.toggle-btn { flex:1; padding:10px; border-radius:12px; border:1px solid var(--border); background:var(--surface-1); color:var(--text-primary); font-size:13px; font-weight:600; cursor:pointer; transition: all 0.2s; }
.toggle-btn.active { background:var(--btn-primary-bg); border-color:var(--btn-primary-bg); color:var(--btn-primary-text); }
.toggle-btn.income.active { background:var(--bg-success); border-color:var(--border); color:var(--text-success); }
.toggle-btn.expense.active { background:var(--bg-danger); border-color:var(--border); color:var(--text-danger); }

/* ── Standard Modals (Fallback Overlay) ── */
.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.14); z-index:200; display:none; align-items:center; justify-content:center; padding:16px; }
.modal-overlay.show { display:flex; }
/* opacity:1 is a plain (non-animated) property, deliberately not part of the keyframe below. If the
   entrance animation is ever interrupted or fails to complete for any reason (observed live: a
   modal opened while the AI panel was also open stayed translucent, showing the dashboard bleeding
   through underneath it, unusable), the modal must never depend on the animation finishing to
   become visible — the slide-up motion is cosmetic, being visible at all is not optional. */
.modal { background:var(--surface-1); border-radius:var(--radius); border:1px solid var(--border); box-shadow:var(--shadow); width:100%; max-width:480px; max-height:90vh; overflow-y:auto; padding:24px; opacity:1; animation: modalUp 175ms cubic-bezier(0.16, 1, 0.3, 1); transition: background 0.3s; }
@keyframes modalUp { from { transform: translateY(30px) scale(0.97); } to { transform: translateY(0) scale(1); } }
/* Every modal already opens with modalUp above. None had a matching close animation —
   closeModal() just removed .show, snapping display:none instantly. Opt-in via
   .modal-motion (2026-08-20: budgetDrawerModal, goalsDrawerModal only, scoped
   deliberately — see closeModal() in app.js) rather than changing every modal's
   close behavior at once; the rest of the app's ~30 other modals, several of them
   safety-critical confirm dialogs (see CLAUDE.md's Insurance/Subscriptions save-
   confirm history), keep their exact current behavior untouched. */
.modal-motion.mo-leaving { transition: background var(--dur-fast) var(--ease-out); background: rgba(0,0,0,0); }
.modal-motion.mo-leaving .modal { transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); opacity: 0; transform: translateY(8px) scale(0.98); animation: none; }
/* Wider overlay variant for data-dense surfaces (Budget Health detail, etc.) — avoids awkward horizontal scroll on desktop */
@media (min-width:900px) { .modal.modal-wide { max-width:720px !important; } }
.modal-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; }
.modal-header h2 { font-size:18px; font-weight:700; color:var(--text-primary); }
.modal-close { font-size:24px; background:none; border:none; color:var(--text-secondary); cursor:pointer; line-height:1; }

/* ── Budgets & Tables ── */




.pct.over { background:var(--bg-danger); color:var(--text-danger); }
.pct.ok { background:var(--bg-success); color:var(--text-success); }
.pct.warn { background:var(--bg-danger); color:var(--text-danger); opacity:0.8; }




.empty { text-align:center; padding:40px 20px; color:var(--text-secondary); }
.empty .big { font-size:48px; margin-bottom:12px; }

/* ── Banned Zebra-striping & Alert Overrides ── */











.split-line { display:flex; gap:8px; align-items:center; padding:8px 0; border-bottom:1px dashed var(--border); }
.split-line select, .split-line input { flex:1; padding:8px; border-radius:12px; border:1px solid var(--border); background:var(--surface-0); color:var(--text-primary); font-size:14px; }
.split-line .split-amt { width:90px; flex:0 0 90px; }
.split-line .remove-btn { background:none; border:none; color:var(--text-danger); font-size:20px; cursor:pointer; padding:0 4px; }
.transfer-note { display:none; padding:12px; background:var(--bg-accent); border-radius:12px; font-size:13px; color:var(--text-accent); margin-bottom:12px; border:1px solid var(--border); }
.transfer-note.show { display:block; }

::-webkit-scrollbar { width:6px; height:6px; }
::-webkit-scrollbar-thumb { background:rgba(148,163,184,0.2); border-radius:3px; }
@media (max-width:400px) {  .amount-input { font-size:24px !important; } }

/* ── Grid System ── */


/* A 3-column outer grid with an odd card count (e.g. 4 small "wealth" cards) always strands the
   last row with empty trailing columns — the exact dead-space gap this fixes. cmd-wealth-grid is a
   cmd-full block that runs its own 2-column sub-grid, so an even card count always fills complete
   rows regardless of how tall any individual card's content is. */











/* ── Hero Card (flat — Design Bible) ── */
















/* ── KPI Grid ── */


.kpi-card { background:var(--surface-1); border:1px solid var(--border); border-radius:12px; padding:20px 18px; }







/* ── Semantic outline badges ── */
.badge { display:inline-flex; align-items:center; gap:4px; font-size:10px; font-weight:600; padding:3px 8px; border-radius:12px; white-space:nowrap; text-transform: uppercase; letter-spacing: 0.05em; border: 1px solid var(--border); }
.badge i { font-size:10px; }
.badge-success { background:var(--bg-success); color:var(--text-success); }
.toggle-switch-track { position:absolute; inset:0; background:var(--border); border-radius:24px; cursor:pointer; transition:.2s; }
.toggle-switch-track::before { content:''; position:absolute; left:3px; top:3px; width:18px; height:18px; background:#fff; border-radius:50%; transition:.2s; }
#setting-sandbox-toggle:checked + .toggle-switch-track { background:#B45309; }
#setting-sandbox-toggle:checked + .toggle-switch-track::before { transform:translateX(20px); }
.badge-danger { background:var(--bg-danger); color:var(--text-danger); }
.badge-warning { background:var(--bg-warning); color:var(--text-warning); }
.badge-accent { background:var(--bg-accent); color:var(--text-accent); }

.badge-neutral { background:var(--surface-0); color:var(--text-secondary); }

/* ── Data Tables ── */
.data-table { width:100%; border-collapse:collapse; }
.data-table thead { background:transparent; }
.data-table th { text-align:left; font-size:11px; font-weight:700; color:var(--text-secondary); text-transform:uppercase; letter-spacing:0.06em; padding:9px 14px; border-bottom:1.5px solid var(--border-strong); }
.data-table td { padding:11px 14px; border-bottom:1px solid var(--border); font-size:14px; vertical-align:middle; color:var(--text-primary); }
.data-table tr:last-child td { border-bottom:none; }
.data-table tbody tr:hover td { background:var(--surface-0); }

/* ── Upcoming bills: fixed to ~5 rows, the rest scrolls ──
   The card used to grow with the number of bills, which on a month with a lot
   of them turned the dashboard's most-glanced-at card into the longest thing
   on the page. A fixed box means the dashboard's shape never depends on how
   many bills happen to be outstanding.

   --bills-max-h is written by renderUpcomingBills() from the MEASURED height
   of a real row, not from a guess. A hardcoded pixel value was tried first and
   was wrong immediately: the arithmetic said 43px per row, the browser said
   63px, because the row also contains a Modify button and a due-date badge.
   Measuring means this stays correct if the row ever gains another control.

   The 55vh ceiling is what keeps mobile sane -- there each bill stacks into a
   multi-line block roughly three times the desktop height, so "5 rows" would
   be most of the screen. Whichever is smaller wins. */
.bills-scroll {
  max-height: min(var(--bills-max-h, 360px), 55vh);
  overflow-y: auto;
  overflow-x: auto;
}
/* Keeps the column labels in place while the rows move under them. */
.bills-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-1);
}
/* Slim, themed, and always visible rather than the OS default overlay bar --
   on a fixed-height list the scrollbar is the only cue that there is more to
   see, so it must not be the kind that hides until you touch it. */
.bills-scroll::-webkit-scrollbar { width: 5px; height: 5px; }
.bills-scroll::-webkit-scrollbar-track { background: transparent; }
.bills-scroll::-webkit-scrollbar-thumb {
  background: rgba(148, 163, 184, 0.30);
  border-radius: 3px;
}
.bills-scroll::-webkit-scrollbar-thumb:hover { background: rgba(148, 163, 184, 0.55); }
.bills-scroll::-webkit-scrollbar-corner { background: transparent; }
/* Firefox only. MUST stay behind @supports.
   `scrollbar-width` is now implemented in Chrome too, and there it OUTRANKS
   ::-webkit-scrollbar — setting it unscoped silently threw away the 5px bar
   above and gave Chrome its own idea of "thin", which is 10px on Windows and
   twice the width of the chat panel's. Measured, not assumed. */
@supports not selector(::-webkit-scrollbar) {
  .bills-scroll { scrollbar-width: thin; scrollbar-color: rgba(148,163,184,0.30) transparent; }
}

/* Upcoming Bills rows — same icon-tile + name/meta/amount hierarchy as Subscriptions' .svc/.ico/
   .name/.meta/.amt (main.css, under .sub-tcard), given its own prefixed classes rather than reusing
   those directly since this card isn't wrapped in a .sub-tcard and .name/.meta/.amt are common
   enough words that an unscoped global rule risked bleeding into unrelated parts of the page. */
.bill-row { display:flex; align-items:center; gap:12px; }
.bill-ico { width:34px; height:34px; border-radius:10px; display:flex; align-items:center; justify-content:center; font-size:16px; flex-shrink:0; }
.bill-name { font-weight:700; font-size:13.5px; }
.bill-meta { font-size:11px; color:var(--text-muted); margin-top:1px; }
.bill-amt { font-weight:700; font-size:13.5px; }


/* ── Progress strip ── */
.pstrip { background:var(--surface-0); border-radius:6px; overflow:hidden; height:4px; }
.pstrip-fill { height:100%; border-radius:6px; transition: width 0.5s ease; }

/* ── Rigid Calendar Grid Physics (Chapter 12) ── */

.mini-cal-hdr { text-align:center; font-size:10px; font-weight:600; color:var(--text-muted); padding:4px 0; text-transform: uppercase; }
.mini-cal-day {
  text-align: center;
  font-size: 11px;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0;
  cursor: pointer;
  color: var(--text-secondary);
  user-select: none;
  position: relative;
}
.mini-cal-day:hover { background: var(--surface-0); }
.mini-cal-day.mc-today {
  background-color: var(--text-primary) !important;
  color: var(--surface-1) !important;
  font-weight: 700;
}
.mini-cal-day.mc-has { font-weight:700; color:var(--text-primary); }
.mini-cal-day.mc-other {
  color: var(--text-muted);
  opacity: 0.4;
  cursor: default;
}
.mini-cal-day.mc-bill { color: var(--text-danger); font-weight: 700; }

/* ── Appearance selector ── */

.appearance-opt { flex:1; padding:8px 6px; border-radius:12px; border:1px solid var(--border); background:var(--surface-0); color:var(--text-secondary); font-size:11px; font-weight:500; cursor:pointer; text-align:center; display:flex; flex-direction:column; align-items:center; gap:4px; transition:all 0.15s; font-family:var(--font-sans); }
.appearance-opt i { font-size:16px; }
.appearance-opt.active { background:var(--bg-accent); border-color:var(--text-accent); color:var(--text-accent); }

/* ── Full Calendar Modal (Chapter 12) ── */
.cal-grid-7 {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
}
.cal-day-cell {
  aspect-ratio: 1 / 1;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s;
  color: var(--text-secondary);
  user-select: none;
  position: relative;
}
.cal-day-cell:hover { background: var(--surface-0); }
.cal-day-cell.cal-other {
  color: var(--text-muted);
  opacity: 0.4;
  cursor: default;
}
.cal-day-cell.cal-today {
  background-color: var(--text-primary) !important;
  color: var(--surface-1) !important;
  font-weight: 700;
}
.cal-day-cell.cal-selected {
  background: var(--bg-accent);
  color: var(--text-accent);
  border: 1px solid var(--text-accent);
}
.cal-dot-row {
  display: flex;
  gap: 2px;
  margin-top: 2px;
  position: absolute;
  bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
}
.cal-dot { width:4px; height:4px; border-radius:50%; }

/* ── Net Worth card — Trajectory layout, honed to match the mockup ──
   Full-width three-column grid. Left: display number in Fraunces + stats.
   Middle: trajectory chart, borderless, seamless — no "chart-inside-a-card".
   Right: exactly five rolled-up buckets, height stable regardless of data. */
.nw-grid { display:grid; grid-template-columns:minmax(240px, 320px) minmax(340px, 1fr) minmax(220px, 280px); gap:36px; font-variant-numeric:tabular-nums; padding-top:8px; align-items:stretch; }
.nw-left { display:flex; flex-direction:column; justify-content:flex-start; }
.nw-lbl { font-size:11px; letter-spacing:0.14em; text-transform:uppercase; color:var(--text-secondary); font-weight:600; }
.nw-big {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-variation-settings: 'opsz' 144;
  font-size: clamp(52px, 5.2vw, 74px);
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 0.95;
  color: var(--text-primary);
  margin: 10px 0 12px;
}
.nw-b-delta { display:inline-flex; align-items:center; gap:8px; padding:6px 14px; border-radius:999px; font-size:12.5px; font-weight:600; width:fit-content; }
.nw-b-delta.pos { background:color-mix(in srgb, var(--pl-pos) 16%, transparent); color:var(--pl-pos); }
.nw-b-delta.neg { background:color-mix(in srgb, var(--pl-neg) 16%, transparent); color:var(--pl-neg); }
.nw-b-delta .dim { opacity:0.72; font-weight:500; margin-left:4px; }
.nw-stats { display:grid; grid-template-columns:1fr 1fr; gap:18px 24px; margin-top:26px; padding-top:22px; border-top:1px solid var(--border); }
.nw-stat { display:flex; flex-direction:column; gap:3px; }
.nw-stat-lbl { font-size:10.5px; text-transform:uppercase; letter-spacing:0.12em; color:var(--text-secondary); font-weight:600; }
.nw-stat-val { font-size:15px; font-weight:700; color:var(--text-primary); }
.nw-stat-val.pos { color:var(--pl-pos); }
.nw-stat-val.neg { color:var(--pl-neg); }
.nw-stat-val.muted { color:var(--text-secondary); font-weight:500; }

/* Chart column — borderless, no separate background. Sits on the same card
   ground as the rest of the card so the whole thing reads as one surface. */
.nw-chart { display:flex; flex-direction:column; padding:6px 0 0; min-height:230px; }
.nw-chart-head { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:8px; gap:16px; }
.nw-chart-title { font-size:11px; letter-spacing:0.14em; text-transform:uppercase; color:var(--text-secondary); font-weight:600; }
.nw-chart-note { font-size:11px; color:var(--text-secondary); font-weight:500; opacity:0.8; text-align:right; }
.nw-chart-body { flex:1; min-height:190px; position:relative; }
.nw-chart-svg { width:100%; height:100%; display:block; }
.nw-chart-x { display:grid; grid-template-columns:repeat(12, 1fr); font-size:10px; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-secondary); font-weight:600; margin-top:8px; }
.nw-chart-x span { text-align:center; }

/* Composition strip — shown in the middle column until 3+ real monthly
   snapshots exist. Assets bar + Debts bar, BOTH scaled to total assets so
   the debt bar's visible length reads as the debt-to-asset ratio at a glance.
   No rings, no fake history. */
.nw-comp { display:flex; flex-direction:column; gap:20px; padding:8px 0 4px; }
.nw-comp-block { display:flex; flex-direction:column; gap:8px; }
.nw-comp-head { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
.nw-comp-lbl { font-size:10.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--text-secondary); font-weight:600; }
.nw-comp-val { font-size:16px; font-weight:700; color:var(--text-primary); font-variant-numeric:tabular-nums; }
.nw-comp-val.neg { color:var(--pl-neg); }
.nw-comp-dtoa { margin-left:auto; font-size:11.5px; font-weight:600; padding:3px 10px; border-radius:999px; }
.nw-comp-dtoa.pos { background:color-mix(in srgb, var(--pl-pos) 16%, transparent); color:var(--pl-pos); }
.nw-comp-dtoa.warn { background:color-mix(in srgb, var(--gold, #C48A26) 16%, transparent); color:var(--gold, #C48A26); }
.nw-comp-dtoa.neg { background:color-mix(in srgb, var(--pl-neg) 16%, transparent); color:var(--pl-neg); }
.nw-comp-bar { display:flex; height:24px; background:var(--surface-0); border-radius:6px; overflow:hidden; }
.nw-comp-seg { display:flex; align-items:center; padding:0 10px; color:#fff; font-size:11px; font-weight:600; letter-spacing:0.01em; overflow:hidden; white-space:nowrap; transition: width .4s ease; }
.nw-comp-seg span { text-overflow:ellipsis; overflow:hidden; }
.nw-comp-seg.re { background:var(--pl-pos); }
.nw-comp-seg.iv { background:color-mix(in srgb, var(--pl-pos) 70%, #ffffff 30%); }
.nw-comp-seg.ss { background:color-mix(in srgb, var(--pl-pos) 50%, #ffffff 50%); color:var(--pl-pos); font-weight:700; }
.nw-comp-seg.ln { background:var(--pl-neg); }
.nw-comp-seg.cc { background:color-mix(in srgb, var(--pl-neg) 70%, #ffffff 30%); }
.nw-comp-seg.empty { color:var(--pl-pos); background:color-mix(in srgb, var(--pl-pos) 12%, transparent); font-weight:600; padding:0 12px; }
.nw-comp-legend { display:flex; gap:14px; flex-wrap:wrap; font-size:11.5px; color:var(--text-secondary); }
.nw-comp-key { display:inline-flex; align-items:center; gap:6px; font-variant-numeric:tabular-nums; }
.nw-comp-dot { display:inline-block; width:8px; height:8px; border-radius:2px; }
.nw-comp-dot.re { background:var(--pl-pos); }
.nw-comp-dot.iv { background:color-mix(in srgb, var(--pl-pos) 70%, #ffffff 30%); }
.nw-comp-dot.ss { background:color-mix(in srgb, var(--pl-pos) 50%, #ffffff 50%); }

.nw-right { display:flex; flex-direction:column; }
.nw-breakdown-title { font-size:11px; letter-spacing:0.14em; text-transform:uppercase; color:var(--text-secondary); font-weight:600; margin-bottom:10px; }
.nw-brk-row { display:grid; grid-template-columns:1fr auto; align-items:baseline; column-gap:8px; row-gap:3px; padding:11px 0; border-bottom:1px solid var(--border); }
.nw-brk-row:last-of-type { border-bottom:none; }
.nw-brk-name { font-size:13px; font-weight:600; color:var(--text-primary); }
.nw-brk-val { font-size:13.5px; font-weight:700; color:var(--text-primary); font-variant-numeric:tabular-nums; }
.nw-brk-val.neg { color:var(--pl-neg); }
.nw-brk-val.muted { color:var(--text-secondary); font-weight:500; }
.nw-brk-meta { grid-column:1 / -1; font-size:11px; color:var(--text-secondary); }

@media (max-width: 1180px) {
  .nw-grid { grid-template-columns:1fr; gap:28px; }
  .nw-chart { min-height:200px; }
  .nw-big { font-size:56px; }
}

/* ── Insurance / emergency-fund tiles ── */







/* ── Emergency Fund Donut Wrap ── */


/* ── Document Vault ── */
.doc-section { margin-top:20px; padding-top:20px; border-top:1px solid var(--border); }
.doc-section-hdr { font-size:12px; font-weight:700; color:var(--text-primary); text-transform:uppercase; letter-spacing:.06em; margin-bottom:12px; display:flex; justify-content:space-between; align-items:center; }
.doc-attach-btn { font-size:11px; font-weight:700; color:var(--text-accent); background:var(--bg-accent); border:1px solid var(--border); border-radius:12px; padding:6px 14px; cursor:pointer; letter-spacing:.04em; }
.doc-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:12px; margin-top:4px; }
.doc-thumb { border-radius:12px; border:1px solid var(--border); aspect-ratio:1; overflow:hidden; cursor:pointer; position:relative; display:flex; align-items:center; justify-content:center; background:var(--surface-0); transition:transform 0.2s; }
.doc-thumb:active { transform:scale(0.95); }
.doc-thumb img { width:100%; height:100%; object-fit:cover; }



.doc-del-btn { position:absolute; top:6px; right:6px; width:20px; height:20px; border-radius:50%; background:var(--bg-danger); color:var(--text-danger); border:1px solid var(--border); font-size:11px; cursor:pointer; display:flex; align-items:center; justify-content:center; line-height:1; }
.doc-add-thumb { border:2px dashed var(--border); cursor:pointer; flex-direction:column; aspect-ratio:1; border-radius:12px; display:flex; align-items:center; justify-content:center; }
.doc-add-thumb div { font-size:24px; color:var(--text-secondary); }
.doc-add-thumb span { font-size:10px; color:var(--text-secondary); font-weight:600; margin-top:4px; }


/* ── Reports: the All / Expenses / Income segment style is still used by the Vault account tabs and the Teacher Mode tabs ── */
/* Expense/Income segmented control */
.rep-ftype-seg { display:inline-flex; margin-bottom:10px; border:1px solid var(--border); border-radius:10px; overflow:hidden; background:var(--surface-0); }
.rep-ftype-btn { padding:6px 18px; border:none; border-right:1px solid var(--border); background:transparent; color:var(--text-secondary); font-size:13px; font-weight:600; cursor:pointer; font-family:var(--font-sans); transition:background .12s,color .12s; }
.rep-ftype-btn:last-child { border-right:none; }
.rep-ftype-btn:hover { background:var(--surface-1); color:var(--text-primary); }
.rep-ftype-btn.active { background:var(--fill-accent); color:var(--on-accent); }

/* ── Screen Toggle System ── */
.screen {
  display: none !important;
}
/* Switching screens (showScreen() just toggles this class) was an instant display:none/block
   swap — no transition at all, which read as an abrupt jump-cut, most noticed on "View all"
   from the dashboard. A CSS animation (not a transition) is what actually plays here: display
   has no rendered "from" state to transition out of, but an animation defined on .screen.active
   runs correctly the moment the element becomes part of the render tree. Respects reduced-motion. */
.screen.active {
  display: block !important;
  animation: screenEnter 220ms ease-out;
}
@keyframes screenEnter {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .screen.active { animation: none; }
}

/* ── Person Report styles ── */




  /* Flex/grid children: prevent overflow blowout */
  .cmd-card, .kpi-card { min-width: 0; }
  .txn-row .name, .txn-row .meta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Chart responsive */
  #dash-perf-chart svg { width: 100%; }
  /* Tailwind-ish helpers */
  .hidden { display: none !important; }
  .w-full { width: 100%; }
  .overflow-x-auto { overflow-x: auto; max-width: 100%; }
  /* Extended 2026-08-20 (was horizontal-only: height + thumb color) to also cover vertical
     lists — e.g. Spending by Necessity's category list — and Firefox, and to stop scroll
     momentum from leaking into the page behind the card. Matches Atlas's .scroll-area. */
  .custom-scrollbar { scrollbar-width: thin; overscroll-behavior: contain; }
  .custom-scrollbar::-webkit-scrollbar { width: 4px; height: 4px; }
  .custom-scrollbar::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
  /* A wide-table wrapper that only ever needs HORIZONTAL scroll (Reports, Budget, Vault,
     dashboard mini-tables) was trapping vertical mouse-wheel scrolling instead of letting it
     reach the page underneath — confirmed with a real reproduction (a mouse-wheel event
     over the wrapper leaves .content-area's scrollTop untouched), not just reasoned about.
     A first attempt here pinned overflow-y:hidden, on the theory that overflow-x:auto was
     silently promoting overflow-y to auto too (the same CSS quirk this file already
     documents for the opposite axis) and creating an empty scroll container. That theory
     was wrong: this wrapper has no max-height, so it can never have vertical overflow in
     the first place (scrollHeight === clientHeight always) — overflow-y's value was never
     the deciding factor, proven by testing overflow-y:hidden and overflow-y:auto side by
     side with everything else held constant and getting the identical (broken) result
     either way. The actual cause is .custom-scrollbar's overscroll-behavior:contain: any
     element with overflow-x:auto is a real scroll container (on the X axis) whether or not
     Y has anything to scroll, and `contain` stops ALL scroll chaining out of a scroll
     container to its parent — including the vertical wheel input this element was never
     going to consume itself. Setting overscroll-behavior back to auto here (confirmed via
     the same reproduction — chaining resumes and the page scrolls normally) is the actual
     fix. Scoped to the combined selector for the same reason as before: the vertical-
     scrolling lists elsewhere (Spending by Necessity, etc.) use .custom-scrollbar alone,
     without .overflow-x-auto, and still want overscroll-behavior:contain — that's genuine
     scroll momentum inside a real vertical list, not this horizontal-only false positive. */
  .overflow-x-auto.custom-scrollbar { overscroll-behavior: auto; }
  @media (min-width: 640px) {
    .sm\\:table-cell { display: table-cell !important; }
  }

  /* ── Mobile containment (root-cause fixes, not just overflow hiding) ── */
  @media (max-width: 899px) {
    .bottom-nav {
      position: fixed;
      bottom: 0; left: 0; right: 0;
      height: 64px;
      background: var(--bg);
      border-top: 1px solid var(--border);
      display: flex; justify-content: space-around; align-items: center;
      padding-bottom: env(safe-area-inset-bottom, 0);
      z-index: 100;
    }
    .bottom-nav .nav-btn {
      display: flex; flex-direction: column; align-items: center; gap: 4px;
      background: none; border: none; color: var(--text-muted);
      font-size: 10px; font-weight: 500; font-family:var(--font-sans);
    }
    .bottom-nav .nav-btn.active { color: var(--text-primary); font-weight: 600; }
    
    /* content-area must not become a horizontal scroll container (overflow-y:auto forces overflow-x:auto) */
    .content-area { overflow: visible !important; height: auto !important; padding: 16px 14px 96px !important; }
    #app { padding: 0 !important; width: 100%; max-width: 100%; }
    body { padding-bottom: 0; }
    /* Declutter header: Add + search live in the bottom nav / are non-essential on small screens */
    #app-header { padding: 0 14px; gap: 8px; }
    .hdr-search { display: none !important; }
    .hdr-primary-btn { display: none !important; }
    /* Grids collapse to one column, read-order preserved */
    
    
    
    #dash-comparison > div { grid-template-columns: 1fr 1fr 1fr !important; }
    #screen-documents .input-group { min-width: 0; }
    
  }

  /* ── Dashboard tables → stacked cards (Bible "card transformation") ── */
  @media (max-width: 767px) {
    .data-table.stack-mobile thead { display: none; }
    .data-table.stack-mobile, .data-table.stack-mobile tbody { display: block; width: 100%; }
    .data-table.stack-mobile tr {
      display: block; border: 1px solid var(--border); border-radius: var(--radius);
      padding: 6px 12px; margin-bottom: 8px; background: var(--surface-1);
    }
    .data-table.stack-mobile td {
      display: flex; justify-content: space-between; align-items: center; gap: 12px;
      padding: 6px 0; border-bottom: 1px solid var(--border); max-width: none; white-space: normal;
      text-align: right; font-size: 13px;
    }
    .data-table.stack-mobile tr td:last-child { border-bottom: none; }
    
    .data-table.stack-mobile td::before {
      content: attr(data-label); text-align: left; color: var(--text-muted);
      font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; flex-shrink: 0;
    }
    .data-table.stack-mobile td[data-label=""]::before { content: none; }
  }

/* PIN-lock shake animation (formerly injected via JS at the bottom of the old inline <script>) */
@keyframes shake {
  0%,100% { transform: translateX(0); }
  20%,60% { transform: translateX(-8px); }
  40%,80% { transform: translateX(8px); }
}

/* ── AI Assistant (Phase 1) ── */
/* Floating entry button — only on Dashboard/Transactions/Reports (toggled by
   updateAiFabVisibility). Sits above content (z 150), below the drawer tier (1000). */
.ai-fab {
  display: none;
  position: fixed;
  right: 20px;
  bottom: 20px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: var(--fill-accent);
  color: var(--on-accent);
  box-shadow: var(--shadow);
  cursor: pointer;
  z-index: 150;
  align-items: center;
  justify-content: center;
  transition: var(--transition-button);
}
.ai-fab.visible { display: flex; }
.ai-fab:hover { transform: scale(1.06); }
.ai-fab:active { transform: scale(0.96); }
.ai-fab svg { width: 22px; height: 22px; }
/* Gentle twinkle on the icon's sparkles — quiet "something magic lives here" cue */
.ai-fab .fab-sparkle { animation: aiTwinkle 2.6s ease-in-out infinite; }
.ai-fab .fab-sparkle-2 { animation-delay: 1.3s; }
@keyframes aiTwinkle { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }
@media (max-width: 899px) {
  /* Clear the fixed bottom-nav (z 100) on mobile */
  .ai-fab { right: 16px; bottom: calc(66px + env(safe-area-inset-bottom, 0px) + 12px); }
}

/* ── AI Panel — fixed embedded sidebar (no overlay backdrop) ── */
.ai-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  background: var(--surface-0);
  border-left: 1px solid var(--border);
  box-shadow: -4px 0 24px rgba(0,0,0,0.06);
  display: flex;
  flex-direction: column;
  z-index: 150;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 280ms cubic-bezier(0.16, 1, 0.3, 1), visibility 0s linear 280ms;
}
.ai-panel.open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 280ms cubic-bezier(0.16, 1, 0.3, 1), visibility 0s;
}

/* Shift the whole app container when panel is open — desktop only.
   #app is a block element that responds correctly to margin-right. */
@media (min-width: 900px) {
  body.ai-panel-open #app {
    margin-right: 420px !important;
    transition: margin-right 280ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  #app {
    transition: margin-right 280ms cubic-bezier(0.16, 1, 0.3, 1);
  }
}

/* Panel header — single clean row: title | provider select | actions */
.ai-panel-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  height: 52px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--surface-1);
}
.ai-panel-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  font-family: var(--font-display);
  letter-spacing: -0.01em;
  white-space: nowrap;
  flex-shrink: 0;
}
.ai-provider-quick {
  flex: 1;
  min-width: 0;
  max-width: 144px;
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  font-family: var(--font-sans);
  cursor: pointer;
  outline: none;
}
.ai-provider-quick:focus { border-color: var(--fill-accent); }
.ai-status-dot {
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  background: var(--text-muted); opacity: 0.35;
  transition: background 0.4s, opacity 0.4s;
}
.ai-status-dot.online { background: #22c55e; opacity: 0.8; }
.ai-panel-actions {
  display: flex;
  align-items: center;
  gap: 0;
  flex-shrink: 0;
  margin-left: auto;
}

.ai-messages {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 10px;
  padding: 4px 2px; min-height: 0;
}
.ai-empty { margin: auto; text-align: center; padding: 0 12px; }
.ai-chips { display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
.ai-chip {
  padding: 9px 14px; border-radius: 12px; border: 1px solid var(--border);
  background: var(--surface-0); color: var(--text-primary); font-size: 13px;
  font-family: var(--font-sans); cursor: pointer; text-align: left;
  transition: background 0.12s, color 0.12s;
}
.ai-chip:hover { background: var(--surface-1); border-color: var(--border-strong); }

.ai-day-divider {
  display: flex; align-items: center; gap: 6px; align-self: stretch;
  margin: 2px 0 0; flex-shrink: 0;
}
.ai-day-divider::before, .ai-day-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); opacity: 0.5; }
.ai-day-divider span {
  font-size: 9px; font-weight: 400;
  color: var(--text-muted); white-space: nowrap; opacity: 0.7;
}

.ai-msg-stamp {
  font-size: 9px; color: var(--text-muted); opacity: 0.6;
  margin-bottom: 2px; font-family: var(--font-sans);
}
.ai-msg-stamp--user { text-align: right; }

.ai-msg-user {
  align-self: flex-end; max-width: 85%;
  background: var(--bg-accent); color: var(--text-accent);
  padding: 8px 12px; border-radius: 12px 12px 4px 12px;
  font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: break-word;
}
.ai-msg-assistant {
  align-self: flex-start; max-width: 92%;
  background: var(--surface-0); border: 1px solid var(--border); color: var(--text-primary);
  padding: 10px 12px; border-radius: 12px 12px 12px 4px;
  font-size: 14px; line-height: 1.55; overflow-wrap: break-word;
}
.ai-msg-assistant ul { margin: 4px 0 4px 18px; padding: 0; }
.ai-msg-assistant li { margin: 2px 0; }

.ai-msg-feedback {
  margin-top: 6px;
  display: flex;
  gap: 4px;
}
.ai-msg-feedback button {
  width: 24px; height: 24px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 50%;
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 150ms ease;
  flex-shrink: 0;
}
.ai-msg-feedback button svg { width: 12px; height: 12px; }
.ai-msg-feedback button:hover {
  background: var(--surface-2);
  color: var(--text-primary);
  border-color: var(--text-muted);
}
.ai-msg-feedback button.active {
  background: var(--bg-accent);
  color: var(--text-accent);
  border-color: var(--bg-accent);
}

/* ── Voice reply controls (per message) ──
   Its own row above the rating buttons, deliberately: rating an answer and
   listening to it are different intentions, and mixing six identical circles
   into one strip makes both harder to hit. Shares the feedback row's shape so
   the two read as one family. */
.ai-msg-voice {
  margin-top: 8px;
  display: flex;
  gap: 4px;
}
.ai-msg-voice button {
  width: 24px; height: 24px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 50%;
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 150ms ease;
  flex-shrink: 0;
}
.ai-msg-voice button svg { width: 12px; height: 12px; }
.ai-msg-voice button:hover {
  background: var(--surface-2);
  color: var(--text-primary);
  border-color: var(--text-muted);
}
.ai-msg-voice button.active {
  background: var(--bg-accent);
  color: var(--text-accent);
  border-color: var(--bg-accent);
}
/* Synthesis takes a moment on a long reply. A spinning icon is the difference
   between "working" and "dead button" -- and a dead-looking button gets tapped
   again, which would be a second billed Google call. */
.ai-msg-voice button.is-loading {
  cursor: default;
  opacity: 0.7;
}
.ai-msg-voice button.is-loading svg { animation: aiVoiceSpin 0.9s linear infinite; }
@keyframes aiVoiceSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* CFO Notebook indicator dot on the header button */
#ai-notebook-btn { position: relative; }
#ai-notebook-btn.has-entries::after {
  content: '';
  position: absolute;
  top: 5px; right: 5px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #22c55e;
  pointer-events: none;
}

/* CFO Notebook panel — replaces messages+footer while open */
.cfo-notebook-panel {
  flex-direction: column;
  flex: 1;
  min-height: 0;
  background: var(--surface-1);
}
.cfo-nb-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.cfo-nb-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  flex: 1;
}
.cfo-nb-action-btn {
  font-size: 11px;
  font-weight: 500;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-0);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 150ms, color 150ms;
  white-space: nowrap;
}
.cfo-nb-action-btn:hover { background: var(--surface-2); color: var(--text-primary); }
.cfo-nb-action-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.cfo-nb-list {
  flex: 1;
  overflow-y: auto;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.nb-empty {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.6;
  padding: 16px 4px;
}
.nb-entry {
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
}
.nb-entry-header {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.nb-entry-date {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
}
.nb-entry-type {
  font-size: 10px;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: 4px;
  padding: 1px 5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.nb-entry-del {
  margin-left: auto;
  width: 20px; height: 20px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px;
  padding: 0;
  transition: color 150ms, background 150ms;
}
.nb-entry-del:hover { color: var(--text-danger); background: var(--bg-danger); }
.nb-entry-del svg { width: 11px; height: 11px; }
.nb-entry-text {
  font-size: 12px;
  color: var(--text-primary);
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

.ai-msg-error {
  align-self: flex-start; max-width: 92%;
  background: var(--bg-danger); color: var(--text-danger);
  border: 1px solid var(--border);
  padding: 10px 12px; border-radius: var(--radius);
  font-size: 13px; line-height: 1.5;
}
.ai-msg-error .ai-error-action {
  display: inline-block; margin-top: 6px; font-size: 12px; font-weight: 600;
  color: var(--text-danger); text-decoration: underline; cursor: pointer;
  background: none; border: none; padding: 0; font-family: var(--font-sans);
}

/* Pulsing "thinking" placeholder shown until the first streamed token arrives */
.ai-thinking { display: inline-flex; gap: 4px; align-items: center; padding: 2px 0; }
.ai-thinking span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--text-muted);
  animation: aiPulse 1.2s ease-in-out infinite;
}
.ai-thinking span:nth-child(2) { animation-delay: 0.2s; }
.ai-thinking span:nth-child(3) { animation-delay: 0.4s; }
@keyframes aiPulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 0.9; } }

.ai-footer {
  padding: 12px 16px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface-1);
  flex-shrink: 0;
}
.ai-footer textarea {
  display: block; width: 100%; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface-0); color: var(--text-primary);
  font-family: var(--font-sans); font-size: 14px; padding: 10px 12px;
  resize: none; min-height: 80px; max-height: 180px; line-height: 1.5;
  outline: none; transition: border-color 0.15s, box-shadow 0.15s;
}
.ai-footer textarea:focus {
  border-color: var(--fill-accent);
  box-shadow: 0 0 0 2px var(--bg-accent);
}
.ai-footer-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 8px;
}
.ai-hint { font-size: 10px; color: var(--text-muted); font-family: var(--font-sans); }
.ai-send-btn {
  width: 32px; height: 32px; border-radius: 50%; border: none;
  background: var(--fill-accent); color: var(--on-accent);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: opacity 0.15s, transform 0.1s;
}
.ai-send-btn:hover { opacity: 0.85; }
.ai-send-btn:active { transform: scale(0.94); }
.ai-send-btn svg { width: 15px; height: 15px; }

/* .ai-mic-btn and its three states were removed 2026-08-09 along with
   speech-to-text. Finn reads replies aloud; it does not listen. */

/* ── Sign-off: entries Finn wrote, awaiting the boss's signature ──
   Amber, not red. These are not errors — they are real, correct-until-proven-
   otherwise records that simply have not been looked at yet. Red would make an
   ordinary Tuesday feel like something had gone wrong. */




.review-row { padding: 12px 0; border-bottom: 1px solid var(--border); }
.review-row:last-child { border-bottom: none; }
.review-row-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.review-amt { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
.review-amt.expense { color: var(--text-danger); }
.review-amt.income { color: var(--text-success); }
.review-meta { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.review-actions { display: flex; gap: 6px; align-items: center; flex-shrink: 0; }
/* His own words, kept verbatim, so a mis-heard entry can be traced back to the
   instruction that produced it rather than guessed at weeks later. */
.review-said {
  font-size: 12px; color: var(--text-muted); font-style: italic;
  margin-top: 6px; padding-left: 10px; border-left: 2px solid var(--border);
}
.review-missing {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; color: #B45309; margin-top: 6px;
}
.review-missing svg { width: 12px; height: 12px; flex-shrink: 0; }
@media (prefers-color-scheme: dark) { .review-missing { color: #FCD34D; } }

/* Same-day, same-amount warning — lets him compare a Gmail-detected charge against whatever else
   is already on record without leaving this panel to open Reports. */
.review-dupe-warning {
  display: flex; flex-direction: column; gap: 6px;
  font-size: 12px; color: #B45309; margin-top: 8px;
  padding: 8px 10px; border-radius: 8px;
  background: rgba(245, 158, 11, 0.08); border: 1px solid rgba(245, 158, 11, 0.25);
}
.review-dupe-warning svg { width: 12px; height: 12px; flex-shrink: 0; vertical-align: -1px; }
.review-dupe-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 4px 0 4px 17px; font-size: 12px; color: var(--text-secondary); font-weight: 500;
}
.review-dupe-row .btn-soft { font-size: 11px; padding: 3px 8px; flex-shrink: 0; }
@media (prefers-color-scheme: dark) { .review-dupe-warning { color: #FCD34D; } }

/* AI Settings modal sits above the AI panel drawer (z-index 1000) */
#aiSettingsModal { z-index: 1100; }
.ai-setup-status { font-size: 12px; color: var(--text-secondary); margin-top: 8px; line-height: 1.5; }
.ai-setup-status.ok { color: var(--text-success); }
.ai-setup-status.fail { color: var(--text-danger); }

/* ── Private Vault ──
   PIN overlay mirrors #pin-overlay's shape (icon, title, dots, keypad, shake-on-wrong-PIN via the
   existing shared `shake` keyframe) but is a fully separate element — 6 digits, own ids/classes. */
.vault-pin-overlay {
  display: none; position: fixed; inset: 0; z-index: 9998;
  background: var(--surface-0); align-items: center; justify-content: center; flex-direction: column;
}
.vault-pin-box { width: 100%; max-width: 360px; padding: 32px 24px; text-align: center; }
.vault-pin-icon { width: 32px; height: 32px; color: var(--text-primary); margin-bottom: 10px; }
.vault-pin-title { font-family: var(--font-sans); font-size: 20px; font-weight: 700; color: var(--text-primary); margin-bottom: 6px; }
.vault-pin-subtitle { font-family: var(--font-sans); font-size: 14px; color: var(--text-secondary); margin-bottom: 28px; }
.vault-pin-dots { display: flex; justify-content: center; gap: 14px; margin-bottom: 24px; }
.vault-pin-dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--border-strong); background: transparent; transition: background 0.2s, border-color 0.2s; }
.vault-pin-dot.filled { background: var(--text-primary); border-color: var(--text-primary); }
.vault-pin-error { font-family: var(--font-sans); font-size: 13px; color: var(--text-danger); min-height: 20px; margin-bottom: 12px; }
.vault-pin-keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; max-width: 240px; margin: 0 auto; }
.vault-pin-keypad button {
  padding: 18px; border-radius: 12px; border: 1px solid var(--border); background: var(--surface-1);
  font-family: var(--font-display); font-size: 20px; font-weight: 600; color: var(--text-primary);
  cursor: pointer; transition: background 0.1s;
}
.vault-pin-keypad button:active { background: var(--surface-0); }
.vault-pin-forgot, .vault-pin-cancel {
  display: block; margin: 16px auto 0; background: none; border: none; cursor: pointer;
  font-family: var(--font-sans); font-size: 13px; color: var(--text-muted);
}
.vault-pin-forgot { text-decoration: underline; }

/* Ledger screen — a full-screen overlay outside the showScreen()/nav system on purpose (no
   sidebar/nav entry point). Sits above drawers/modals (z-index 1000) but below toasts (2000) so a
   save-confirmation toast still reads on top of it. */
.vault-screen {
  display: none; position: fixed; inset: 0; z-index: 1500;
  background: var(--surface-0); flex-direction: column;
}
.vault-screen-hdr {
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px 20px; border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.vault-screen-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 700; color: var(--text-primary);
}
.vault-screen-title svg.lucide { width: 16px; height: 16px; }
.vault-ledger-body { flex: 1; overflow-y: auto; padding: 16px 20px; }
/* The generic .modal-overlay is z-index:200 — far below .vault-screen's 1500, so Add Entry/Transfer
   opened from inside the vault would render invisible and unclickable behind the vault screen
   itself. These two need to sit above the vault screen (but still below toasts at 2000). */
#vaultEntryModal, #vaultTransferModal { z-index: 1600; }
/* Restore and Reset are reachable from the PIN overlay too (z-index 9998), not just from the vault
   screen — the whole point of "save a copy first" is that it works when you CAN'T get in. So these
   two have to clear the PIN overlay, not just the vault screen. */
#vaultRestoreModal, #vaultResetModal { z-index: 9999; }
.vault-add-bar { padding: 14px 20px; border-top: 1px solid var(--border); flex-shrink: 0; }
.vault-backup-bar {
  display: flex; gap: 8px; align-items: center;
  padding: 0 20px 14px; flex-shrink: 0; flex-wrap: wrap;
}
.vault-backup-bar #vault-backup-status {
  font-size: 11px; color: var(--text2); margin-left: auto;
}
.vault-note-line { font-size: 12px; line-height: 1.5; color: var(--text2); }
.vault-inline-error { font-size: 12px; color: var(--text-danger); min-height: 16px; margin-top: 6px; }

/* Per-account balances + cumulative total — shown once above the account tabs so switching tabs
   never hides the bigger picture. */
.vault-balance-strip {
  display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 20px 0; flex-shrink: 0;
}
.vault-balance-chip {
  flex: 1; min-width: 90px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface-1);
}
.vault-balance-chip.total { background: var(--bg-accent); border-color: var(--border-strong); }
.vault-balance-chip-label {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); margin-bottom: 2px;
}
.vault-balance-chip-amount {
  font-size: 15px; font-weight: 800; color: var(--text-primary); font-variant-numeric: tabular-nums;
}
.vault-balance-chip.total .vault-balance-chip-amount { color: var(--text-accent); }

/* ── Budget page ── */













/* Necessity/Status filters (2026-08-26) — share Reports' .rep-mfilter-* checkbox-popover widget
   (main.css's Reports section below) instead of the earlier .bp-chip pill buttons. This group
   just gives the two widgets a sensible width in a flex row — .rep-mfilter-wrap has none of its
   own, since Reports places it inside a table <td> instead, which sizes it automatically. */



/* Budget table (2026-08-18) — replaced the earlier 5-zone card grid, where "Spent This Month,"
   "Spent Last Month," and "3-Month Average" all looked like interchangeable numbers scattered
   around a card with no strong visual anchor to their own label. A real <table> gives every
   number a column header directly above it, so which figure is which is never in question —
   the owner's own words were "I confuse what amount I am looking at and where I am looking." */
/* table-layout:fixed with explicit % widths on every column (2026-08-18 revision) — the first
   pass left most columns unconstrained, so the browser's automatic layout gave Category and
   Spent-this-month more room than they needed (their header text happened to measure wide) and
   squeezed the rest. Percentages always sum to 100 and are sized to what each column actually
   holds: Category needs room for icon+name+necessity, the numeric columns don't. Text also
   bumped up a size across the table per the owner's feedback that it read too small. */


































.not-budgeted-toggle { display: flex; align-items: center; justify-content: space-between; padding: 12px 4px; margin-top: 8px; border-top: 1px solid var(--border-strong); cursor: pointer; user-select: none; }
.not-budgeted-toggle .lbl { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.not-budgeted-toggle .chev { font-size: 11px; color: var(--text-muted); }


/* ── Mobile "More" sheet — reuses the standard modal, anchored to the bottom on small screens ── */
.more-sheet-overlay { align-items: flex-end; padding: 0; }
.more-sheet { max-width: 480px; width: 100%; border-radius: var(--radius) var(--radius) 0 0; padding: 0 0 12px; max-height: 80vh; }
.more-sheet-handle { display: flex; justify-content: center; padding: 10px 0 2px; }
.more-sheet-handle span { width: 34px; height: 4px; border-radius: 2px; background: var(--border-strong); display: block; }
.more-sheet .modal-header { padding: 6px 20px 8px; margin-bottom: 4px; }
.more-sheet-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 13px 20px; font-size: 13.5px; color: var(--text-primary); background: none; border: none; border-top: 1px solid var(--border); cursor: pointer; text-align: left; }
.more-sheet-item .chev { margin-left: auto; color: var(--text-muted); width: 16px; height: 16px; }
@media (min-width: 900px) {
  .more-sheet-overlay { align-items: center; padding: 16px; }
  .more-sheet { border-radius: var(--radius); }
  .more-sheet-handle { display: none; }
}

/* Budget & Goals — three compact cards side by side (2026-08-18). Reduced from .t's default
   22px/24px padding and dropped the forced min-height:300px the old single-column Goals screen
   used — these cards hold a progress bar and a couple of mini goal cards each, not enough
   content to justify a tall card, and forcing height only produced visible empty space. */
/* .t.goals-card-compact (compound selector), not .goals-card-compact alone — .t's own padding
   rule is a single class selector too, and it's defined LATER in this file, so equal-specificity
   + later-in-source was letting .t's 22px/24px silently win over this one. Compounding the
   selector makes it win on specificity regardless of where either rule sits in the cascade. */




/* ============================================================
   ATLAS DAYLIGHT LAYOUT CLASSES
   ============================================================ */

/* ---------- tiles & bento ---------- */

.t{ border-radius:var(--r); padding:22px 24px; position:relative; overflow:hidden;
    display:flex; flex-direction:column; transition:transform 0.2s, box-shadow 0.2s; }
.t.plain{ background:var(--card); border:1px solid var(--line); box-shadow:var(--shadow); }
.t.plain, .t.plain svg{
  --mint-ink:var(--mint-mark); --sky-ink:var(--sky-mark); --lav-ink:var(--lav-mark);
  --blush-ink:var(--blush-mark); --butter-ink:var(--butter-mark);
}
.t.plain .tag-s, .t.plain .sq {
  --mint-ink:var(--mint-on); --sky-ink:var(--sky-on); --lav-ink:var(--lav-on);
  --blush-ink:var(--blush-on); --butter-ink:var(--butter-on);
}
.t.fill{ color:var(--ink-tile); box-shadow:var(--shadow); }
.t.alert{ background:var(--dl-alert); color:var(--dl-alert-on); }
.t.done{ background:var(--dl-done); color:var(--dl-done-on); }
.t.task{ background:var(--dl-task); color:var(--dl-task-on); }
.t.project{ background:var(--dl-project); color:var(--dl-project-on); }
.t.skip{ background:var(--dl-skip); color:var(--dl-skip-on); }

.c3{grid-column:span 3}.c4{grid-column:span 4}.c5{grid-column:span 5}
.c6{grid-column:span 6}.c7{grid-column:span 7}.c8{grid-column:span 8}.c9{grid-column:span 9}.c12{grid-column:span 12}

.t-head{ display:flex; align-items:center; gap:10px; margin-bottom:14px; }
.t-lbl{ font-size:13px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; opacity:.85; }
.t.fill .t-lbl,.t.ink .t-lbl{ opacity:.95; }




/* Big typography */
.big{ font-family:var(--font-serif); font-size:46px; line-height:.95; font-variant-numeric:tabular-nums; letter-spacing:-.02em; }
.big.md{ font-size:36px; } .big.sm{ font-size:28px; }
.big .u{ font-family:var(--font-sans); font-size:16px; opacity:.7; margin-left:4px; letter-spacing:0; font-weight:600; }
.sub{ font-size:14px; opacity:.8; margin-top:6px; }
.delta{ font-size:14px; font-weight:700; font-variant-numeric:tabular-nums; }

.tag-s{ display:inline-flex; align-items:center; gap:6px; font-size:13px; font-weight:660;
        padding:5px 10px; border-radius:8px; background:rgba(255,255,255,.6); white-space:nowrap; }
.t.plain .tag-s{ background:var(--card-2); color:var(--fg-2); border:1px solid var(--line); }

/* Rows */
.rows{ display:flex; flex-direction:column; }
.r{ display:flex; align-items:center; gap:12px; padding:12px 0; border-bottom:1px solid var(--line-2); }
.r:last-child{ border-bottom:0; }
.r-name{ font-size:15px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.r-meta{ font-size:13px; color:var(--fg-3); margin-top:3px; display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.r-body{ min-width:0; flex:1; }
.r-right{ margin-left:auto; font-size:15px; color:var(--fg); font-weight:600; font-variant-numeric:tabular-nums; flex:none; text-align:right; }
.sq{ width:32px; height:32px; border-radius:9px; flex:none; display:grid; place-items:center; font-size:13px; font-weight:750; }



/* Shell adjustments mapped over existing ids/classes */
.side { background:var(--rail); border-right:1px solid var(--line); padding:18px 13px 16px; display:flex; flex-direction:column; gap:16px; height:100vh;}
.side-top { display:flex; align-items:center; gap:12px; padding:0 8px; margin-bottom:12px; }
.logo { width:36px; height:36px; border-radius:10px; flex:none; display:grid; place-items:center; background:var(--fg); color:var(--bg); font-family:var(--font-serif); font-size:20px; font-weight:700;}
.logo-txt { font-family:var(--font-serif); font-size:22px; letter-spacing:-.01em; font-weight:500;}
.me { display:flex; flex-direction:column; align-items:center; gap:8px; padding:8px 0 18px; border-bottom:1px solid var(--line-2); }
.me-pic { width:64px; height:64px; border-radius:50%; overflow:hidden; display:grid; place-items:center; background:linear-gradient(150deg,var(--sky),var(--lav)); font-family:var(--font-serif); font-size:24px; font-weight:500; color:var(--ink-tile); border:2px solid var(--card); box-shadow:var(--shadow); position: relative; }





/* Atlas Pastel Tiles */
.t-mint { background: var(--mint); color: var(--mint-ink); border-color: var(--mint); }

.t-mint .t-val { color: var(--mint-ink); font-weight: 700; }







.t-sky { background: var(--sky); color: var(--sky-ink); border-color: var(--sky); }

.t-sky .t-val { color: var(--sky-ink); font-weight: 700; }

.me-name { font-size:16px; font-weight:660; }
.me-role { font-size:13px; color:var(--fg-3); }

/* Overriding old Sidebar styles to use new look */
#sidebar { background: var(--rail); border-right: 1px solid var(--line); padding: 18px 13px 16px; }
.sb-nav-item { display:flex; align-items:center; gap:12px; width:100%; text-align:left; font:inherit; font-size:15px; font-weight:540; cursor:pointer; border:0; background:transparent; color:var(--fg-2); padding:12px; border-radius:10px; transition:all 0.15s ease; margin-bottom: 2px;}
.sb-nav-item:hover { background:var(--card-2); color:var(--fg); }
.sb-nav-item.active { background:var(--fg); color:var(--bg); font-weight:650; box-shadow:var(--shadow-2); }
.sb-nav-item.active i, .sb-nav-item.active svg, .sb-nav-item.active span { color:inherit !important; opacity:1; }
.sb-nav-item i { width:17px; height:17px; flex:none; color:currentColor; }
.sb-section-label { font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--fg-3); font-weight:700; padding:12px 10px 6px; }
.sb-footer { margin-top:auto; display:flex; flex-direction:column; gap:8px; padding-top:12px; border-top:1px solid var(--line-2); background:transparent; border-right:none;}

/* Overriding Topbar */
#app-header { background:transparent; border-bottom:1px solid var(--line); padding-bottom:18px; margin-top:16px; margin-bottom:24px; box-shadow:none; align-items:center; }
.hdr-title { font-family:var(--font-serif); font-size:32px; letter-spacing:-.015em; font-weight:400; color:var(--fg); }
.hdr-month { font-size:15px; color:var(--fg-3); font-family:var(--font-sans); }
.hdr-icon-btn, .hdr-search { border-radius:10px; border:1px solid var(--line); background:var(--card); color:var(--fg-2); display:flex; align-items:center; cursor:pointer; transition:all 0.15s;}
.hdr-icon-btn { width:40px; height:40px; justify-content:center;}
.hdr-icon-btn:hover { color:var(--fg); border-color:var(--track); box-shadow:var(--shadow);}
.hdr-primary-btn { background:var(--fg); color:var(--bg); border:0; padding:10px 16px; border-radius:10px; font-size:14px; font-weight:600; cursor:pointer; box-shadow:var(--shadow-2); transition:all 0.15s;}

/* Hover Bounce Interaction for Cards */
/* Hover lift removed 2026-10 (makeover B1): dashboard cards stay still on hover. */


/* ── Subscriptions & Services ── */
.sub-kpis { display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-bottom:8px; }
.sub-kpi { background:var(--card); border:1px solid var(--line,var(--border)); border-radius:var(--radius); padding:20px 22px; box-shadow:var(--shadow); }





.pill { font-size:11px; font-weight:700; padding:4px 11px; border-radius:100px; letter-spacing:.02em; margin-right:8px; }








/* Loans grid — Insurance & Loans screen. Dense, table-adjacent cards.
   NO rings anywhere by owner rule — the coverage indicator is a thin horizontal
   bar; every other metric is text. See v2/js/modules/loans.js's file-header note. */
.loans-grid { display:grid; grid-template-columns:1fr; gap:12px; }
@media (min-width: 900px) { .loans-grid { grid-template-columns:1fr 1fr; } }
.loan-card { background:var(--card); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow); padding:16px 18px; display:flex; flex-direction:column; gap:12px; }
.loan-card-head { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; }
.loan-name { font-size:15px; font-weight:700; color:var(--text-primary); }
.loan-provider { font-size:12px; color:var(--text-secondary); margin-top:2px; }
/* Three-dot (⋮) row menu — global rule, no pencil icons anywhere in the app
   ([[no-pencil-icons]]). The button prints the character directly, so no
   lucide icon load is needed on hot render paths. */
.loan-edit-btn { background:none; border:none; color:var(--text-secondary); cursor:pointer; padding:4px 8px; border-radius:6px; font-size:20px; line-height:1; }
.loan-edit-btn:hover { background:var(--surface-0); color:var(--text-primary); }

.loan-primary { display:flex; flex-direction:column; gap:8px; }
.loan-outstanding-val { font-size:22px; font-weight:700; color:var(--text-primary); letter-spacing:-0.01em; }
.loan-outstanding-lbl { font-size:12px; color:var(--text-secondary); display:flex; align-items:center; gap:4px; }
.loan-note-inline { font-size:11px; color:var(--text-secondary); cursor:help; }

.loan-progress-wrap { display:flex; flex-direction:column; gap:4px; }
.loan-progress-bar { position:relative; height:6px; background:var(--surface-0); border-radius:999px; overflow:hidden; }
.loan-progress-fill { position:absolute; top:0; left:0; bottom:0; background:linear-gradient(90deg, var(--pl-pos), var(--pl-pos-soft, var(--pl-pos))); border-radius:999px; transition:width .4s ease; }
.loan-progress-lbl { font-size:11px; color:var(--text-secondary); }

.loan-stats { display:grid; grid-template-columns:repeat(4, 1fr); gap:8px; padding-top:8px; border-top:1px solid var(--line-2, var(--border)); }
.loan-stat { display:flex; flex-direction:column; gap:2px; }
.loan-stat-lbl { font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--text-secondary); font-weight:600; }
.loan-stat-val { font-size:13px; font-weight:700; color:var(--text-primary); }
.loan-stat-sub { font-size:11px; color:var(--text-secondary); font-weight:500; margin-left:3px; }

.loan-foot { display:flex; align-items:center; gap:6px; font-size:11px; color:var(--text-secondary); }
.loan-note-sep { opacity:.5; }
.loan-notes { cursor:help; text-decoration:underline dotted; }
.loan-emi-src { font-size:10px; padding:1px 5px; border-radius:4px; background:color-mix(in srgb, var(--pl-pos) 15%, transparent); color:var(--pl-pos); font-weight:600; }
.loan-emi-src-fallback { background:color-mix(in srgb, var(--text-secondary) 15%, transparent); color:var(--text-secondary); }

/* Other Assets — third tab on Investments. Real HTML table so every column
   fills its allotted width and there is no empty middle band — global owner
   rule ([[no-empty-middle-cards]]). NO rings anywhere ([[no-rings-in-ui]]).
   Row menu is a three-dot ⋮ ([[no-pencil-icons]]) opening a shared floating
   menu. See v2/js/modules/otherAssets.js's header note for the schema. */
.am-other-assets { padding:8px 0; }

.oa-summary-row { display:grid; grid-template-columns:repeat(6, 1fr); gap:10px; padding:12px 4px 16px; border-bottom:1px solid var(--line-2, var(--border)); margin-bottom:12px; }
.oa-summary-item { display:flex; flex-direction:column; gap:2px; }
.oa-summary-item.pos .oa-summary-val { color:var(--pl-pos); }
.oa-summary-item.neg .oa-summary-val { color:var(--pl-neg); }
.oa-summary-lbl { font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--text-secondary); font-weight:600; }
.oa-summary-val { font-size:16px; font-weight:700; color:var(--text-primary); }
.oa-gain-pct { font-size:12px; font-weight:600; opacity:.85; }

.oa-table-wrap { background:var(--card); border:1px solid var(--border); border-radius:var(--radius); overflow-x:auto; overscroll-behavior:auto; }
.oa-table { width:100%; border-collapse:collapse; font-size:13px; min-width:820px; }
.oa-table thead th { position:sticky; top:0; background:var(--surface-0); color:var(--text-secondary); font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; font-weight:600; padding:10px 12px; text-align:left; border-bottom:1px solid var(--line-2, var(--border)); }
.oa-table thead th.oa-c-basis, .oa-table thead th.oa-c-current, .oa-table thead th.oa-c-gain { text-align:right; }
.oa-table thead th.oa-c-actions { width:44px; }
.oa-table tbody td { padding:12px; border-bottom:1px solid var(--line-2, var(--border)); vertical-align:middle; }
.oa-table tbody tr:last-child td { border-bottom:none; }
.oa-table tbody tr:hover { background:color-mix(in srgb, var(--text-primary) 3%, transparent); }

.oa-c-type { display:flex; align-items:center; gap:8px; }
.oa-type-chip { display:inline-flex; width:32px; height:32px; align-items:center; justify-content:center; border-radius:9px; background:var(--surface-0); font-size:17px; flex:none; }
.oa-type-lbl { font-size:11px; font-weight:600; color:var(--text-secondary); }
.oa-c-name { min-width:180px; }
.oa-name { font-size:14px; font-weight:700; color:var(--text-primary); }
.oa-provider { font-size:11.5px; color:var(--text-secondary); margin-top:2px; }
.oa-c-owner { width:88px; }
.oa-owner-tag { font-size:10.5px; padding:2px 8px; border-radius:5px; background:color-mix(in srgb, var(--text-primary) 10%, transparent); color:var(--text-primary); font-weight:600; }
.oa-c-basis, .oa-c-current, .oa-c-gain { text-align:right; font-weight:700; color:var(--text-primary); white-space:nowrap; }
.oa-current-num { font-size:14px; font-weight:700; }
.oa-c-sub { font-size:11px; color:var(--text-secondary); font-weight:500; margin-top:2px; }
.oa-c-gain.pos { color:var(--pl-pos); }
.oa-c-gain.neg { color:var(--pl-neg); }
.oa-muted { color:var(--text-secondary); font-weight:500; }
.oa-c-actions { text-align:center; width:44px; }
.oa-menu-btn { background:none; border:none; color:var(--text-secondary); cursor:pointer; padding:4px 8px; border-radius:6px; font-size:20px; line-height:1; }
.oa-menu-btn:hover { background:var(--surface-0); color:var(--text-primary); }

@media (max-width: 900px) {
  .oa-summary-row { grid-template-columns:repeat(3, 1fr); }
  .oa-type-lbl { display:none; }
}
@media (max-width: 640px) {
  .oa-summary-row { grid-template-columns:repeat(2, 1fr); }
}










.icon-btn { width:32px; height:32px; border-radius:9px; border:1px solid var(--border); background:var(--surface-0); color:var(--text-secondary); cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:15px; flex-shrink:0; }
.icon-btn:hover { background:var(--surface-1); }

.icon-btn svg { width:15px; height:15px; }








/* In-app confirm dialog (Save / Delete) — reuses .modal-overlay's centering, own card styling */
.confirm-box { background:var(--surface-1); border-radius:var(--radius); box-shadow:var(--shadow-2,var(--shadow)); width:100%; max-width:400px; padding:26px; text-align:left; }
.confirm-box .cico { width:44px; height:44px; border-radius:13px; display:flex; align-items:center; justify-content:center; font-size:20px; margin-bottom:16px; background:var(--bg-accent); color:var(--text-accent); }
.confirm-box.danger .cico { background:var(--bg-danger); color:var(--text-danger); }
.confirm-box h3 { margin:0 0 8px; font-size:17px; font-weight:800; color:var(--text-primary); }
.confirm-box p { margin:0 0 22px; font-size:13.5px; color:var(--text-secondary); line-height:1.6; }
.confirm-box .row { display:flex; gap:10px; }
.confirm-box button { flex:1; border:none; border-radius:11px; padding:12px; font-family:inherit; font-size:13.5px; font-weight:700; cursor:pointer; }
.confirm-box .cancel { background:var(--surface-0); color:var(--text-primary); border:1px solid var(--border) !important; }
.confirm-box .go-danger { background:var(--text-danger); color:#fff; }
.confirm-box .go-neutral { background:var(--fg); color:var(--bg); }
.confirm-box .col { display:flex; flex-direction:column; gap:8px; margin-bottom:8px; }
.confirm-box .col button { flex:none; }

/* PR #20 lesson, still true for the Reports entries card (now an .fm-card): the multi-select filter
   popovers sit inside it, so it must never be a shared `.card` (which carries `.card:active
   { transform: scale(0.99) }` and would scale an open popover on every click). .fm-card has no
   hover or press transform. Do not add one. */

/* Reports multi-select column filters — an Excel-AutoFilter-style checkbox popover replacing the
   old single-value <select> per column. Positioned the same way the Subscriptions kebab menu
   (.sub-menu) already is, absolute inside a position:relative wrapper, so it escapes the table's
   overflow-x:auto scroller the same proven way. */
.rep-mfilter-wrap { position:relative; }
.rep-mfilter-btn { width:100%; display:flex; align-items:center; justify-content:space-between; gap:4px; font-size:11px; padding:4px 7px; border-radius:6px; border:1px solid var(--border); background:var(--surface-1); color:var(--text-primary); font-family:inherit; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rep-mfilter-btn:hover { background:var(--surface-0); }
.rep-mfilter-btn.active { border-color:var(--text-accent); color:var(--text-accent); font-weight:700; }
.rep-mfilter-btn i { width:11px; height:11px; flex-shrink:0; }
.rep-mfilter-pop { position:absolute; top:calc(100% + 4px); left:0; z-index:30; min-width:190px; max-width:250px; max-height:260px; overflow-y:auto; background:var(--surface-1); border:1px solid var(--border); border-radius:10px; box-shadow:var(--shadow-2,var(--shadow)); padding:6px; display:none; }
.rep-mfilter-pop.open { display:block; }
.rep-mfilter-opt { display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:6px; font-size:12.5px; color:var(--text-primary); cursor:pointer; }
.rep-mfilter-opt:hover { background:var(--surface-0); }
.rep-mfilter-opt span { overflow:hidden; text-overflow:ellipsis; }
.rep-mfilter-divider { border-top:1px solid var(--border); margin:4px 2px; }
.rep-mfilter-empty { padding:8px; font-size:12px; color:var(--text-muted); }

@media (max-width: 760px) {
  .sub-kpis { grid-template-columns:repeat(2,1fr); }
}

@media (max-width: 1260px) {
  .c3,.c4,.c5,.c6,.c7,.c8{ grid-column:span 12; }
}

/* ═══════════════════════════════════════════════════════════════
   INVESTMENTS SCREENS (assets.js — Investments overview+holdings, Watchlist)
   Dense bento card system, ported from the mockup at
   /root/.claude/plans/first-of-all-i-squishy-crown.md (Round 5/6) — every card
   carries multiple filled elements, never one number floating in empty space.
   ═══════════════════════════════════════════════════════════════ */

/* No max-width here on purpose — every other screen fills .content-area edge to edge,
   the 1280px cap this used to carry was the one thing making Investments/Watchlist
   visibly narrower than Dashboard/Transactions/Reports on a wide screen. */
.am-page { padding: 24px; }
.am-page .grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 13px; align-items: stretch; margin-bottom: 13px; }
.am-page .c4 { grid-column: span 4; } .am-page .c5 { grid-column: span 5; } .am-page .c7 { grid-column: span 7; } .am-page .c12 { grid-column: span 12; }
.am-page .stack { display: flex; flex-direction: column; gap: 13px; }

.am-page .t {
  border-radius: var(--r); padding: 18px 20px; position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform .18s var(--ease-out), box-shadow .18s var(--ease-out);
}
.am-page .t:hover { transform: translateY(-2px); }
.am-page .t.plain { background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow); }
.am-page .t.mint { background: var(--mint); color: var(--mint-on); box-shadow: var(--shadow); }
.am-page .t.sky { background: var(--sky); color: var(--sky-on); box-shadow: var(--shadow); }
/* Fixed, not theme-relative: this tile is deliberately always-dark (the "black card" look),
   same as the reference dashboard's hero card. Using var(--fg)/var(--bg) here inverted to a
   LIGHT card in dark mode, while every child element (refresh button, delta chip, stat-row
   border) stayed hardcoded for "readable on dark" — the combination read as empty/invisible
   text in dark mode. #15171c/#edeff4 are this app's own light-mode --fg / dark-mode --fg
   literals, so the tile now looks identical in both themes. */
.am-page .t.ink { background: #15171c; color: #edeff4; box-shadow: var(--shadow-2); }
.am-page .t .pos { color: var(--mint-mark); } .am-page .t .neg { color: var(--blush-mark); }
.am-page .t.mint .pos, .am-page .t.sky .pos { color: var(--mint-on); }



/* Every .am-page .t card clips its own content at the rounded corner (overflow:hidden,
   needed by the hero card's chart canvas) — that same rule was silently slicing off the
   watchlist search dropdown below it, since an absolutely-positioned child is still clipped
   by any ancestor's overflow:hidden regardless of z-index. Scoped override, this card only:
   it holds no chart or image that needs edge-clipping, so there's nothing to lose. */




/* ── Hero chart card — number + delta + real chart + 3-stat footer, all in one card ── */



.am-hero-delta { font-size: 14.5px; font-weight: 700; margin-top: 4px; }
.am-hero-delta.pos { color: #7ef5b8; } .am-hero-delta.neg { color: #ffaaa0; }
.am-chart-canvas { flex: 1; min-height: 170px; margin-top: 10px; }
.am-chart-empty { height: 100%; min-height: 150px; display: flex; align-items: center; justify-content: center; font-size: 12.5px; opacity: .6; }




/* ── Compact per-broker cards — value + delta chip + a filled list of top holdings,
   the "MONEY card" treatment: never just a number and a sparkline. ── */









/* ── Top movers strip ── */

/* No monogram in these chips (kept only in the Holdings table) — narrower card, the
   name gets the full width and wraps to two lines instead of being squeezed/ellipsized. */







/* ── "What Needs a Look" attention panel ── */







/* ── Allocation small multiples (instrument / sector / broker) ── */






/* ── Holdings — real multi-column table, every column filled on every row ── */







/* Click-to-sort headers — deliberately no separate filter control, per the ask to
   keep this minimal: the header row itself is the entire sorting UI. */











/* Dense running P&L numbers read as glare in dark mode using the pastel chip-mark
   tokens (--mint-mark/--blush-mark are tuned for backgrounds, not small text on a
   dark card) — use the dedicated --pl-pos/--pl-neg pair here instead. */






/* ── Logo / monogram — img-first, monogram-fallback (see assets.js logoHtml()) ── */
.am-logo { width: 36px; height: 36px; border-radius: 10px; flex: none; position: relative; }
.am-logo.am-logo-sm { width: 28px; height: 28px; border-radius: 8px; }
.am-logo img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; display: block; }
.am-logo img.err { display: none; }
.am-logo .mono { width: 100%; height: 100%; border-radius: inherit; display: none; place-items: center; font-size: 13px; font-weight: 700; font-family: var(--font-sans); }
.am-logo.am-logo-sm .mono { font-size: 11px; }
.am-logo img.err + .mono { display: grid; }
.am-logo .mono:first-child { display: grid; } /* no <img> at all (LOGO_FILES_EXIST=false in assets.js): the letter mark shows directly */
.am-logo.h-sage .mono { background: var(--accent-sage); color: #15171c; } .am-logo.h-blue .mono { background: var(--accent-blue); color: #15171c; }
.am-logo.h-lilac .mono { background: var(--accent-lilac); color: #15171c; } .am-logo.h-coral .mono { background: var(--accent-coral); color: #15171c; }
.am-logo.h-amber .mono { background: var(--accent-amber); color: #15171c; }
.am-logo.h-forest .mono { background: var(--accent-forest); color: #fff; } .am-logo.h-indigo .mono { background: var(--accent-indigo); color: #fff; }
.am-logo.h-plum .mono { background: var(--accent-plum); color: #fff; } .am-logo.h-rust .mono { background: var(--accent-rust); color: #fff; }
.am-logo.h-bronze .mono { background: var(--accent-bronze); color: #fff; }
[data-appearance="dark"] .am-logo.h-forest .mono, [data-appearance="dark"] .am-logo.h-indigo .mono, [data-appearance="dark"] .am-logo.h-plum .mono,
[data-appearance="dark"] .am-logo.h-rust .mono, [data-appearance="dark"] .am-logo.h-bronze .mono { color: #15171c; }
@media (prefers-color-scheme: dark) {
  :root:not([data-appearance="light"]) .am-logo.h-forest .mono, :root:not([data-appearance="light"]) .am-logo.h-indigo .mono,
  :root:not([data-appearance="light"]) .am-logo.h-plum .mono, :root:not([data-appearance="light"]) .am-logo.h-rust .mono,
  :root:not([data-appearance="light"]) .am-logo.h-bronze .mono { color: #15171c; }
}

/* ── Watchlist ── */
/* Watchlist top card — title + "..." menu, group dropdown, Add Stock trigger. */











/* Floating "..." menu / group picker — body-level, position:fixed (set via JS),
   same clipping-safe approach used for the search suggestion box.
   z-index deliberately above the shared amModalBase() modal (10000) — this menu is
   opened FROM inside modals (Add Custom Asset → Category picker) and must render on
   top of them. Both live at document body level, so a tie on 10000 was resolved by
   whichever was appended first losing paint order — the modal was appended later
   than the floating menu (which any prior watchlist "⋮" click had already created)
   and buried the dropdown behind itself. Any modal that might spawn one of these
   menus must stay below this value. */
.am-floating-menu { display: none; z-index: 10050; background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shadow-2); padding: 6px; max-height: 320px; overflow-y: auto; }
.am-fmenu-item { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 9px 10px;
  border: none; background: none; color: var(--text-primary); font-size: 13px; font-weight: 600;
  cursor: pointer; border-radius: 7px; white-space: nowrap; }
.am-fmenu-item:hover { background: var(--surface-0); }
.am-fmenu-item.active { color: var(--pl-pos); }
.am-fmenu-item.danger { color: var(--pl-neg); }
.am-fmenu-item i { width: 15px; height: 15px; flex: none; }

.am-suggest-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; cursor: pointer; }
.am-suggest-row:hover { background: var(--surface-0); }
.am-suggest-row:not(:last-child) { border-bottom: 1px solid var(--line-2); }
.am-suggest-nm { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.am-suggest-sym { font-size: 12px; color: var(--text-secondary); flex: none; }
/* Compact single-row-per-stock list — matches the density of a real broker watchlist
   (Zerodha/Fyers/TradingView) instead of one padded, shadowed card per stock, which
   ate vertical space to show three numbers. Rows abut with a 1px divider instead of
   each carrying its own border+shadow+gap. */








/* Drag-to-reorder — plain HTML5 drag/drop, no visible up/down buttons per request. */


/* Watchlist has no hero panel of its own (see Round 5 plan) — clicking a card opens its
   chart in this modal instead, reusing the app's existing .modal-overlay/.modal convention
   (app.js's showModal/closeModal use the same .show class) rather than a bespoke pattern. */


/* Remove (✕) only appears on hover/focus — permanently visible was one more thing
   competing for width in an already-tight row. */




.wl-name { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-price { font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-secondary); text-align: right; }

 


.am-empty-state { text-align: center; padding: 50px 24px; color: var(--text-secondary); font-size: 14px; }

/* ── Skeleton loading ── */
.am-skeleton-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-s); margin-bottom: 8px; }
.am-skeleton-circle { width: 40px; height: 40px; border-radius: 12px; background: var(--border); flex-shrink: 0; }
.am-skeleton-lines { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.am-skel { height: 12px; background: var(--border); border-radius: 6px; animation: am-pulse 1.5s ease-in-out infinite; }
.am-skel-sm { width: 60%; }
@keyframes am-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

@media (max-width: 980px) {
  .am-page .c4, .am-page .c5, .am-page .c7 { grid-column: span 12; }
}

/* --- New Investments & Watchlist Overrides --- */





/* Sidebar narrowed now that rows are a compact single-line list rather than padded
   cards — the bigger width win for the chart is removing .am-page's old 1280px cap
   above, but every bit helps. */













.am-tf-btn { border: none; background: transparent; padding: 5px 12px; font-size: 12px; font-weight: 700; color: var(--text-secondary); border-radius: 6px; cursor: pointer; transition: all .15s; }
.am-tf-btn:hover { color: var(--text-primary); }
.am-tf-btn.active { background: var(--card); color: var(--text-primary); box-shadow: var(--shadow); }












.am-range-bar { height: 6px; background: var(--line-2); border-radius: 3px; position: relative; overflow: visible; }
.am-range-fill { height: 100%; background: linear-gradient(90deg, var(--blush-mark), var(--mint-mark)); border-radius: 3px; }
.am-range-pin { position: absolute; top: -4px; width: 14px; height: 14px; border-radius: 50%; background: var(--text-primary); border: 2px solid var(--card); transform: translateX(-50%); box-shadow: var(--shadow); }

.custom-scrollbar::-webkit-scrollbar { width: 5px; height: 5px; }
.custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }

/* --- TradingView Pro & Market Depth Overrides --- */
.am-tv-container { width: 100%; height: 560px; border-radius: var(--r-s); overflow: hidden; border: 1px solid var(--line-2); background: var(--surface-0); margin-top: 4px; }
@media (max-width: 900px) { .am-tv-container { height: 420px; } }

























#am-tv-wrapper { height: 500px; width: 100%; }
#am-tv-wrapper:fullscreen { height: 100vh; background: var(--bg); padding:16px; }
.am-tv-container { width: 100%; height: 100%; }

/* ── Fyers API Connection & Sync UI ── */





.am-fyers-btn {
  background: var(--text-primary);
  color: var(--surface-1);
  border: 1px solid var(--text-primary);
  border-radius: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all .15s ease;
}
.am-fyers-btn:hover {
  opacity: 0.9;
  transform: translateY(-1px);
}
.am-fyers-btn-outline {
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--line-2);
  border-radius: 6px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all .15s ease;
}
.am-fyers-btn-outline:hover {
  color: var(--text-primary);
  border-color: var(--border);
}
.am-fyers-btn-outline.active {
  color: var(--text-primary);
  border-color: var(--text-primary);
  background: var(--surface-0);
}

/* Manual holdings (Add Custom Asset — crypto, property, anything with no live market
   feed): LTP/day-change columns don't apply, so those cells carry a plain badge and an
   inline "Update Value" action instead. */












/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   PHONE VIEW (2026-09-14) — js/modules/phone.js. Only active on body.phone-mode, which is only set
   below 768px when the owner has not chosen "Full site". Everything is prefixed .ph- and built on
   the app's own tokens, so it follows the light/dark appearance setting and touches nothing else.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
body.phone-mode #sidebar,
body.phone-mode .main-area,
body.phone-mode #ai-fab { display: none !important; }
body.phone-mode { padding-bottom: 0; background: var(--bg); }
.phone-view-return { display: none !important; }
body.phone-capable:not(.phone-mode) .phone-view-return { display: flex !important; }

/* Finn opens the existing AI panel. On a phone it takes the whole screen. */
@media (max-width: 767px) {
  .ai-panel { width: 100vw; max-width: 100vw; }
}

#phone-shell {
  --ph-display: 'Fraunces', var(--font-serif);
  --ph-body: 'Instrument Sans', var(--font-sans);
  font-family: var(--ph-body);
  color: var(--fg);
  background: var(--bg);
  min-height: 100vh;
  padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
}
#phone-shell button { font-family: inherit; }

.ph-sandbox { background: var(--butter); color: var(--butter-on); font-weight: 700; font-size: 13px; text-align: center; padding: 8px 12px; }

.ph-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: calc(16px + env(safe-area-inset-top, 0px)) 18px 6px; }
.ph-top-text { min-width: 0; }
.ph-title { font-family: var(--ph-display); font-weight: 600; font-size: 36px; line-height: 1.02; letter-spacing: -0.01em; margin: 0; color: var(--fg); text-wrap: balance; }
.ph-sub { font-size: 13px; color: var(--fg-2); margin-top: 7px; line-height: 1.4; }
.ph-warn-txt { color: var(--butter-mark); font-weight: 600; }
.ph-pill { border: 1px solid var(--line); background: var(--card); color: var(--fg); font-weight: 600; font-size: 13px; padding: 9px 14px; border-radius: 999px; white-space: nowrap; cursor: pointer; flex-shrink: 0; }

.ph-body { padding: 10px 14px 18px; display: flex; flex-direction: column; gap: 12px; }
.ph-card { background: var(--card); border-radius: 22px; padding: 16px 18px; box-shadow: var(--shadow); min-width: 0; }
.ph-card-list { padding: 2px 18px; }
.ph-label { font-size: 11px; letter-spacing: .11em; text-transform: uppercase; font-weight: 700; color: var(--fg-2); }
.ph-num { font-family: var(--ph-display); font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: var(--fg); overflow-wrap: anywhere; }
.ph-cap { font-size: 12.5px; color: var(--fg-2); margin: 6px 0 0; line-height: 1.45; }
.ph-note { margin: -2px 6px 0; }
.ph-muted { color: var(--fg-3); }
.ph-pos { color: var(--mint-mark); }
.ph-neg { color: var(--blush-mark); }
.ph-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.ph-link { background: none; border: none; padding: 4px 0; font-size: 13px; font-weight: 600; color: var(--mint-mark); cursor: pointer; }

/* Home — net cash flow */
.ph-hero-num { font-size: 44px; line-height: 1.05; margin: 8px 0 4px; }
.ph-hero-num.ph-pos { color: var(--mint-mark); }
.ph-hero-num.ph-neg { color: var(--blush-mark); }
.ph-split { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.ph-split > div { background: var(--card-2); border-radius: 14px; padding: 10px 12px; min-width: 0; }
.ph-split-v { font-size: 21px; margin-top: 3px; }
.ph-flowbar { height: 8px; border-radius: 99px; background: var(--track); margin-top: 12px; overflow: hidden; }
.ph-flowbar span { display: block; height: 100%; background: var(--blush-mark); border-radius: 99px; }

/* Home — budget. Bars with a pace tick, no ring (the .fm-bar look from the makeover components). */
.ph-bhead { display: flex; align-items: baseline; gap: 10px; margin-top: 8px; }
.ph-bhead-p { font-size: 28px; line-height: 1; }
.ph-bledger { display: grid; gap: 14px; margin-top: 14px; }
.ph-bl { display: grid; gap: 6px; min-width: 0; }
.ph-bl-top { font-size: 14px; font-weight: 600; display: flex; justify-content: space-between; gap: 8px; }
.ph-bl-top span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ph-bl-top b { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ph-bl-of { color: var(--fg-3); font-weight: 500; }
.ph-bar { height: 6px; border-radius: 99px; background: var(--track); overflow: hidden; }
.ph-bar span { display: block; height: 100%; border-radius: 99px; background: var(--mint-mark); }



/* Lists */
.ph-list { display: flex; flex-direction: column; margin-top: 4px; }
.ph-item { display: grid; grid-template-columns: 38px minmax(0, 1fr) auto; gap: 11px; align-items: center; padding: 10px 0; border: none; border-bottom: 1px solid var(--line); background: none; color: inherit; text-align: left; width: 100%; cursor: pointer; }
.ph-item:last-child { border-bottom: none; }
.ph-item:focus-visible, .ph-nav-btn:focus-visible, .ph-pill:focus-visible, .ph-seg button:focus-visible, .ph-more:focus-visible, .ph-fab:focus-visible { outline: 2px solid var(--text-accent); outline-offset: 2px; border-radius: 10px; }
.ph-item-text { min-width: 0; }
.ph-ico { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; font-size: 18px; }
.ph-t1 { font-size: 14px; font-weight: 600; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ph-t2 { font-size: 12px; color: var(--fg-2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ph-amt { font-weight: 700; font-size: 14px; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; color: var(--fg); }
.ph-amt.ph-in { color: var(--mint-mark); }
.ph-amt.ph-muted { color: var(--fg-3); }
.ph-chip { font-size: 10.5px; font-weight: 700; letter-spacing: .02em; padding: 3px 8px; border-radius: 999px; display: inline-block; margin-top: 3px; white-space: nowrap; }
.ph-chip-due { background: var(--butter); color: var(--butter-on); }
.ph-chip-over { background: var(--blush); color: var(--blush-on); }
.ph-chip-paid { background: var(--mint); color: var(--mint-on); }
.ph-when { width: 38px; text-align: center; }
.ph-when-d { font-family: var(--ph-display); font-weight: 600; font-size: 19px; line-height: 1; color: var(--fg); }
.ph-when-m { font-size: 10px; font-weight: 700; color: var(--fg-2); letter-spacing: .06em; margin-top: 2px; }

/* Home — last 3 months */
.ph-snap { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 12px; }
.ph-snap-m { text-align: center; min-width: 0; }
.ph-snap-pair { height: 82px; display: flex; gap: 5px; align-items: flex-end; justify-content: center; border-bottom: 1px solid var(--line); }
.ph-snap-pair span { width: 16px; border-radius: 6px 6px 2px 2px; display: block; min-height: 2px; }
.ph-snap-in { background: var(--mint-mark); opacity: .55; }
.ph-snap-ex { background: var(--blush-mark); opacity: .5; }
.ph-snap-ml { font-size: 12px; font-weight: 600; margin-top: 6px; color: var(--fg); }
.ph-snap-sv { font-size: 11px; color: var(--fg-2); }
.ph-legend { display: flex; gap: 12px; font-size: 12px; color: var(--fg-2); }
.ph-legend i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; margin-right: 5px; vertical-align: -1px; }

/* Home — wealth */
.ph-wealth { background: var(--ink-tile); color: #F2F4F7; }
.ph-wealth .ph-label, .ph-wealth .ph-cap { color: rgba(242, 244, 247, .68); }
.ph-wealth .ph-num { color: #F2F4F7; }
.ph-wealth-num { font-size: 36px; margin: 6px 0 2px; }
.ph-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.ph-pair-v { font-size: 24px; margin: 6px 0 2px; }
.ph-tint-sky { background: var(--sky); }
.ph-tint-mint { background: var(--mint); }
.ph-tint-butter { background: var(--butter); }
.ph-tint-sky, .ph-tint-sky .ph-label, .ph-tint-sky .ph-cap, .ph-tint-sky .ph-num { color: var(--sky-on); }
.ph-tint-mint, .ph-tint-mint .ph-label, .ph-tint-mint .ph-cap, .ph-tint-mint .ph-num { color: var(--mint-on); }
.ph-tint-butter, .ph-tint-butter .ph-label, .ph-tint-butter .ph-cap, .ph-tint-butter .ph-num { color: var(--butter-on); }
.ph-tint-sky .ph-pos, .ph-tint-mint .ph-pos { color: var(--mint-on); font-weight: 700; }
.ph-tint-sky .ph-neg, .ph-tint-mint .ph-neg { color: var(--blush-on); font-weight: 700; }

/* Money */
.ph-search { display: flex; gap: 10px; align-items: center; background: var(--card); border-radius: 14px; padding: 4px 14px; color: var(--fg-3); box-shadow: var(--shadow); }
.ph-search svg { width: 17px; height: 17px; flex-shrink: 0; }
.ph-search input { border: none; background: transparent; color: var(--fg); font: 500 15px var(--ph-body); padding: 9px 0; width: 100%; min-width: 0; outline: none; }
.ph-seg { display: flex; background: var(--line); border-radius: 12px; padding: 3px; gap: 3px; }
.ph-seg button { flex: 1; min-width: 0; text-align: center; font-size: 13px; font-weight: 600; padding: 8px 2px; border-radius: 9px; border: none; background: transparent; color: var(--fg-2); cursor: pointer; }
.ph-seg button.ph-on { background: var(--card); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.ph-day { font-size: 12px; font-weight: 700; color: var(--fg-2); letter-spacing: .04em; margin: 6px 6px -4px; display: flex; justify-content: space-between; font-variant-numeric: tabular-nums; }
#ph-money-list { display: flex; flex-direction: column; gap: 12px; }
.ph-fab { position: fixed; right: 16px; bottom: calc(86px + env(safe-area-inset-bottom, 0px)); z-index: 90; background: var(--btn-primary-bg); color: var(--btn-primary-text); font-weight: 700; font-size: 15px; padding: 14px 22px; border-radius: 999px; border: none; box-shadow: var(--shadow-2); cursor: pointer; }
.ph-more { align-self: center; background: var(--card); border: 1px solid var(--line); color: var(--fg); font-weight: 600; font-size: 13px; padding: 10px 18px; border-radius: 999px; cursor: pointer; margin-top: 4px; }

/* Reports */
.ph-rep-num { font-size: 38px; margin: 6px 0 0; }
.ph-hbar { display: grid; grid-template-columns: minmax(0, 96px) 1fr auto; gap: 10px; align-items: center; font-size: 13px; margin-bottom: 11px; }
.ph-hbar:last-child { margin-bottom: 0; }
.ph-hbar-n { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ph-hbar-a { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ph-hbar .ph-bar { height: 10px; }
.ph-hbar .ph-bar span { background: var(--mint-mark); }
.ph-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 12px 14px; }
.ph-dates label { display: grid; gap: 4px; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); min-width: 0; }
.ph-dates input { font: 500 14px var(--ph-body); color: var(--fg); background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px; width: 100%; min-width: 0; }

/* Bottom bar */
.ph-nav { position: fixed; left: 0; right: 0; bottom: 0; z-index: 100; display: grid; grid-template-columns: repeat(5, 1fr); background: var(--card); border-top: 1px solid var(--line); padding: 8px 4px calc(10px + env(safe-area-inset-bottom, 0px)); }
.ph-nav-btn { display: flex; flex-direction: column; align-items: center; gap: 3px; font-size: 11px; font-weight: 600; color: var(--fg-3); background: none; border: none; padding: 0; cursor: pointer; }
.ph-nav-btn svg { width: 22px; height: 22px; }
.ph-nav-pad { padding: 4px 16px; display: grid; place-items: center; border-radius: 999px; }
.ph-nav-btn.ph-on { color: var(--fg); }
.ph-nav-btn.ph-on .ph-nav-pad { background: var(--btn-primary-bg); color: var(--btn-primary-text); }

@media (prefers-reduced-motion: no-preference) {
  .ph-item, .ph-nav-pad, .ph-seg button { transition: background-color .15s ease, color .15s ease; }
}


/* ── MAKEOVER COMPONENTS (2026-10) — used by B2+ ── */
/* Ported from the approved mockup (handover/design/makeover-mockup.html). Every class is prefixed
   `fm-` so nothing collides with the existing .t / .card / .btn / .chip families. No screen uses
   these yet (B1 is foundation only); B2+ adopts them screen by screen. Colours and sizes come from
   the tokens above, so light and dark follow automatically. */

.fm-n { font-family: var(--font-display); font-variant-numeric: tabular-nums lining-nums; font-optical-sizing: auto; }
.fm-muted { color: var(--fg-3); }
.fm-cap { font-size: var(--fs-label); color: var(--fg-3); }

/* card */
.fm-card { background: var(--card); border: 1px solid transparent; border-radius: var(--r); box-shadow: var(--shadow); min-width: 0; display: flex; flex-direction: column; }
@media (prefers-color-scheme: dark) { :root:not([data-appearance="light"]) .fm-card { border-color: var(--ink-line); } }
[data-appearance="dark"] .fm-card { border-color: var(--ink-line); }
.fm-card-h { display: flex; align-items: center; gap: 12px; padding: 18px 22px 12px; }
.fm-tt { font-size: var(--fs-card-title); font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); display: flex; align-items: center; gap: 8px; }
.fm-tt .sub { font-size: var(--fs-label); letter-spacing: 0; text-transform: none; color: var(--fg-3); font-weight: 500; }
.fm-ctl { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.fm-card-b { padding: 4px 22px 20px; min-width: 0; }
.fm-card-b.flush { padding: 0 0 6px; }
.fm-card-f { margin-top: auto; padding: 12px 22px; border-top: 1px solid var(--line-2); display: flex; align-items: center; gap: 12px; font-size: var(--fs-label); color: var(--fg-3); }

/* segmented control */
.fm-seg { display: inline-flex; background: var(--card-2); border: 1px solid var(--line); border-radius: 11px; padding: 3px; gap: 2px; }
.fm-seg button { border: 0; background: transparent; padding: 5px 11px; border-radius: 8px; font-size: var(--fs-label); font-weight: 600; color: var(--fg-3); font-family: inherit; cursor: pointer; }
.fm-seg button.on { background: var(--card); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.fm-seg button[disabled] { opacity: .45; cursor: default; }

/* chips */
.fm-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; font-size: var(--fs-label); font-weight: 600; white-space: nowrap; }
.fm-chip.mint { background: var(--mint); color: var(--mint-on); }
.fm-chip.sky { background: var(--sky); color: var(--sky-on); }
.fm-chip.lav { background: var(--lav); color: var(--lav-on); }
.fm-chip.blush { background: var(--blush); color: var(--blush-on); }
.fm-chip.butter { background: var(--butter); color: var(--butter-on); }
.fm-chip.plain { background: var(--card-2); color: var(--fg-2); border: 1px solid var(--line); }

/* KPI strip */
.fm-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }
.fm-kpi { padding: 18px 22px; border-left: 1px solid var(--line-2); min-width: 0; }
.fm-kpi:first-child { border-left: 0; }
.fm-kpi .lb { font-size: var(--fs-label); color: var(--fg-3); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.fm-kpi .v { font-size: var(--fs-fig-m); font-weight: 600; margin-top: 6px; line-height: 1.15; }
.fm-kpi .cap { font-size: var(--fs-label); color: var(--fg-3); margin-top: 4px; }

/* table */
.fm-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-body); }
.fm-table th { position: sticky; top: 0; background: var(--card); z-index: 1; text-align: left; font-size: var(--fs-label); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--fg-3); padding: 10px 14px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.fm-table td { padding: 11px 14px; border-bottom: 1px solid var(--line-2); white-space: nowrap; vertical-align: middle; }
.fm-table th:first-child, .fm-table td:first-child { padding-left: 22px; }
.fm-table th:last-child, .fm-table td:last-child { padding-right: 22px; }
.fm-table .fm-r { text-align: right; } /* not `.r`: the legacy .r list-row rule is display:flex and would break table cells */
.fm-table td.fm-n { font-size: var(--fs-body); }
.fm-table td.desc { white-space: normal; min-width: 180px; }
.fm-table tr.grp td { background: var(--card-2); font-size: var(--fs-label); font-weight: 600; color: var(--fg-2); padding-top: 9px; padding-bottom: 9px; }
.fm-table tr.grp td .fm-n { font-size: 15px; }
.fm-table tfoot td { border-bottom: 0; border-top: 1px solid var(--line); font-weight: 600; background: var(--card); }
.fm-table tbody tr:hover td { background: color-mix(in srgb, var(--card-2) 70%, transparent); }
.fm-table tr.grp:hover td { background: var(--card-2); }

/* bars (horizontal only — no rings) */
.fm-bar { position: relative; height: 10px; border-radius: 6px; background: var(--track); overflow: visible; }
.fm-bar > i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px; display: block; }
.fm-bar .pace { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--fg); border-radius: 1px; opacity: .75; }

/* ledger rows: name | bar | value */
.fm-ledger { display: grid; gap: 14px; }
.fm-lrow { display: grid; grid-template-columns: minmax(120px, 1.1fr) minmax(0, 2fr) auto; gap: 14px; align-items: center; }
.fm-lrow .nm { font-size: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px; min-width: 0; }
.fm-lrow .nm .tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-lrow .val { text-align: right; font-size: 15px; white-space: nowrap; }
.fm-lrow .val .fm-n { font-size: var(--fs-body); }
.fm-lrow .val .pct { display: inline-block; width: 3.2em; text-align: right; color: var(--fg-3); }

/* buttons, links, three-dot menu button, empty state */
.fm-btn { display: inline-flex; align-items: center; gap: 8px; border-radius: 12px; padding: 9px 16px; font-size: 15px; font-weight: 600; border: 1px solid var(--line); background: var(--card); color: var(--fg); white-space: nowrap; font-family: inherit; cursor: pointer; }
.fm-btn:hover { border-color: var(--fg-3); }
.fm-btn.primary { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.fm-btn.sm { padding: 6px 12px; font-size: var(--fs-label); border-radius: 10px; }
.fm-link { border: 0; background: none; color: var(--fg-2); font-size: var(--fs-label); font-weight: 600; display: inline-flex; align-items: center; gap: 4px; padding: 4px 6px; border-radius: 8px; font-family: inherit; cursor: pointer; }
.fm-link:hover { color: var(--fg); background: var(--card-2); }
.fm-dots { width: 32px; height: 32px; border-radius: 9px; border: 1px solid transparent; background: none; color: var(--fg-3); display: inline-grid; place-items: center; cursor: pointer; }
.fm-dots:hover { border-color: var(--line); color: var(--fg); background: var(--card); }
.fm-empty { padding: 28px 22px 30px; text-align: center; color: var(--fg-3); display: grid; gap: 10px; justify-items: center; }
.fm-empty .e1 { font-weight: 600; color: var(--fg); font-size: var(--fs-body); }

/* month board (the dark signature card) */
.fm-board { background: var(--board-bg); color: var(--ink-fg); border-radius: var(--r); padding: 26px 30px 24px; box-shadow: var(--shadow-2); border: 1px solid var(--ink-line); display: grid; gap: 22px; }
.fm-board .top { display: grid; grid-template-columns: minmax(0, 1.3fr) repeat(3, minmax(0, 1fr)); gap: 28px; align-items: end; }
.fm-board .lb { font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-fg-2); font-weight: 600; }
.fm-board .head { font-size: var(--fs-fig-xl); font-weight: 600; line-height: 1.05; margin-top: 8px; letter-spacing: -.01em; }
.fm-board .fig { font-size: var(--fs-fig-l); font-weight: 600; margin-top: 6px; }
.fm-board .cap { font-size: var(--fs-label); color: var(--ink-fg-2); margin-top: 6px; }
.fm-board .cap b { color: var(--ink-fg); font-weight: 600; }
.fm-board .stripttl { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; gap: 12px; }
.fm-board .stripttl .tt { font-size: 15px; color: var(--ink-fg); }
.fm-board .stripttl .tt .fm-n { font-size: 17px; }
.fm-strip { display: flex; height: 22px; border-radius: 7px; overflow: hidden; gap: 2px; background: #ffffff14; }
.fm-strip i { display: block; height: 100%; min-width: 3px; }
.fm-strip-legend { display: flex; flex-wrap: wrap; gap: 8px 26px; margin-top: 12px; font-size: 15px; color: var(--ink-fg-2); }
.fm-strip-legend b { color: var(--ink-fg); font-weight: 600; }

@media (max-width: 1280px) { .fm-board .top { grid-template-columns: 1fr 1fr; } }
@media (max-width: 900px) {
  .fm-kpis { grid-template-columns: 1fr 1fr; }
  .fm-kpi:nth-child(3) { border-left: 0; }
  .fm-board .top { grid-template-columns: 1fr; }
  .fm-lrow { grid-template-columns: 1fr auto; }
  .fm-lrow .fm-bar { grid-column: 1 / -1; order: 3; }
}


/* ── MAKEOVER B2 — DASHBOARD (2026-10) ── */
/* Added to the fm- family above. Everything reads from tokens, so light and dark follow. */
:root { --nec-unc: var(--fg-3); }

.fm-page { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 20px; margin-top: 4px; align-items: stretch; }
.fm-page > .c12 { grid-column: span 12; } .fm-page > .c8 { grid-column: span 8; } .fm-page > .c7 { grid-column: span 7; } .fm-page > .c6 { grid-column: span 6; } .fm-page > .c5 { grid-column: span 5; } .fm-page > .c4 { grid-column: span 4; }
@media (max-width: 1280px) { .fm-page > .c8, .fm-page > .c7, .fm-page > .c6, .fm-page > .c5, .fm-page > .c4 { grid-column: span 12; } }

.fm-big { font-size: var(--fs-fig-l); font-weight: 600; line-height: 1.1; }
.fm-split { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.fm-row { display: flex; align-items: center; gap: 10px; }
.fm-sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex: none; }
.fm-pos { color: var(--mint-mark); } .fm-neg { color: var(--blush-mark); }
.fm-tbl-wrap { overflow: auto; max-width: 100%; }
.fm-upper { text-transform: uppercase; letter-spacing: .06em; font-weight: 600; }

/* Category icon tile */
.fm-cat { display: flex; align-items: center; gap: 10px; }
.fm-ic { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex: none; }
.fm-ic svg { width: 16px; height: 16px; }
.fm-ic.mint { background: var(--mint); color: var(--mint-on); } .fm-ic.sky { background: var(--sky); color: var(--sky-on); }
.fm-ic.lav { background: var(--lav); color: var(--lav-on); } .fm-ic.blush { background: var(--blush); color: var(--blush-on); }
.fm-ic.butter { background: var(--butter); color: var(--butter-on); }

/* Month board extras */
.fm-board .head.pos { color: var(--ink-fg); }
.fm-strip-note { margin-top: 10px; font-size: var(--fs-label); color: var(--ink-fg-2); }
.fm-strip-note b { color: var(--ink-fg); font-weight: 600; }
.fm-board .fm-empty { color: var(--ink-fg-2); padding: 14px 0 6px; justify-items: start; text-align: left; }
.fm-board .fm-empty .e1 { color: var(--ink-fg); }

/* Income and spending chart + 3-month average panel */
.fm-chart { width: 100%; display: block; }
.fm-chart text { font-family: var(--font-sans); font-size: var(--fs-label); fill: var(--fg-3); }
.fm-chart .vlab { font-family: var(--font-display); font-size: var(--fs-label); fill: var(--fg-2); font-variant-numeric: tabular-nums; paint-order: stroke; stroke: var(--card); stroke-width: 5px; stroke-linejoin: round; }
.fm-legend { display: flex; gap: 16px; align-items: center; font-size: var(--fs-label); color: var(--fg-2); flex-wrap: wrap; }
.fm-legend span { display: inline-flex; align-items: center; gap: 6px; }

/* Needs you */
.fm-todo { display: grid; }
.fm-todo .it { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 12px 22px; border-top: 1px solid var(--line-2); }
.fm-todo .it:first-child { border-top: 0; }
.fm-todo .t1 { font-weight: 600; font-size: 15px; }
.fm-todo .t2 { font-size: var(--fs-label); color: var(--fg-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Floating row menu (the ⋮ button) */
.fm-menu { position: fixed; z-index: 700; background: var(--card); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-2); padding: 6px; min-width: 180px; }
.fm-menu button { display: flex; width: 100%; gap: 10px; align-items: center; border: 0; background: none; padding: 9px 12px; border-radius: 8px; font-size: 15px; text-align: left; color: var(--fg); font-family: inherit; cursor: pointer; }
.fm-menu button:hover { background: var(--card-2); }
.fm-menu button svg { width: 16px; height: 16px; }

/* Savings goals, emergency fund */
.fm-goalname { font-weight: 600; }
.fm-scale { position: relative; height: 18px; white-space: nowrap; font-size: var(--fs-label); color: var(--fg-3); }
.fm-scale span { position: absolute; }
.fm-bar.tall { height: 12px; }
.fm-bar .tick3 { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--fg); opacity: .35; border-radius: 1px; }

.fm-nwcard .fm-card-b { padding: 4px 22px 20px; }
.fm-aligned .fm-lrow { grid-template-columns: minmax(110px, 1.1fr) minmax(0, 2fr) 150px; }
@media (max-width: 900px) { .fm-aligned .fm-lrow { grid-template-columns: 1fr auto; } }
.fm-table .fm-dots { vertical-align: middle; }


/* ── MAKEOVER B3 — TRANSACTIONS AND REPORTS (2026-10) ── */
/* Filter bars: native selects and inputs drawn in the fm- family. */
.fm-filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding: 16px 22px; }
.fm-filters.fm-filters-sub { padding-top: 0; }
.fm-filters.fm-filters-tight { padding-top: 4px; padding-bottom: 14px; }
.fm-kpis.fm-kpis-top { border-top: 1px solid var(--line-2); }
.fm-sel { font: inherit; font-size: 15px; color: var(--fg-2); background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; min-height: 40px; box-sizing: border-box; }
.fm-sel:hover { border-color: var(--fg-3); }
.fm-sel:focus-visible { outline: 2px solid var(--fg-3); outline-offset: 1px; }
select.fm-sel { cursor: pointer; }
.fm-fl { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-label); font-weight: 600; color: var(--fg-3); }
.fm-search { position: relative; display: inline-flex; align-items: center; }
.fm-search > svg, .fm-search > i { position: absolute; left: 12px; width: 16px; height: 16px; color: var(--fg-3); pointer-events: none; }
.fm-search .fm-sel { padding-left: 36px; width: 230px; }
.fm-range { display: inline-flex; align-items: center; gap: 8px; }
.fm-range .fm-sel { width: 120px; }
.fm-seg button:focus-visible { outline: 2px solid var(--fg-3); outline-offset: 1px; }

/* The multi-select checkbox filters (shared with Budget) read larger and use the fm- tokens inside these bars */
.fm-filters .rep-mfilter-btn { width: auto; min-width: 150px; font-size: 15px; padding: 8px 12px; min-height: 40px; border-radius: 10px; background: var(--card); border: 1px solid var(--line); color: var(--fg-2); }
.fm-filters .rep-mfilter-btn:hover { border-color: var(--fg-3); background: var(--card); }
.fm-filters .rep-mfilter-btn.active { color: var(--fg); border-color: var(--fg); font-weight: 600; }
.fm-filters .rep-mfilter-btn i, .fm-filters .rep-mfilter-btn svg { width: 14px; height: 14px; }
.fm-filters .rep-mfilter-pop { background: var(--card); border: 1px solid var(--line); box-shadow: var(--shadow-2); min-width: 220px; max-height: 320px; }
.fm-filters .rep-mfilter-opt { font-size: 15px; padding: 7px 8px; color: var(--fg); }
.fm-filters .rep-mfilter-opt:hover { background: var(--card-2); }
.fm-filters .rep-mfilter-divider { border-top-color: var(--line); }
.fm-filters .rep-mfilter-empty { font-size: var(--fs-label); color: var(--fg-3); }

/* Rows that open an entry; the sticky header, the scrolling table and the net footer */
.fm-table tr.fm-clickrow { cursor: pointer; }
.fm-table th.fm-sortable { cursor: pointer; user-select: none; }
.fm-table th.fm-sortable:hover { color: var(--fg); }
.fm-sorti { width: 14px; height: 14px; vertical-align: -2px; }
.fm-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.fm-table td.fm-empty-cell { text-align: center; color: var(--fg-3); padding: 34px 22px; white-space: normal; }
/* Scrolls inside the card with the header fixed. No overscroll-behavior:contain here: with it, the mouse
   wheel stops at this box and never reaches the page (see the note by .overflow-x-auto.custom-scrollbar). */
.fm-tbl-wrap.fm-scroll { max-height: 600px; min-height: 240px; overscroll-behavior: auto; }
.fm-table tfoot td { position: sticky; bottom: 0; z-index: 1; }
.fm-card-f.fm-wrapfoot { flex-wrap: wrap; row-gap: 8px; }
.fm-card-f .fm-footnote { margin-left: auto; }


/* ── MAKEOVER B4 — BUDGET, INSURANCE, SUBSCRIPTIONS, DOCUMENTS, SETTINGS (2026-10) ── */
/* Reports chart: a hatched swatch for the "earlier months for comparison" legend entry. */
.fm-sw-hatch { background: repeating-linear-gradient(45deg, var(--fg-3) 0 2px, transparent 2px 5px); opacity: .7; }

/* Budget & goals */
.fm-kpibar { padding: 0 22px 18px; }
.fm-barcell { min-width: 150px; width: 22%; }
.fm-th-sub { font-size: var(--fs-label); font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--fg-3); }
.fm-amt-input { width: 120px; text-align: right; font-family: var(--font-display); font-variant-numeric: tabular-nums lining-nums; }
.fm-amt-input::-webkit-outer-spin-button, .fm-amt-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.fm-amt-input { -moz-appearance: textfield; }
.fm-mini { display: inline-flex; align-items: flex-end; gap: 3px; height: 26px; vertical-align: middle; margin-right: 6px; }
.fm-mini i { width: 9px; border-radius: 2px; background: var(--fg-3); opacity: .55; display: block; }
.fm-card-f .fm-link[aria-expanded] svg { transition: transform .15s ease; }
.fm-card-f .fm-link[aria-expanded="true"] svg { transform: rotate(180deg); }
.fm-table td .fm-cap { margin-top: 2px; }


/* Tabs inside a card (Insurance policies, Subscriptions' Freemium / Free) */
.fm-tabs { display: flex; gap: 4px; padding: 0 22px; border-bottom: 1px solid var(--line); overflow-x: auto; overflow-y: hidden; }
.fm-table tr.fm-dim td { opacity: .6; }
.fm-chip svg { width: 14px; height: 14px; }
.fm-tabs button { border: 0; background: none; padding: 12px 12px; font-size: 15px; font-weight: 600; color: var(--fg-3); border-bottom: 2px solid transparent; margin-bottom: -1px; font-family: inherit; cursor: pointer; white-space: nowrap; }
.fm-tabs button:hover { color: var(--fg); }
.fm-tabs button.on { color: var(--fg); border-bottom-color: var(--fg); }
.fm-tabs button:focus-visible { outline: 2px solid var(--fg-3); outline-offset: -2px; border-radius: 6px; }
.fm-tabs button .ct { font-size: var(--fs-label); color: var(--fg-3); margin-left: 6px; font-weight: 500; }

/* Loans: one panel per loan inside the Loans card */
.fm-loans-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); gap: 18px; }
.fm-loan { border: 1px solid var(--line); border-radius: var(--r-s); min-width: 0; display: flex; flex-direction: column; }
.fm-loan-h { display: flex; align-items: flex-start; gap: 12px; justify-content: space-between; padding: 16px 20px 6px; }
.fm-loan-name { font-weight: 650; font-size: 17px; }
.fm-loan-b { padding: 4px 20px 16px; display: grid; gap: 12px; }
.fm-loan-kpis { border-top: 1px solid var(--line-2); }
.fm-loan-kpis .fm-kpi { padding: 14px 20px; }
.fm-loan-kpis .fm-kpi .v { font-size: 20px; }
.fm-loan-f { margin-top: auto; padding: 12px 20px; border-top: 1px solid var(--line-2); font-size: var(--fs-label); color: var(--fg-3); display: grid; gap: 4px; }
.fm-loan-note { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

/* Add forms inside a Documents card, and the labelled fields they use */
.fm-card-f.fm-formfoot { display: grid; gap: 12px; align-items: start; }
.fm-fld { display: grid; gap: 6px; font-size: var(--fs-label); font-weight: 600; color: var(--fg-2); min-width: 0; }
.fm-fld .fm-sel { width: 100%; font-weight: 400; }
.fm-textarea { width: 100%; min-height: 96px; resize: vertical; font-family: inherit; line-height: 1.4; }

/* Settings: two columns of cards; every row is a label with a caption on the left, the control on the right */
.fm-setcols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
.fm-setcol { display: grid; gap: 20px; min-width: 0; }
@media (max-width: 1280px) { .fm-setcols { grid-template-columns: 1fr; } }
.fm-setrow { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 0; border-top: 1px solid var(--line-2); min-width: 0; }
.fm-setrow:first-child { border-top: 0; padding-top: 4px; }
.fm-setrow > div:first-child { min-width: 0; }
.fm-setrow .lbl { font-weight: 600; font-size: 15px; }
.fm-setrow .fm-cap { margin-top: 2px; }
.fm-setrow .ctl { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; flex: none; max-width: 52%; }
.fm-setrow .ctl .fm-sel { width: 200px; }
.fm-setrow.stack { flex-direction: column; align-items: stretch; gap: 12px; }
.fm-pinrow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 700px) {
  .fm-setrow { flex-direction: column; align-items: stretch; }
  .fm-setrow .ctl { max-width: none; justify-content: flex-start; }
  .fm-setrow .ctl .fm-sel { width: 100%; }
  .fm-pinrow { grid-template-columns: 1fr; }
}
.fm-btn.danger { color: var(--over); border-color: color-mix(in srgb, var(--over) 45%, var(--line)); }
.fm-btn.danger:hover { border-color: var(--over); }
.fm-seg button.appearance-opt.active { background: var(--card); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.fm-toggle { position: relative; display: inline-block; width: 44px; height: 24px; flex: none; }
.fm-toggle input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.fm-toggle input:checked + .toggle-switch-track { background: var(--warn); }
.fm-toggle input:focus-visible + .toggle-switch-track { outline: 2px solid var(--fg-3); outline-offset: 2px; }
.fm-smsresult { align-items: center; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; }
.fm-more summary { cursor: pointer; font-weight: 600; font-size: 15px; }
.fm-more ol { margin: 8px 0 0; padding-left: 20px; display: grid; gap: 4px; }


/* ── MAKEOVER B5 — INVESTMENTS AND WATCHLIST FRAME (2026-10) ── */
/* The old am- bento cards are gone; both screens are now .fm-page + fm- components. Everything reads
   from tokens, so light and dark follow. The chart canvases keep their old am- ids and classes. */
.am-page { padding: 0; }
.fm-seg button.active { background: var(--card); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.fm-seg button { display: inline-flex; align-items: center; gap: 6px; }
.fm-seg button svg { width: 15px; height: 15px; }
.fm-pl-sub { font-size: var(--fs-label); }
.fm-table td .am-logo { flex: none; }
.fm-table tfoot td { font-size: var(--fs-body); }

/* Investments header: connection state on the left, Sync / menu on the right */
.fm-invhead { grid-column: span 12; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.fm-invhead .st { display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 600; min-width: 0; flex-wrap: wrap; }
.fm-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--fg-3); flex: none; display: inline-block; }
.fm-dot.live { background: var(--ok); }
.fm-chartbox { height: 360px; min-height: 0; margin-top: 4px; }
.fm-chartbox .am-chart-empty { font-size: var(--fs-label); height: 100%; }

/* Allocation: one block per segment, name + value on top, bar underneath (the card is narrow) */
.fm-alloc { display: grid; gap: 16px; }
.fm-alloc-row { display: grid; gap: 7px; }
.fm-alloc-row .top { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.fm-alloc-row .nm { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; min-width: 0; }
.fm-alloc-row .nm .tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-alloc-row .val { font-size: 15px; white-space: nowrap; text-align: right; }
.fm-alloc-row .val .fm-n { font-size: var(--fs-body); }
.fm-alloc-row .val .pct { display: inline-block; width: 3.6em; text-align: right; color: var(--fg-3); }

/* The per-holding chart dialog */
.fm-dialog { position: fixed; inset: 0; z-index: 900; display: none; align-items: center; justify-content: center; padding: 16px; background: rgba(0,0,0,.4); }
.fm-dialog.open { display: flex; }
.fm-dialog-box { width: min(900px, 100%); max-height: calc(100vh - 32px); overflow: auto; box-shadow: var(--shadow-2); }
.fm-dlg-name { display: flex; align-items: center; gap: 10px; font-weight: 650; font-size: 17px; flex-wrap: wrap; }
.fm-dlg-price { font-size: var(--fs-fig-l); font-weight: 600; line-height: 1.1; margin-top: 6px; }
.fm-dialog .am-hero-delta, .fm-wl-head .am-hero-delta { font-size: 15px; font-weight: 600; margin-top: 2px; color: var(--fg-3); }
.fm-dialog .am-hero-delta.pos, .fm-wl-head .am-hero-delta.pos { color: var(--mint-mark); }
.fm-dialog .am-hero-delta.neg, .fm-wl-head .am-hero-delta.neg { color: var(--blush-mark); }
.fm-dialog .am-chart-empty { font-size: var(--fs-label); }

/* Watchlist: list on the left, chart panel on the right */
.fm-wl { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); align-items: start; }
.fm-wl-list { border-right: 1px solid var(--line-2); max-height: 820px; overflow-y: auto; min-width: 0; }
.fm-wl-listhead { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--line-2); position: sticky; top: 0; background: var(--card); z-index: 2; }
.fm-sym { display: grid; grid-template-columns: minmax(0, 1fr) auto 32px; gap: 10px; align-items: center; padding: 10px 12px 10px 20px; border-top: 1px solid var(--line-2); border-left: 3px solid transparent; cursor: pointer; }
.fm-sym:hover { background: color-mix(in srgb, var(--card-2) 70%, transparent); }
.fm-sym.on { background: var(--card-2); border-left-color: var(--fg); }
.fm-sym.dragging { opacity: .4; }
.fm-sym .nm { min-width: 0; }
.fm-sym-t { font-weight: 600; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-sym .px { text-align: right; }
.fm-sym-px { font-size: 16px; }
.fm-sym-rm { opacity: 0; width: 28px; height: 28px; }
.fm-sym:hover .fm-sym-rm, .fm-sym:focus-within .fm-sym-rm { opacity: 1; }
@media (hover: none) { .fm-sym-rm { opacity: 1; } }
.fm-wl-main { min-width: 0; }
.fm-wl-head { padding-left: 24px; padding-right: 24px; flex-wrap: wrap; }
.fm-wl-line { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.fm-wl-name { display: flex; align-items: center; gap: 12px; font-family: var(--font-display); font-size: 28px; font-weight: 600; line-height: 1.15; }
.fm-wl-nmtx { display: flex; flex-direction: column; min-width: 0; }
.fm-wl-nm1 { font-family: var(--font-display); font-size: 28px; font-weight: 600; line-height: 1.1; }
.fm-wl-price { font-size: 24px; font-weight: 600; }
.fm-wl-ctl { flex-wrap: wrap; justify-content: flex-end; }
.fm-wl-main > .fm-card-b { padding-left: 24px; padding-right: 24px; }
.fm-wl-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }
.fm-wl-canvas { min-height: 420px; width: 100%; }
.fm-wl-canvas .am-chart-empty, #am-tv-container .am-chart-empty { font-size: var(--fs-label); }
.fm-wl-range { margin-top: 18px; padding: 14px 16px; background: var(--card-2); border-radius: var(--r-s); border: 1px solid var(--line-2); display: grid; gap: 10px; }
.fm-wl-range .am-range-bar { background: var(--track); }

.fm-wl-box { background: var(--card-2); border: 1px solid var(--line-2); border-radius: var(--r-s); padding: 14px 16px; min-width: 0; }
#am-wl-alerts-wrap .fm-wl-box { margin-top: 16px; }
.fm-wl-boxh { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; font-size: var(--fs-card-title); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); }
.fm-wl-boxh span { display: inline-flex; align-items: center; gap: 6px; }
.fm-wl-boxh .fm-cap { text-transform: none; letter-spacing: 0; font-weight: 500; }
.fm-wl-boxh svg { width: 16px; height: 16px; }









.fm-piv-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.fm-piv { background: var(--card); border: 1px solid var(--line-2); border-radius: 10px; padding: 8px 10px; text-align: center; }
.fm-piv .fm-n { font-size: 15px; font-weight: 600; margin-top: 2px; }
.fm-piv.res .fm-cap { color: var(--blush-mark); }
.fm-piv.sup .fm-cap { color: var(--mint-mark); }
.fm-piv.mid .fm-cap { color: var(--fg-2); }
.fm-alert-form { display: flex; flex-wrap: wrap; gap: 8px; }
.fm-alert-form .fm-sel { flex: 1 1 180px; min-width: 0; }
.fm-alert-list { display: grid; gap: 4px; margin-top: 10px; }
.fm-alert-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; background: var(--card); border: 1px solid var(--line-2); border-radius: 10px; padding: 6px 6px 6px 12px; font-size: 15px; }
.fm-wl-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-top: 16px; }
.fm-wl-stat { background: var(--card-2); border: 1px solid var(--line-2); border-radius: var(--r-s); padding: 10px 14px; min-width: 0; }
.fm-wl-stat .fm-n { font-size: 16px; font-weight: 600; margin-top: 2px; }
@media (max-width: 1100px) { .fm-wl { grid-template-columns: 1fr; } .fm-wl-list { border-right: 0; border-bottom: 1px solid var(--line-2); max-height: 340px; } }
@media (max-width: 800px) {  .fm-wl-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .fm-wl-name, .fm-wl-nm1 { font-size: 22px; } .fm-wl-main > .fm-card-b, .fm-wl-head { padding-left: 16px; padding-right: 16px; } }
@media (max-width: 600px) {
  #screen-assets .fm-kpi { padding: 14px 16px; }
  #screen-assets .fm-kpi .v { font-size: 20px; }
  #screen-assets .fm-card-h { flex-wrap: wrap; row-gap: 8px; }
}
/* Allocation ends level with the chart card; a long list scrolls inside its own body (every segment stays listed). */
.fm-alloc-card { height: 0; min-height: 100%; }
.fm-alloc-card .fm-card-b { flex: 1; min-height: 0; overflow-y: auto; }
@media (max-width: 1280px) { .fm-alloc-card { height: auto; min-height: 0; } .fm-alloc-card .fm-card-b { max-height: 420px; flex: none; } }

/* Full site on a phone-width screen (2026-11): the laptop header's buttons and the card headers' controls
   were wider than the screen, so the page was laid out ~670px wide inside a 390px window and the right
   edge (12M/All buttons, "View all", the Category column) was cut off or pannable sideways. Let both wrap.
   Only applies below 768px; the real phone view hides this header entirely. */
@media (max-width: 767px) {
  #app-header { flex-wrap: wrap; height: auto; min-height: 54px; padding: 8px 12px; row-gap: 8px; }
  #app-header .hdr-month { display: none; }
  #app-header .hdr-search { flex: 1 1 150px; min-width: 0; }
  #app-header .hdr-search input { min-width: 0; width: 100%; }
  #app-header .backup-pill .bp-label { display: none; }
  .fm-card-h { flex-wrap: wrap; }
  .fm-card-h .fm-ctl { margin-left: 0; flex-wrap: wrap; max-width: 100%; }  /* Six period buttons in one strip (Transactions): scroll inside the strip instead of widening the page. */
  .fm-filters .fm-seg { max-width: 100%; overflow-x: auto; }
}

/* Shared in-app dialogs (utils/dialog.js): the destructive confirm button. Chip tokens, so it reads in light and dark. */
.btn.btn-danger { background: var(--bg-danger); color: var(--text-danger); }
.btn.btn-danger:hover { background: var(--bg-danger); filter: brightness(0.96); }

/* Loan cards: notes sit behind "More" (a native <details>, so it works with the keyboard and needs no script). */
.fm-loan-more summary { cursor: pointer; list-style: none; font-weight: 600; color: var(--fg-2); width: fit-content; }
.fm-loan-more summary::-webkit-details-marker { display: none; }
.fm-loan-more summary:hover { color: var(--fg); }
.fm-loan-more .m-less { display: none; }
.fm-loan-more[open] .m-more { display: none; }
.fm-loan-more[open] .m-less { display: inline; }
.fm-loan-more-b { margin-top: 8px; display: grid; gap: 8px; color: var(--fg-2); font-weight: 400; line-height: 1.5; }
.fm-loan-more-b p { margin: 0; }

/* Budget: an amount typed but not saved yet (2026-11-01) */
.fm-amt-input.fm-unsaved { border-color: var(--warn); box-shadow: 0 0 0 1px var(--warn); }
.fm-unsaved-note { color: var(--warn); margin-right: 10px; }

/* Insights screen (2026-11): read-only analysis. Colours from tokens only; nothing under 14px. */
.fm-ins-watch { list-style: none; margin: 0; padding: 2px 22px 18px; display: grid; gap: 10px; }
.fm-ins-watch li { display: flex; gap: 12px; align-items: flex-start; font-size: var(--fs-body); line-height: 1.5; }
.fm-ins-watch .dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--warn); margin-top: 8px; }
.fm-ins-calm { font-size: var(--fs-body); color: var(--fg-2); }
.fm-ins-sub { font-size: var(--fs-label); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 8px; }
.fm-ins-pad { padding: 14px 22px 4px; margin: 0; }
.fm-ins-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 36px; padding: 4px 22px 20px; }
.fm-ins-grid > div, .fm-ins-trio > div { min-width: 0; }
.fm-ins-grid .fm-table th:first-child, .fm-ins-grid .fm-table td:first-child { padding-left: 0; }
.fm-ins-grid .fm-table th:last-child, .fm-ins-grid .fm-table td:last-child { padding-right: 0; }
.fm-ins-trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px 36px; padding: 4px 22px 20px; }
.fm-ins-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.fm-ins-list li { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: var(--fs-body); }
.fm-ins-list li:last-child { border-bottom: 0; }
.fm-ins-list li > span:last-child { text-align: right; flex: none; }
.fm-ins-kitchen { display: grid; gap: 12px; }
.fm-ins-krow { display: grid; grid-template-columns: minmax(150px, 190px) minmax(0, 1fr) 110px; gap: 14px; align-items: center; }
.fm-ins-krow .nm { font-size: 15px; font-weight: 600; }
.fm-ins-krow .val { text-align: right; font-size: var(--fs-body); }
.fm-stack { display: flex; gap: 2px; height: 16px; border-radius: 6px; overflow: hidden; background: var(--track); }
.fm-stack i { display: block; height: 100%; min-width: 2px; }
.fm-sg0 { background: var(--accent-blue); } .fm-sg1 { background: var(--accent-forest); } .fm-sg2 { background: var(--accent-amber); }
.fm-sg3 { background: var(--accent-plum); } .fm-sg4 { background: var(--accent-coral); } .fm-sg5 { background: var(--fg-3); opacity: .6; }
.fm-ins-legend { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 18px; font-size: var(--fs-label); color: var(--fg-2); }
.fm-ins-lg { display: inline-flex; align-items: center; gap: 8px; }
.fm-ins-lg i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.fm-ins-lg b { color: var(--fg); font-weight: 600; }
@media (max-width: 900px) {
  .fm-ins-grid, .fm-ins-trio { grid-template-columns: 1fr; }
  .fm-ins-krow { grid-template-columns: 1fr auto; }
  .fm-ins-krow .fm-stack { grid-column: 1 / -1; order: 3; }
}

/* Upcoming bills: a long bill name wraps onto a second line instead of pushing the table sideways (2026-11-01).
   The name column takes the spare width; due, amount, status and actions stay on one line. */
.fm-table td.fm-bill-name { white-space: normal; width: 100%; min-width: 150px; }
.fm-table td.fm-bill-name .fm-cat > div { overflow-wrap: anywhere; line-height: 1.3; }

/* Insights, visual version (2026-11-01). Big numbers, colour and charts first; tables open from "See the numbers".
   Colours from tokens only; nothing under 14px. Approved mockup: handover/design/insights-visual-mockup.html */
.fm-page > .c3 { grid-column: span 3; }
#screen-insights .fm-iv-intro { grid-column: span 12; margin: 0; color: var(--fg-3); font-size: var(--fs-body); }
.fm-iv-lb { font-size: var(--fs-label); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--fg-3); }
.fm-iv-big { font-size: 38px; line-height: 1.1; font-weight: 600; margin: 8px 0 8px; overflow-wrap: anywhere; color: var(--fg); }
.fm-iv-big .u { font-size: 18px; font-weight: 500; color: var(--fg-2); }
.fm-iv-big-s { font-size: 30px; }
.fm-iv-tile { padding-top: 20px; padding-bottom: 20px; }
.fm-iv-cap, .fm-iv-cap2 { color: var(--fg-3); font-size: var(--fs-label); margin-top: 8px; line-height: 1.4; }
.fm-iv-cap2 { margin-top: 12px; }
.fm-iv-sent { color: var(--fg-2); font-size: var(--fs-body); line-height: 1.45; }
.fm-iv-spark { display: flex; align-items: flex-end; gap: 5px; height: 34px; margin-top: 14px; }
.fm-iv-spark > i { flex: 1; background: var(--track); border-radius: 3px; display: block; }
.fm-iv-spark > i.now { background: var(--fg); }
.fm-iv-spark.big { height: 44px; }
.fm-iv-spark.big > i.hot { background: var(--over); }
/* "Look at this" cards: a coloured left edge says how much attention each one wants. */
.fm-card.fm-iv-look { border-left: 5px solid var(--line); }
.fm-card.fm-iv-look.bad { border-left-color: var(--over); }
.fm-card.fm-iv-look.warn { border-left-color: var(--warn); }
.fm-card.fm-iv-look.good { border-left-color: var(--ok); }
.fm-iv-look-b { display: flex; flex-direction: column; flex: 1; padding-top: 20px; padding-bottom: 20px; }
.fm-iv-look-b .fm-iv-foot { margin-top: auto; padding-top: 6px; }
.fm-iv-hbs { margin-top: 14px; display: grid; gap: 8px; }
.fm-iv-hb { display: grid; grid-template-columns: minmax(78px, 120px) minmax(0, 1fr) auto; gap: 10px; align-items: center; font-size: var(--fs-body); }
.fm-iv-hb .trk { height: 14px; background: var(--card-2); border: 1px solid var(--line-2); border-radius: 5px; overflow: hidden; display: block; }
.fm-iv-hb .trk i { display: block; height: 100%; border-radius: 4px; }
.fm-iv-hb .v { font-weight: 600; text-align: right; min-width: 52px; }
.fm-iv-prog { margin-top: 16px; }
.fm-iv-prog .tr { height: 10px; border-radius: 6px; background: var(--track); overflow: hidden; }
.fm-iv-prog .tr i { display: block; height: 100%; border-radius: 6px; }
.fm-iv-prog .ax { display: flex; justify-content: space-between; color: var(--fg-3); font-size: var(--fs-label); margin-top: 6px; }
.fm-iv-more { margin-top: 14px; border: 0; background: none; padding: 6px 0; font: inherit; font-size: var(--fs-label); font-weight: 600; color: var(--sky-mark); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.fm-iv-more:hover { text-decoration: underline; }
.fm-iv-more:focus-visible { outline: 2px solid var(--fg-2); outline-offset: 2px; border-radius: 6px; }
.fm-iv-more .chv { transition: transform var(--dur-base, .18s) ease; }
.fm-iv-more[aria-expanded="true"] .chv { transform: rotate(180deg); }
.fm-iv-foot .fm-iv-more { margin-top: 8px; }
/* The strips that hold the tables, directly under each row of cards. */
.fm-card.fm-iv-dp { padding-bottom: 6px; }
.fm-iv-dp[hidden], .fm-iv-detail[hidden] { display: none; }
.fm-iv-detail + .fm-iv-detail { border-top: 1px solid var(--line-2); margin-top: 10px; }
/* Savings chart: geometry is real. The plot box is the one box both the bars and the goal line are measured in. */
.fm-iv-chart { display: grid; grid-template-columns: 62px minmax(0, 1fr); column-gap: 8px; margin-top: 30px; }
.fm-iv-chart .gut { position: relative; height: 210px; }
.fm-iv-chart .gut span { position: absolute; right: 0; transform: translateY(50%); font-size: var(--fs-label); color: var(--fg-3); white-space: nowrap; }
.fm-iv-chart .plot { position: relative; height: 210px; border-bottom: 1px solid var(--line); }
.fm-iv-chart .goal { position: absolute; left: 0; right: 0; border-top: 2px dashed var(--fg-3); opacity: .7; }
.fm-iv-chart .cols { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 14px; padding: 0 6px; }
.fm-iv-chart .col { position: relative; height: 100%; }
.fm-iv-chart .b { position: absolute; bottom: 0; left: 50%; width: 100%; max-width: 62px; transform: translateX(-50%); border-radius: 7px 7px 0 0; box-sizing: border-box; }
.fm-iv-chart .b.part { opacity: .55; border: 2px dashed; border-bottom: 0; }
.fm-iv-chart .v { position: absolute; left: 0; right: 0; text-align: center; font-weight: 700; font-size: 15px; z-index: 1; }
.fm-iv-chart .mons { display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 14px; padding: 8px 6px 0; color: var(--fg-3); font-size: var(--fs-label); text-align: center; line-height: 1.25; }
/* Where each Rs 100 went */
.fm-iv-split { display: flex; height: 44px; border-radius: 10px; overflow: hidden; margin: 8px 0 14px; background: var(--track); }
.fm-iv-split > div { display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 15px; min-width: 0; }
.fm-iv-split .sf, .fm-iv-leg .sf { background: var(--chart-expense); }
.fm-iv-split .sd, .fm-iv-leg .sd { background: var(--accent-plum); }
.fm-iv-split .sk, .fm-iv-leg .sk { background: var(--ok); }
.fm-iv-leg { display: grid; gap: 8px; font-size: var(--fs-body); }
.fm-iv-leg span { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 8px; vertical-align: -1px; }
.fm-iv-over { display: inline-block; background: var(--blush); color: var(--blush-on); border-radius: 10px; padding: 8px 14px; font-weight: 700; font-size: var(--fs-body); margin-bottom: 14px; }
/* What moved: red bars to the right (more), green to the left (less). */
.fm-iv-axis, .fm-iv-mv { display: grid; grid-template-columns: minmax(96px, 160px) minmax(0, 1fr) minmax(0, 1fr) 62px; align-items: center; gap: 10px; }
.fm-iv-axis { color: var(--fg-3); font-size: var(--fs-label); margin: 4px 0; }
.fm-iv-axis .a1 { text-align: right; }
.fm-iv-mv { padding: 7px 0; font-size: var(--fs-body); }
.fm-iv-mv .nm { overflow-wrap: anywhere; line-height: 1.25; }
.fm-iv-mv .l { display: flex; justify-content: flex-end; }
.fm-iv-mv .r { display: flex; border-left: 2px solid var(--line); }
.fm-iv-mv .bar { display: block; height: 16px; border-radius: 4px; }
.fm-iv-mv .pc { font-weight: 700; text-align: right; font-size: var(--fs-body); }
/* Needs vs wants, Kitchen: one stacked bar per month */
.fm-iv-nrow { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center; margin: 10px 0; font-size: var(--fs-body); }
.fm-iv-nrow .mo { color: var(--fg-3); }
.fm-iv-nrow b { min-width: 56px; text-align: right; }
.fm-iv-stk { display: flex; gap: 2px; height: 24px; border-radius: 6px; overflow: hidden; background: var(--track); }
.fm-iv-stk > i { display: block; height: 100%; min-width: 2px; }
.nc-ess { background: var(--nec-ess); } .nc-non { background: var(--nec-non); } .nc-extra { background: var(--nec-extra); }
.nc-grow { background: var(--nec-grow); } .nc-unc { background: var(--fg-3); opacity: .6; }
.fm-iv-duo { display: flex; gap: 36px; flex-wrap: wrap; margin: 4px 0 18px; }
.fm-iv-duo .fm-iv-big { margin-bottom: 8px; }
@media (max-width: 1280px) {
  #screen-insights .fm-page > .c3 { grid-column: span 6; }
  #screen-insights .fm-page > .c4 { grid-column: span 4; }
  #screen-insights .fm-page > .c8, #screen-insights .fm-page > .c7, #screen-insights .fm-page > .c5, #screen-insights .fm-page > .c6 { grid-column: span 12; }
  #screen-insights .fm-page > #ins-per100-card { grid-column: span 12; }
}
@media (max-width: 1000px) { #screen-insights .fm-page > .c4 { grid-column: span 12; } }
@media (max-width: 600px) {
  #screen-insights .fm-page > .c3 { grid-column: span 12; }
  .fm-iv-big { font-size: 34px; }
  .fm-iv-chart { grid-template-columns: 56px minmax(0, 1fr); }
  .fm-iv-chart .cols, .fm-iv-chart .mons { gap: 6px; padding: 0 2px; }
  .fm-iv-chart .mons { padding-top: 8px; }
  .fm-iv-axis, .fm-iv-mv { grid-template-columns: 92px minmax(0, 1fr) minmax(0, 1fr) 54px; gap: 6px; }
  .fm-iv-nrow { grid-template-columns: 36px minmax(0, 1fr) auto; gap: 8px; }
  .fm-iv-hb { grid-template-columns: 84px minmax(0, 1fr) auto; }
}
