/* ===== Ascend — net worth, calmly tracked. Cream + forest-green aesthetic ===== */
/* Base theme is a warm dark; the light theme below is the brand's primary look
   (cream paper + forest green), matching the app icon. */
:root {
  /* Dark mode is the brand in a different lighting — a warm forest near-black, not
     a cool neutral charcoal. Surfaces lean green-brown so the cream/forest identity
     survives at night. */
  --bg: #14160e;
  --surface: #1c1f15;
  --surface-2: #262a1d;
  --hover: rgba(255,255,255,.045);
  --active: rgba(255,255,255,.09);
  --shadow-color: 0,0,0;    /* dark mode: neutral black shadows */
  --line: rgba(255,255,255,.085);
  --line-strong: rgba(255,255,255,.15);
  --text: #f0efe6;
  --muted: #9ba293;
  --muted-2: #8b9080;       /* ~5:1 on the dark bg — WCAG AA (was #767d73, ~4.3:1) */
  --accent: #49a679;        /* forest green, lifted for dark legibility (was minty #4caf82) */
  --accent-soft: rgba(73,166,121,.16);
  --positive: #5cc78d;      /* gains/up — brighter than brand so directional change pops */
  --red: #e8675a;
  --red-soft: rgba(232,103,90,.16);
  --warn: #d99a2b;          /* caution/amber (e.g. mid Monte-Carlo success) — ~7.6:1 on dark */
  --skel: #262a1d;
  --skel-hi: #333829;
  --radius: 22px;
  --radius-sm: 14px;
  --ease: cubic-bezier(.22,.61,.36,1);
  /* Clearance above the fixed tab bar — one source for the FAB / coachmark / toast
     bottom offsets so they no longer drift as three hand-tuned magic numbers. */
  --tabbar-h: 64px;
}
[data-theme="light"] {
  --bg: #f3eee3;            /* warm cream paper */
  --surface: #fbf9f2;       /* ivory cards */
  --surface-2: #eae3d4;     /* warm tan tiles / tracks */
  --hover: rgba(40,52,40,.045);
  --active: rgba(40,52,40,.08);
  --shadow-color: 31,42,35;  /* light mode: forest-ink shadows, never pure black on cream */
  --line: rgba(40,52,40,.10);
  --line-strong: rgba(40,52,40,.17);
  --text: #1f2a23;          /* deep forest charcoal */
  /* Muted/semantic tokens are deepened so they clear WCAG AA (4.5:1) on the TAN
     --surface-2 tiles (.stat/.kstat/.rd-stat), not just on the lighter cream --bg —
     the tan tiles dropped the prior values to ~4.1:1. */
  --muted: #5d6753;         /* ~4.7:1 on the tan tiles, ~5.1:1 on cream */
  --muted-2: #5a6450;       /* ~4.9:1 on tan tiles */
  --accent: #2a6f53;        /* forest green — ~4.7:1 on tan tiles, AA for text */
  --accent-soft: rgba(42,111,83,.14);
  --positive: #237046;      /* gains/up — distinct from brand; ~4.8:1 on tan tiles */
  --red: #af4029;           /* warm terracotta-red — ~4.6:1 on tan tiles */
  --red-soft: rgba(175,64,41,.10);
  --warn: #855c0f;          /* caution/amber — deep ochre, ~4.6:1 on the tan tiles */
  --skel: #e7e0d2;
  --skel-hi: #f5f1e8;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-feature-settings: "ss01", "cv01";
  /* Tabular figures app-wide so every stacked number column (stats, returns, P/E grid,
     reconciliation, holdings) aligns digit-for-digit instead of wobbling. */
  font-variant-numeric: tabular-nums;
}
::selection { background: var(--accent-soft); }
/* Visually hidden but available to assistive tech (offscreen live regions, etc.). */
.sr-only { position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }

/* Horizontal insets keep content clear of the notch in landscape; the large
   bottom inset clears the fixed tab bar + floating Sync pill + home indicator. */
.wrap { max-width: 880px; margin: 0 auto; padding: 22px max(20px, env(safe-area-inset-right)) calc(116px + env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); }

/* ---------- top bar ---------- */
/* padding-top absorbs the iOS status bar / Dynamic Island so the brand row
   never sits under it (the bar's var(--bg) fills the inset area). */
/* Pin to its OWN compositor layer (same trick the .tabbar uses). Without it, iOS
   caches this sticky bar's painted background in the main scroll layer and does NOT
   invalidate it when --bg flips on a light/dark toggle — so the bar keeps the OLD
   theme colour as a strip across the top (incl. the safe-area inset) until a scroll
   forces a repaint. On its own layer, the theme-flip style recalc repaints it at once. */
header.topbar { display:flex; align-items:center; justify-content:space-between; gap:14px; margin-bottom:30px; position:sticky; top:0; z-index:40; background:var(--bg); padding:calc(12px + env(safe-area-inset-top)) 0 12px; transform:translate3d(0,0,0); will-change:transform; -webkit-backface-visibility:hidden; }
header.topbar.scrolled { border-bottom:1px solid var(--line); }
.brand { display:flex; align-items:center; gap:11px; min-width:0; background:none; border:none; padding:0; margin:0; font:inherit; color:inherit; cursor:pointer; text-align:left; }
.brand:active { transform:scale(.98); }
/* Net worth slides into the header once the hero scrolls out of view. */
.nav-nw { font-size:16px; font-weight:600; letter-spacing:-.01em; font-variant-numeric:tabular-nums; opacity:0; max-width:0; overflow:hidden; white-space:nowrap; transition:opacity .2s var(--ease); }
header.topbar.scrolled .nav-nw { opacity:1; max-width:200px; }
header.topbar.scrolled .brand h1 { display:none; }
.logo {
  width:34px; height:34px; border-radius:10px; overflow:hidden;
  display:grid; place-items:center; flex:none;
  /* Forest tile + cream "summit" mark — a brand constant in both themes, matching
     the home-screen icon (so the in-app mark and the app icon are the same mark). */
  background:#2c7457; color:#f3eee3;
}
.logo img { width:100%; height:100%; object-fit:cover; display:block; }
.logo svg { width:58%; height:58%; display:block; }
.brand h1 { font-size:16px; margin:0; font-weight:600; letter-spacing:-.01em; }
.brand p { display:none; }
.topbar-actions { display:flex; gap:6px; align-items:center; }

/* buttons */
/* Inherit the theme text color: <button> defaults to the UA color (near-black),
   which reads fine on cream but is unreadable on dark surfaces. Buttons that need
   a specific color (.btn-primary, .seg button, …) set their own and override this.
   Without it, content-style buttons (.rundown-card, .rd-hold) go black in dark mode. */
button { font:inherit; color:inherit; cursor:pointer;
  /* Scope the transition to the properties that animate, not `all` — animating `all`
     eased JS-toggled state classes (hidden, active) in unintended ways. */
  transition-property: color, background-color, border-color, transform, filter, box-shadow, opacity;
  transition-duration:.18s; transition-timing-function:var(--ease); }
.btn-primary {
  background:var(--accent); color:#00210f; border:none; font-weight:600; font-size:14px;
  padding:11px 18px; border-radius:999px; display:inline-flex; align-items:center; gap:7px;
}
[data-theme="light"] .btn-primary { color:#fff; }
.btn-primary:hover { filter:brightness(1.08); }
.btn-primary:disabled { opacity:.4; cursor:default; filter:none; }
.btn-ghost {
  background:transparent; color:var(--text); border:1px solid var(--line-strong);
  padding:9px 14px; border-radius:999px; font-size:13px; display:inline-flex; align-items:center; gap:7px;
}
.btn-ghost:hover { background:var(--hover); border-color:var(--text); }
.icon-only { width:38px; height:38px; padding:0; justify-content:center; border-radius:999px; }
.btn-danger { color:var(--red); border:1px solid transparent; background:transparent; padding:9px 14px; border-radius:999px; }
.btn-danger:hover { border-color:var(--red); }

/* Unified connect picker */
.connect-list { display:flex; flex-direction:column; gap:6px; max-height:46vh; overflow:auto; margin:4px 0 2px; }
.connect-row { display:flex; align-items:center; gap:12px; width:100%; text-align:left; background:var(--surface-2); border:1px solid transparent; border-radius:var(--radius-sm); padding:10px 12px; cursor:pointer; font-size:14px; color:var(--text); }
.connect-row:hover { background:var(--hover); border-color:var(--line); }
.connect-row .clogo { width:30px; height:30px; border-radius:8px; object-fit:contain; background:#fff; flex:none; }
.connect-row .cfallback { width:30px; height:30px; border-radius:8px; flex:none; display:flex; align-items:center; justify-content:center; background:var(--surface); color:var(--muted); font-size:14px; }
.connect-row .cname { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.connect-row .cvia { font-size:11px; color:var(--muted-2); flex:none; }
.connect-row.cother { background:transparent; border:1px dashed var(--line); margin-top:2px; }
.connect-row.cother:hover { background:var(--hover); }
.connect-row.cother .cfallback { background:transparent; }
/* Pro-locked upsell row in the connect picker (free users). */
.connect-row.cupsell { background:var(--accent-soft); border:1px solid transparent; margin-top:2px; }
.connect-row.cupsell:hover { border-color:var(--accent); }
.connect-row.cupsell .cvia { color:var(--accent); font-weight:600; }
.connect-row.cupsell .cfallback { background:transparent; }

.inv-code { font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:15px; font-weight:600; letter-spacing:.04em; color:var(--accent); }

/* RentCast property list (inside the Properties modal) */
.prop-list { display:flex; flex-direction:column; gap:8px; margin:4px 0 6px; }
.prop-list:empty { display:none; }
.prop-row { display:flex; align-items:center; gap:10px; background:var(--surface-2); border-radius:var(--radius-sm); padding:10px 12px; }
.prop-row .prop-addr { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; cursor:pointer; }
.prop-row .prop-addr:hover { opacity:.8; }
.prop-row .prop-addr > :first-child, .prop-row .prop-addr { font-size:14px; }
.prop-meta { font-size:12px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.prop-meta.dim { font-style:italic; opacity:.85; }
.prop-row .prop-del { color:var(--muted); border:none; background:transparent; font-size:18px; line-height:1; padding:2px 6px; border-radius:8px; align-self:flex-start; }
.prop-row .prop-del:hover { color:var(--red); background:var(--hover); }
.prop-row .prop-reconnect { flex:none; align-self:center; white-space:nowrap; border:none; background:var(--accent); color:#00210f; font:inherit; font-size:13px; font-weight:600; padding:7px 12px; border-radius:9px; cursor:pointer; }
[data-theme="light"] .prop-row .prop-reconnect { color:#fff; }
.prop-row .prop-reconnect:hover { filter:brightness(1.05); }
.prop-row .prop-retry { flex:none; align-self:center; white-space:nowrap; border:1px solid var(--line-strong);
  background:transparent; color:var(--text); font:inherit; font-size:12px; font-weight:600; padding:6px 9px; border-radius:9px; cursor:pointer; }
.manage-subtitle { margin:18px 0 8px; font-size:12px; font-weight:650; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; }
.reconciliation-list { display:flex; flex-direction:column; gap:7px; }
.recon-row { display:grid; grid-template-columns:1fr auto; gap:3px 12px; padding:10px 12px; border-radius:var(--radius-sm); background:var(--surface-2); }
.recon-name { font-size:13px; font-weight:600; }
.recon-net { font-size:14px; font-weight:650; }
.recon-meta { grid-column:1 / -1; font-size:11px; color:var(--muted); }
.history-import-actions, .scenario-actions { display:flex; gap:7px; flex-wrap:wrap; }
.prop-refresh-bar { display:flex; align-items:center; gap:10px; margin-top:10px; }
.prop-refresh-bar .btn-ghost:disabled { opacity:.5; cursor:not-allowed; }
.prop-refresh-note { font-size:12px; color:var(--muted); }

/* ---------- hero ---------- */
.hero { text-align:left; margin-bottom:30px; }
.metric-label { color:var(--muted); font-size:14px; font-weight:500; letter-spacing:-.01em; }
.metric-value { font-size:clamp(44px, 9vw, 68px); font-weight:700; line-height:1.02; letter-spacing:-.03em; margin:6px 0 12px; }
.metric-sub { font-size:15px; color:var(--muted); display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.pill { display:inline-flex; align-items:center; gap:5px; font-size:15px; font-weight:600; }
.pill.up { color:var(--positive); }
.pill.down { color:var(--red); }
.pill .dim { color:var(--muted); font-weight:500; }

/* small stat tiles */
.stats { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:30px; }
.stat {
  background:var(--surface-2); border-radius:var(--radius-sm); padding:16px 18px;
}
.stat-label { font-size:13px; color:var(--muted); }
.stat-value { font-size:22px; font-weight:650; margin-top:4px; letter-spacing:-.02em; }
.stat-value.green { color:var(--positive); }
.stat-value.red { color:var(--red); }
.stat-sub { font-size:12px; color:var(--muted-2); margin-top:3px; }

/* ---------- sections ---------- */
.section { margin-bottom:34px; }
.section-head { display:flex; align-items:center; justify-content:space-between; margin:0 0 14px; gap:12px; }
.section-head h2 { font-size:19px; font-weight:600; margin:0; letter-spacing:-.02em; }
.section-head .hint { color:var(--muted); font-size:13px; }
.trend-meta { display:inline-flex; align-items:center; gap:12px; }

.chartbox { width:100%; height:200px; }
svg#lineChart { display:block; width:100%; height:100%; overflow:visible; }
.axis-label { fill:var(--muted-2); font-size:11px; }

.empty { color:var(--muted); font-size:14px; text-align:center; padding:34px 16px; }

/* Boot load-failure / retry state — never strand the user on infinite skeletons. */
.load-error { min-height:62vh; display:flex; align-items:center; justify-content:center; padding:32px 24px; }
.load-error[hidden] { display:none; }
.load-error-card { text-align:center; max-width:320px; }
.load-error-ic { width:56px; height:56px; border-radius:16px; margin:0 auto 16px; display:grid; place-items:center; background:var(--red-soft); color:var(--red); }
.load-error-ic svg { width:26px; height:26px; }
.load-error-card strong { display:block; font-size:18px; font-weight:600; letter-spacing:-.02em; margin-bottom:6px; }
.load-error-card p { font-size:14px; line-height:1.5; color:var(--muted); margin:0 0 18px; }

/* Markets orientation/empty state — a primary tab must never paint blank. */
.markets-empty { text-align:center; padding:72px 24px; max-width:340px; margin:0 auto; }
.markets-empty[hidden] { display:none; }
.markets-empty-ic { width:58px; height:58px; border-radius:17px; margin:0 auto 18px; display:grid; place-items:center; background:var(--accent-soft); color:var(--accent); }
.markets-empty-ic svg { width:27px; height:27px; }
.markets-empty h2 { font-size:19px; font-weight:600; letter-spacing:-.02em; margin:0 0 8px; }
.markets-empty p { font-size:14px; line-height:1.5; color:var(--muted); margin:0; }

/* ---------- touch feedback + hit targets ---------- */
/* iOS has no :hover, so every tappable needs a pressed state. Buttons/pills compress;
   list rows highlight. (.tabbar-btn/.settings-row/.ai-fab/.brand already had theirs.) */
.btn-primary:active, .btn-ghost:active, .btn-danger:active, .icon-only:active,
.copilot-chip:active, .seg button:active, .connect-row:active, .earn-more:active,
.digest-cat-chip:active, .pill-btn:active,
.research-shelf-toggle:active, .proj-adjust-btn:active, .wrapped-nudge:active,
.btn-share:active, .research-chip:active, .scenario-del:active, .row-info:active { transform: scale(.97); }
.acct-row:active, .h-row:active, .earn-row.tappable:active, .news-item:active,
.prop-row:active, .rundown-card:active, .insight-card:active,
.defi-bk-row:active, .spend-month:active { background: var(--active); }
/* Expand small close/delete controls to a 44pt touch target (HIG min) without changing
   their look — an invisible centered ::before, same trick as .kstat-info.
   (.scenario-del is already position:absolute, so it's its own positioning context.) */
.overlay-x, .rundown-card-dismiss, .install-hint-close, .prop-row .prop-del { position: relative; }
.overlay-x::before, .rundown-card-dismiss::before, .install-hint-close::before,
.digest-x::before, .insight-close::before, .prop-row .prop-del::before, .scenario-del::before {
  content:""; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:44px; height:44px;
}

/* ---------- holdings ---------- */
.h-list { display:flex; flex-direction:column; }
.h-row {
  display:flex; align-items:center; gap:14px; padding:13px 4px;
  border-top:1px solid var(--line); transition:.15s var(--ease);
}
.h-row:first-child { border-top:none; }
.h-row:hover { background:var(--hover); }
/* Reserve a right gutter so the fixed icon FAB (right:16px, ~68px arc) never clips a
   right-aligned holding value AT REST — scroll-to-hide only covers the in-motion case.
   Scoped to holdings so Overview/Accounts rows are untouched. */
#holdingsList .h-row { padding-right:60px; }
.logo-wrap { position:relative; width:40px; height:40px; flex:none; border-radius:50%; overflow:hidden; }
.logo-fallback {
  position:absolute; inset:0; display:grid; place-items:center;
  color:#fff; font-size:14px; font-weight:700; letter-spacing:.2px;
}
.logo-img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; background:#fff; }
/* Stock/ticker brand logos (NOT institution logos) are square 100x100 images,
   and many are full-bleed wordmarks (SANDISK, LUMENTUM, Micron, AOI) whose text
   spans edge to edge. A circular mask clips those ends — the "too zoomed in /
   messed up" look. Render them as rounded squares instead so the whole mark
   shows; object-fit:contain keeps any rare non-square logo from cropping. */
.logo-wrap:not(.acct-logo) { border-radius:11px; }
.logo-wrap:not(.acct-logo) .logo-img { object-fit:contain; }
.cash-logo { background:var(--accent); color:#00210f; font-size:20px; font-weight:800; }
[data-theme="light"] .cash-logo { color:#fff; }
.h-main { flex:1; min-width:0; }
/* Ticker + company name share one line; the name takes the slack and truncates. */
.h-id { display:flex; align-items:baseline; gap:7px; min-width:0; }
.h-ticker { font-size:15px; font-weight:600; letter-spacing:-.01em; flex:none; }
.h-name { font-size:13px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; flex:1 1 auto; }
.h-right { text-align:right; flex:none; }
.h-value { font-size:15px; font-weight:600; letter-spacing:-.01em; }
.h-shares { font-size:13px; color:var(--muted); margin-top:2px; }
/* The live per-share price — the figure members watch closest. Full-contrast and
   tabular so it reads at a glance against the muted share count beside it. */
.h-price { color:var(--text); font-weight:600; font-variant-numeric:tabular-nums; }

/* ---------- breakdown ---------- */
.bar-row { margin-bottom:15px; }
.bar-top { display:flex; justify-content:space-between; font-size:14px; margin-bottom:7px; }
.bar-top .name { display:flex; align-items:center; gap:9px; color:var(--text); }
.dot { width:9px; height:9px; border-radius:50%; }
.bar-track { height:6px; background:var(--surface-2); border-radius:999px; overflow:hidden; }
.bar-fill { height:100%; border-radius:999px; transition:width .5s var(--ease); }

/* segmented control */
.seg { display:inline-flex; background:var(--surface-2); border-radius:999px; padding:3px; gap:2px; }
.seg button { border:none; background:transparent; padding:7px 15px; border-radius:999px; color:var(--muted); font-size:13px; font-weight:500; transition:.15s var(--ease); position:relative; }
/* 44pt tap target (HIG) without inflating the compact pill height — invisible centered expander. */
.seg button::before { content:""; position:absolute; left:0; right:0; top:50%; transform:translateY(-50%); height:44px; }
.seg button.active { background:var(--surface); color:var(--text); box-shadow:0 1px 4px rgba(0,0,0,.3); }
[data-theme="light"] .seg button.active { background:#fff; box-shadow:0 1px 3px rgba(var(--shadow-color),.12); }

/* ---------- accounts ---------- */
.acct-toolbar { display:flex; gap:12px; align-items:center; margin-bottom:8px; flex-wrap:wrap; }
.acct-toolbar h2 { font-size:19px; font-weight:600; margin:0; letter-spacing:-.02em; }
.acct-toolbar .spacer { flex:1; }
.acct-logo .logo-img { background:#fff; }
.acct-row {
  display:flex; align-items:flex-start; gap:14px; padding:14px 4px;
  border-top:1px solid var(--line); transition:.15s var(--ease); cursor:pointer;
}
.acct-row:hover { background:var(--hover); }
.acct-badge { width:40px; height:40px; border-radius:11px; flex:none; display:grid; place-items:center; font-size:15px; font-weight:700; color:#fff; }
.acct-main { flex:1; min-width:0; }
/* Name truncates; the SYNCED/DUPLICATE chips never shrink. */
.acct-name { font-size:15px; font-weight:600; display:flex; align-items:center; gap:8px; letter-spacing:-.01em; min-width:0; }
.acct-name-text { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.src-chip, .owner-chip { flex:none; }
/* Single, truncating line — freshness lives on .acct-sub below, so meta can't wrap. */
.acct-meta { font-size:13px; color:var(--muted); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.acct-sub { display:flex; align-items:center; gap:7px; font-size:12px; color:var(--muted-2); margin-top:4px; min-width:0; }
.acct-sub .acct-fresh { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.acct-right { text-align:right; flex:none; padding-top:1px; }
.acct-bal { font-size:15px; font-weight:600; letter-spacing:-.01em; }
.acct-bal.liability { color:var(--red); }
.src-chip { font-size:11px; padding:2px 7px; border-radius:999px; font-weight:700; letter-spacing:.05em; background:var(--accent-soft); color:var(--accent); }
.owner-chip { font-size:12px; font-weight:500; }
.acct-cat { font-size:12px; font-weight:600; color:var(--muted); }
.glyph-logo { display:grid; place-items:center; }
.glyph-logo svg { width:21px; height:21px; }
.veh-est-note { font-size:13px; color:var(--muted); margin-top:10px; line-height:1.45; min-height:1px; }
.veh-est-note b { color:var(--text); }
.veh-est-dim { color:var(--muted-2); font-style:italic; }

/* ---------- per-account freshness + cross-connector duplicate notice ---------- */
.acct-fresh { color:var(--muted-2); font-variant-numeric:tabular-nums; }
.acct-fresh.stale { color:var(--red); font-weight:600; }
.src-chip.dup { background:var(--red-soft); color:var(--red); }
.acct-row.is-dup { background:var(--red-soft); }
.dup-banner { display:flex; flex-direction:column; gap:8px; margin:2px 0 12px; }
.dup-row {
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  background:var(--red-soft); border:1px solid var(--line);
  border-left:3px solid var(--red); border-radius:var(--radius-sm); padding:12px 14px;
}
.dup-text { flex:1; min-width:200px; font-size:13px; line-height:1.45; }
.dup-text b { color:var(--text); }
.dup-sub { font-size:12px; color:var(--muted); margin-top:3px; }
.dup-actions { display:flex; gap:8px; flex-wrap:wrap; }
.dup-actions .btn-ghost { padding:7px 12px; font-size:13px; }
.dup-hide { color:var(--red); }
/* Headline "needs review" flag — shown under the net-worth number while a likely
   duplicate is unresolved, so the big number isn't silently trusted while inflated. */
.nw-review {
  display:inline-block; margin-top:8px; padding:6px 12px; border-radius:999px;
  background:var(--red-soft); border:1px solid var(--red); color:var(--text);
  font-size:12px; line-height:1.4; text-align:left; cursor:pointer; max-width:100%;
}
.nw-review[hidden] { display:none; }
.nw-review b { color:var(--red); }
.nw-review .nw-review-cta { color:var(--red); font-weight:600; text-decoration:underline; margin-left:2px; }
/* Small "high est." disclosure chip on RentCast real-estate rows. */
.acct-est { color:var(--muted); }
/* Admin funnel + cron heartbeat view. */
.funnel-cron { display:flex; align-items:center; gap:8px; font-size:13px; color:var(--muted); margin:4px 0 12px; }
.funnel-cron-dot { width:9px; height:9px; border-radius:50%; flex:none; background:var(--accent); }
.funnel-cron-dot.stale { background:var(--red); }
.funnel-list { display:flex; flex-direction:column; gap:2px; }
.funnel-row { display:flex; flex-wrap:wrap; justify-content:space-between; gap:12px; padding:7px 10px; border-radius:var(--radius-sm); }
.funnel-row:nth-child(odd) { background:var(--surface-2); }
.funnel-name { color:var(--muted); font-size:13px; }
.funnel-n { font-variant-numeric:tabular-nums; font-weight:600; }
/* Events that haven't fired this month still show (a 0 is informative) — just dimmed. */
.funnel-row.is-zero .funnel-name, .funnel-row.is-zero .funnel-n { opacity:.5; }
/* Per-event breakdown rows, indented under their parent (e.g. research_viewed → held/nonheld). */
.funnel-sub .funnel-name { padding-left:16px; font-size:12px; opacity:.75; }
.funnel-sub .funnel-name::before { content:"↳ "; opacity:.5; }
.funnel-sub .funnel-n { font-weight:500; opacity:.75; }

/* Shared per-row "what this tracks" affordance (funnel events + AI-spend features):
   a tap/hover (i) that reveals a one-line description. The hint sits inside the row
   at flex-basis:100% so it drops to its own line without disturbing nth-child stripes. */
.row-info { flex:none; appearance:none; -webkit-appearance:none; width:15px; height:15px; margin-left:6px;
  padding:0; border:1px solid var(--line); border-radius:50%; background:transparent; color:var(--muted-2);
  font:italic 700 10px/13px Georgia, "Times New Roman", serif; cursor:pointer; vertical-align:middle; }
.row-info:hover { border-color:var(--muted); color:var(--text); }
.row-hint { flex-basis:100%; margin-top:5px; padding-top:5px; border-top:1px dashed var(--line);
  font-size:12px; line-height:1.4; color:var(--muted); }
.row-hint[hidden] { display:none; }

/* ---------- admin: AI spend ---------- */
.spend-total { font-size:clamp(22px, 7vw, 28px); font-weight:700; letter-spacing:-.02em; margin-bottom:4px; }
.spend-total .spend-sub { font-size:12px; font-weight:500; color:var(--muted); letter-spacing:0; }
.spend-peruser { font-size:16px; font-weight:650; letter-spacing:-.01em; margin-bottom:6px; color:var(--text); font-variant-numeric:tabular-nums; }
.spend-peruser .spend-sub { font-size:12px; font-weight:500; color:var(--muted); letter-spacing:0; }
.spend-month { margin-left:auto; font:inherit; font-size:13px; color:var(--text); background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius-sm); padding:6px 10px; cursor:pointer; }
.spend-h { margin:16px 0 6px; font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--muted-2); }
.spend-rows { display:flex; flex-direction:column; gap:2px; }
.spend-row { display:flex; flex-wrap:wrap; align-items:baseline; gap:12px; padding:7px 10px; border-radius:var(--radius-sm); }
.spend-row:nth-child(odd) { background:var(--surface-2); }
.spend-name { flex:1; min-width:0; font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.spend-meta { flex:none; color:var(--muted-2); font-size:12px; font-variant-numeric:tabular-nums; }
.spend-usd { flex:none; font-weight:700; font-variant-numeric:tabular-nums; min-width:64px; text-align:right; }

/* ---------- brokerage sync ---------- */
.sync-card { background:var(--surface-2); border-radius:var(--radius-sm); padding:18px 20px; display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.sync-card .grow { flex:1; min-width:200px; }
.sync-card .status { font-size:13px; color:var(--muted); }
.sync-dot { display:inline-block; width:7px; height:7px; border-radius:50%; margin-right:7px; vertical-align:middle; }
.badge { font-size:12px; font-weight:600; color:var(--muted); }
.badge.on { color:var(--accent); }
.badge.on .sync-dot, .sync-dot.on { background:var(--accent); }
.badge.off .sync-dot, .sync-dot.off { background:var(--muted-2); }

/* ---------- modal → iOS bottom sheet on phones, centered card on wide screens ----------
   Open/close is still driven ONLY by toggling the "open" class on .overlay. */
.overlay{
  position:fixed; inset:0;
  background:rgba(0,0,0,.6);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  display:flex;                 /* always flex; visibility handled by opacity */
  z-index:70;                   /* above the tab bar (60) + Sync pill (61): a sheet covers them, iOS-style */
  align-items:flex-end;         /* phone: dock the sheet to the bottom */
  justify-content:center;
  opacity:0; pointer-events:none; visibility:hidden;
  transition:opacity .28s var(--ease), visibility 0s linear .28s;
}
[data-theme="light"] .overlay{ background:rgba(0,0,0,.3); }
.overlay.open{ opacity:1; pointer-events:auto; visibility:visible; transition:opacity .28s var(--ease), visibility 0s linear 0s; }

.modal{
  width:100%; max-width:none;
  background:var(--surface);
  border:1px solid var(--line); border-bottom:none;
  border-radius:24px 24px 0 0;
  padding:30px 26px calc(26px + env(safe-area-inset-bottom));
  overflow:auto; -webkit-overflow-scrolling:touch;
  position:relative;
  max-height:min(92vh, 92dvh);  /* stays scrollable when the keyboard shows */
  transform:translateY(100%);
  transition:transform .32s var(--ease); will-change:transform;
  box-shadow:0 -10px 40px rgba(var(--shadow-color),.45);
}
.overlay.open .modal{ transform:translateY(0); }
/* iOS-style grab handle (generated, so no markup changes) */
.modal::before{ content:""; position:absolute; top:9px; left:50%; width:38px; height:5px; margin-left:-19px; border-radius:999px; background:var(--line-strong); pointer-events:none; }
/* While dragging, JS sets an inline transform — suppress the transition so it tracks the finger 1:1. */
.modal.dragging{ transition:none; }
/* Top "grab" strip for the swipe-to-close drag. touch-action:none so a downward
   drag here tracks the finger instead of scrolling the sheet. Phones only. */
.sheet-grip{ position:absolute; top:0; left:0; right:0; height:46px; z-index:3; touch-action:none; cursor:grab; }
.sheet-grip:active{ cursor:grabbing; }
@media (min-width:560px){ .sheet-grip{ display:none; } }

@media (min-width:560px){
  .overlay{ align-items:center; padding:20px; }
  .modal{
    max-width:440px; border:1px solid var(--line); border-radius:26px;
    padding:26px; max-height:92vh; box-shadow:none;
    transform:none; transition:none; animation:pop .25s var(--ease);
  }
  .overlay:not(.open) .modal{ animation:none; }
  .overlay.open .modal{ transform:none; }
  .modal::before{ display:none; }
  [data-theme="light"] .modal{ box-shadow:0 24px 60px rgba(40,52,40,.18); }
}
@keyframes pop { from { opacity:0; transform:scale(.96) translateY(8px);} to { opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){
  .overlay, .modal{ transition:none !important; animation:none !important; }
  .sync-top.spinning svg, .reval-dot, .skel, .ptr.spinning .ptr-spinner{ animation:none !important; }
  /* Belt-and-suspenders: confettiBurst() already no-ops under reduced motion,
     but kill any bits that slip through (e.g. a mid-flight preference change). */
  .confetti-bit{ display:none !important; }
}
/* Match the team's reduced-motion discipline for transparency: swap every blur for a
   solid surface so the UI stays legible when the OS asks to reduce transparency. */
@media (prefers-reduced-transparency:reduce){
  .overlay{ -webkit-backdrop-filter:none; backdrop-filter:none; background:rgba(0,0,0,.78); }
  .tabbar{ -webkit-backdrop-filter:none; backdrop-filter:none; background:var(--bg); }
  .pro-lock{ -webkit-backdrop-filter:none; backdrop-filter:none; background:var(--surface); }
  [data-theme="light"] .pro-lock{ background:var(--surface); }
  .pro-teaser-blur{ filter:none; -webkit-filter:none; }
}
/* Strengthen separators and the focus ring when the OS asks for more contrast. */
@media (prefers-contrast:more){
  :root, [data-theme="light"]{ --line:var(--line-strong); }
  :focus-visible{ outline-width:3px; }
}
.modal h3 { margin:0 0 4px; font-size:21px; font-weight:600; letter-spacing:-.02em; }
.modal .sub { color:var(--muted); font-size:13px; margin-bottom:20px; line-height:1.4; }
.field { margin-bottom:15px; }
.field label { display:block; font-size:13px; color:var(--muted); margin-bottom:7px; }
/* font-size MUST be >=16px: iOS Safari auto-zooms the page when focusing any
   input smaller than that. */
input, select { width:100%; font:inherit; font-size:16px; padding:13px 14px; border-radius:13px; border:1px solid var(--line-strong); background:var(--surface-2); color:var(--text); transition:.15s var(--ease); }
input:focus, select:focus { outline:none; border-color:var(--accent); }
/* Global keyboard-focus ring: only on :focus-visible, so mouse/touch focus stays
   ring-free while keyboard (and a11y-tool) users get a clear, consistent target.
   The outline follows each element's own border-radius. Inputs get an accent
   border on :focus already; this adds a matching ring under keyboard nav. */
:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline:2px solid var(--accent); outline-offset:1px; }
.field-row { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.modal-actions { display:flex; gap:10px; justify-content:flex-end; margin-top:24px; align-items:center; }

/* ---------- first-run onboarding ---------- */
.onboard-list { list-style:none; margin:18px 0 4px; padding:0; display:flex; flex-direction:column; gap:16px; }
.onboard-list li { display:flex; gap:14px; align-items:flex-start; }
.onboard-ic { font-size:20px; line-height:1.2; flex:none; width:34px; height:34px; display:grid; place-items:center; background:var(--accent-soft); border-radius:11px; }
.onboard-list b { display:block; font-size:14px; font-weight:600; letter-spacing:-.01em; }
.onboard-list span { display:block; color:var(--muted); font-size:13px; line-height:1.45; margin-top:2px; }
#onboardOverlay .modal-actions .btn-primary { width:100%; justify-content:center; padding:14px; }

/* ---------- login ---------- */
.login-screen { position:fixed; inset:0; display:none; align-items:center; justify-content:center; padding:20px; z-index:80; background:var(--bg); }
.login-screen.open { display:flex; }
.login-card { width:100%; max-width:340px; text-align:center; }
.login-card .logo { margin:0 auto 20px; width:54px; height:54px; border-radius:16px; font-size:26px; }
.login-card h1 { margin:0 0 8px; font-size:24px; font-weight:600; letter-spacing:-.02em; }
.login-card p { color:var(--muted); font-size:14px; margin:0 0 22px; }
.login-card input { display:block; width:100%; text-align:center; padding:14px; border-radius:14px; margin-bottom:10px; }
.login-card .err { color:var(--red); font-size:13px; min-height:18px; margin-top:6px; }
.login-card .btn-primary { width:100%; justify-content:center; margin-top:8px; padding:14px; }
.login-card .auth-toggle { font-size:13px; color:var(--muted); margin:16px 0 0; }
.login-card .auth-toggle a { color:var(--accent); text-decoration:none; font-weight:600; }
.login-card .auth-toggle a:hover { text-decoration:underline; }
.auth-legal { font-size:12px; color:var(--muted); margin:14px 0 0; line-height:1.5; }
.auth-legal a { color:var(--accent); text-decoration:none; font-weight:600; }
.auth-legal a:hover { text-decoration:underline; }
.auth-consent { display:flex; width:100%; box-sizing:border-box; align-items:flex-start; gap:8px; font-size:13px; color:var(--muted); margin:4px 2px 2px; padding:0 2px; text-align:left; line-height:1.45; cursor:pointer; }
.auth-consent input { margin:2px 0 0; flex:0 0 auto; width:16px; height:16px; accent-color:var(--accent); }
.auth-consent span { flex:1 1 auto; }
.auth-consent a { color:var(--accent); text-decoration:none; font-weight:600; }
.auth-consent a:hover { text-decoration:underline; }

/* ---------- toast ---------- */
/* Sits above the bottom tab bar + floating Sync pill so it never hides behind them. */
.toast { position:fixed; bottom:calc(var(--tabbar-h) + 22px + env(safe-area-inset-bottom)); left:50%; transform:translateX(-50%) translateY(20px); background:var(--surface-2); border:1px solid var(--line-strong); padding:13px 20px; border-radius:999px; opacity:0; pointer-events:none; transition:.28s var(--ease); font-size:14px; z-index:90; box-shadow:0 8px 30px rgba(var(--shadow-color),.4); }
.toast.show { opacity:1; transform:translateX(-50%) translateY(0); }
[data-theme="light"] .toast { box-shadow:0 10px 30px rgba(40,52,40,.16); }

/* ---------- privacy mode (blur all amounts) ---------- */
#privacyBtn svg { width:18px; height:18px; display:block; }
body.private .metric-value,
body.private .stat-value,
body.private .pill,
body.private .h-value,
body.private .h-price,
body.private .acct-bal,
body.private .grp-sub,
body.private .amt {
  filter: blur(9px); -webkit-filter: blur(9px);
  user-select:none; pointer-events:none;
  transition: filter .2s var(--ease);
}
/* The whole trend chart (line + dollar axis labels) blurs as one unit. */
body.private .chartbox {
  filter: blur(10px); -webkit-filter: blur(10px);
  user-select:none; pointer-events:none;
  transition: filter .2s var(--ease);
}

/* ---------- grouped accounts (category subtotals) ---------- */
.grp-head { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:18px 4px 7px; }
.grp-head:first-child { padding-top:4px; }
.grp-name { display:flex; align-items:center; gap:8px; font-size:12px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--muted); }
.grp-name .dot { width:8px; height:8px; border-radius:50%; }
.grp-sub { font-size:13px; font-weight:600; color:var(--muted); font-variant-numeric:tabular-nums; }
.grp-head + .acct-row { border-top:none; }

/* ---------- skeleton shimmer loaders ---------- */
.skel { display:inline-block; background:linear-gradient(90deg, var(--skel) 25%, var(--skel-hi) 37%, var(--skel) 63%); background-size:400% 100%; animation:shimmer 1.4s ease infinite; border-radius:8px; }
@keyframes shimmer { 0% { background-position:100% 0; } 100% { background-position:0 0; } }
.skel-hero { height:clamp(40px,8vw,58px); width:min(72%,260px); border-radius:14px; vertical-align:middle; }
.skel-line { height:14px; width:170px; border-radius:7px; }
.skel-stat { height:22px; width:96px; }
.skel-row { display:flex; align-items:center; gap:14px; padding:14px 4px; border-top:1px solid var(--line); }
.skel-row:first-child { border-top:none; }
.skel-circle { width:40px; height:40px; border-radius:50%; flex:none; }
.skel-grow { height:14px; flex:1; max-width:210px; }
.skel-amt { height:14px; width:72px; margin-left:auto; }
/* Loading skeletons for the Signal / Podcast reading sheets (16:9 player + text lines). */
.skel-video { display:block; width:100%; aspect-ratio:16/9; border-radius:12px; }
.skel-para { display:block; height:13px; width:100%; margin:0 0 10px; border-radius:7px; }
.skel-para-short { width:60%; }

.footnote { display:none; }

@media (max-width:560px) {
  .stats { grid-template-columns:1fr; }
  .topbar-actions .label { display:none; }
  .hide-sm { display:none; }
  /* Toolbar action buttons (Connect account / Add manually / Add crypto /
     Property) are too chunky on phones. Slim them down, and break the heading
     onto its own row so the buttons sit together neatly below it (instead of
     wrapping unevenly around the title). */
  .acct-toolbar { gap:8px; row-gap:10px; }
  .acct-toolbar .spacer { flex:1 0 100%; height:0; order:1; }
  .acct-toolbar .btn-ghost { order:2; min-height:34px; padding:6px 12px; font-size:12px; gap:5px; }
  .acct-toolbar .btn-ghost > svg { width:14px; height:14px; }
}

/* ---- account recovery / authenticator (TOTP) ---- */
.recovery-row { display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin-top:18px; padding-top:16px; border-top:1px solid var(--line-strong); }
.recovery-title { font-size:13px; font-weight:600; }
.recovery-status { font-size:12px; color:var(--muted); margin-top:2px; max-width:340px; }
.recovery-row .btn-ghost { flex:none; }
.totp-qr { display:flex; justify-content:center; margin:6px 0 14px; }
.totp-qr > * { background:#fff; padding:12px; border-radius:12px; width:180px; height:180px; }
.totp-qr img, .totp-qr svg { width:100%; height:100%; display:block; }
.totp-key { display:flex; align-items:center; gap:10px; background:var(--surface-2);
  border-radius:var(--radius-sm); padding:10px 12px; margin-bottom:6px; flex-wrap:wrap; }
.totp-key-label { font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); }
.totp-key code { flex:1; min-width:120px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:13px; letter-spacing:.06em; word-break:break-all; color:var(--accent); }
.btn-tiny { padding:5px 10px; font-size:12px; }
.totp-backup { display:grid; grid-template-columns:repeat(2,1fr); gap:8px; margin:6px 0 14px; }
.totp-backup code { background:var(--surface-2); border-radius:10px; padding:9px 10px; text-align:center;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:14px; letter-spacing:.04em; }
.member-badge { font-size:11px; color:var(--accent); border:1px solid var(--accent); border-radius:999px; padding:1px 7px; flex:none; }
.member-badge.pro { color:#00210f; background:var(--accent); border-color:var(--accent); font-weight:650; }
[data-theme="light"] .member-badge.pro { color:#fff; }
.mbr-actions { display:flex; gap:6px; flex:none; align-items:center; }
.mbr-pro.on { color:var(--accent); border-color:var(--accent); }
/* Member row: name truncates, the admin badge keeps its size, and the Reset
   button never gets squeezed/overlapped (it wraps to its own line if tight). */
.prop-name-row { display:flex; align-items:center; gap:6px; min-width:0; }
.prop-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.prop-row .mbr-reset { flex:none; white-space:nowrap; align-self:center; }
#memberList .prop-row { flex-wrap:wrap; row-gap:8px; }
#memberList .prop-addr { flex:1 1 56%; }

/* ===== Offline banner — shown when rendering cached data with no network ===== */
.offline-banner { display:flex; align-items:center; gap:9px; margin:0 0 4px; padding:9px 14px;
  background:var(--accent-soft); color:var(--text); border-radius:var(--radius-sm);
  font-size:13px; line-height:1.3; }
.offline-banner[hidden] { display:none; }
.offline-banner b { font-weight:600; }
.offline-dot { width:8px; height:8px; border-radius:50%; background:var(--accent); flex:none;
  box-shadow:0 0 0 3px var(--accent-soft); }

/* ===== iOS "Add to Home Screen" hint card ===== */
.install-hint { display:flex; align-items:center; gap:12px; margin:0 0 14px; padding:12px 14px;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-sm);
  box-shadow:0 6px 20px rgba(var(--shadow-color),.06); }
.install-hint[hidden] { display:none; }
.install-hint-icon { width:38px; height:38px; border-radius:10px; flex:none; }
.install-hint-text { display:flex; flex-direction:column; gap:2px; font-size:13px; line-height:1.35; }
.install-hint-text strong { font-size:14px; font-weight:650; }
.install-hint-text span { color:var(--muted); }
.install-hint-text b { color:var(--text); font-weight:600; }
.ios-share { width:15px; height:15px; vertical-align:-3px; color:var(--accent); }
.install-hint-close { margin-left:auto; flex:none; width:28px; height:28px; border:none;
  background:transparent; color:var(--muted); font-size:15px; cursor:pointer; border-radius:8px; }
.install-hint-close:hover { background:var(--hover); color:var(--text); }

/* "updating…" marker while cached data is being revalidated in the background */
.reval-dot { font-size:11px; font-weight:500; letter-spacing:0; text-transform:none;
  color:var(--accent); margin-left:6px; animation:reval-pulse 1.1s ease-in-out infinite; }
.reval-dot[hidden] { display:none; }
@keyframes reval-pulse { 0%,100% { opacity:.45; } 50% { opacity:1; } }

/* ============================================================
   iOS-NATIVE CHROME — tab bar, floating Sync, tab panels,
   settings rows, tap targets, in-button icons. (2026 redesign)
   ============================================================ */

/* ---- Tap targets: Apple HIG 44pt minimum on primary controls ---- */
.btn-primary, .btn-ghost, .btn-danger { min-height:44px; }
.btn-tiny { min-height:0; }                 /* tiny copy buttons stay compact */
.icon-only { width:44px; height:44px; }

/* ---- Crisp inline icons inside buttons ---- */
.btn-primary > svg, .btn-ghost > svg, .btn-danger > svg { width:17px; height:17px; flex:none; }
.icon-only svg { width:20px; height:20px; display:block; }
.install-hint-close svg { width:16px; height:16px; display:block; margin:0 auto; }

/* ---- Tab panels: only the active one is shown ---- */
.tab-panel[hidden] { display:none; }

/* ---- Bottom tab bar ---- */
.tabbar {
  position:fixed; left:0; right:0; bottom:0; z-index:60;
  display:flex; align-items:stretch;
  background:var(--bg);                               /* fallback */
  background:color-mix(in srgb, var(--bg) 86%, transparent);
  -webkit-backdrop-filter:saturate(1.4) blur(18px); backdrop-filter:saturate(1.4) blur(18px);
  /* Pin to its own compositor layer. iOS standalone PWAs intermittently let a
     position:fixed element (especially one with a backdrop-filter) detach during
     momentum scroll and float mid-screen; promoting it keeps it stuck to the
     viewport. translate3d(0,0,0) (not translateZ) avoids re-introducing a 2D
     transform that the wide-screen pill rule below would otherwise clobber. */
  transform:translate3d(0,0,0); will-change:transform; -webkit-backface-visibility:hidden;
  border-top:1px solid var(--line);
  padding-bottom:env(safe-area-inset-bottom);
}
.tabbar-btn {
  flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  background:none; border:none; cursor:pointer;
  padding:9px 2px 7px; min-height:52px;
  color:var(--muted-2); transition:color .15s var(--ease);
  -webkit-tap-highlight-color:transparent;
}
.tabbar-btn .tabbar-icon { display:inline-flex; }
.tabbar-btn .tabbar-icon svg { width:25px; height:25px; display:block; }
.tabbar-btn .icon-filled { display:none; }
.tabbar-btn.active { color:var(--accent); }
.tabbar-btn.active .icon-outline { display:none; }
.tabbar-btn.active .icon-filled { display:inline-flex; }
.tabbar-label { font-size:10px; font-weight:600; letter-spacing:0; white-space:nowrap; }
.tabbar-btn:active { opacity:.6; }

/* ---- Floating Sync pill — single Sync action, thumb-reachable from any tab ---- */
/* Sync lives in the top bar now (anchored at the top — it doesn't follow scroll
   the way the AI FAB does). Most styling comes from .btn-ghost.icon-only; this
   just handles the hidden/disabled/spinning states. */
.sync-top[hidden] { display:none; }
.sync-top:disabled { opacity:.4; cursor:default; }
.sync-top.spinning svg { animation:fab-spin .9s linear infinite; }
@keyframes fab-spin { to { transform:rotate(360deg); } }

/* Wide screens: center the tab bar into a floating pill-bar. */
@media (min-width:560px) {
  .tabbar { left:50%; right:auto; transform:translateX(-50%); bottom:16px;
    max-width:480px; width:calc(100% - 40px);
    border:1px solid var(--line); border-radius:26px; padding:0;
    box-shadow:0 10px 30px rgba(var(--shadow-color),.18); }
  /* Column layout (icon over label) packs 5 tabs into the pill without the
     icon+label rows overflowing the way a horizontal layout would. */
  .tabbar-btn { flex-direction:column; gap:3px; padding:10px 6px; min-height:54px; }
  .tabbar-btn .tabbar-icon svg { width:21px; height:21px; }
  .tabbar-label { font-size:11px; }
}

/* ---- Settings → Account rows ---- */
.settings-list { display:flex; flex-direction:column; gap:8px; }
.settings-row {
  display:flex; align-items:center; gap:14px; width:100%; text-align:left;
  background:var(--surface-2); border:1px solid transparent; border-radius:var(--radius-sm);
  padding:14px 16px; cursor:pointer; color:var(--text); font:inherit; min-height:60px;
  transition:.15s var(--ease);
}
.settings-row:hover { background:var(--hover); border-color:var(--line); }
.settings-row:active { opacity:.7; }
.settings-row-icon { flex:none; display:grid; place-items:center; width:36px; height:36px;
  border-radius:10px; background:var(--accent-soft); color:var(--accent); }
.settings-row-icon svg { width:20px; height:20px; }
.settings-row-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.settings-row-title { font-size:15px; font-weight:600; letter-spacing:-.01em; }
.settings-row-sub { font-size:12px; color:var(--muted); }
.settings-row-chev { color:var(--muted-2); font-size:22px; line-height:1; flex:none; }

/* Shared danger styling (delete-account row + button) */
.danger, .recovery-title.danger { color:var(--red); }
.btn-ghost.danger:hover { border-color:var(--red); }

/* Collapsible disclosure header — "Plan ahead" (Overview) + "Admin tools"
   (Settings). Reuses the settings-row look but as a full-width toggle. */
#planningGroup, #adminGroup { margin-bottom:34px; }
.planning-toggle {
  display:flex; align-items:center; gap:14px; width:100%; text-align:left; margin-bottom:0;
  background:var(--surface-2); border:1px solid transparent; border-radius:var(--radius-sm);
  padding:14px 16px; cursor:pointer; color:var(--text); font:inherit; min-height:60px;
  transition:.15s var(--ease);
}
.planning-toggle:hover { background:var(--hover); border-color:var(--line); }
.planning-toggle:active { opacity:.7; }
.planning-toggle-icon { flex:none; display:grid; place-items:center; width:36px; height:36px;
  border-radius:10px; background:var(--accent-soft); color:var(--accent); }
.planning-toggle-icon svg { width:20px; height:20px; }
.planning-toggle-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.planning-toggle-main strong { font-size:15px; font-weight:600; letter-spacing:-.01em; }
.planning-toggle-main span { font-size:12px; color:var(--muted); }
.planning-toggle-chev { color:var(--muted-2); font-size:13px; line-height:1; flex:none;
  transition:transform .18s var(--ease); }
.planning-toggle.open .planning-toggle-chev { transform:rotate(180deg); }
/* The disclosure body adds a little breathing room above its first card. */
#planningBody, #adminBody { margin-top:14px; }

/* Account & security modal — grouped settings sections. */
.settings-group { margin-top:18px; }
.settings-group:first-of-type { margin-top:12px; }
.settings-group-title { font-size:12px; font-weight:600; text-transform:uppercase;
  letter-spacing:.06em; color:var(--muted-2); margin:0 0 8px; }
.settings-group-action { display:flex; justify-content:flex-end; margin-top:4px; }

/* Login screen respects the safe areas too. */
.login-screen { padding:max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); }

/* ===== Biometric lock screen (full-screen, opaque, above everything) ===== */
.lock-screen { position:fixed; inset:0; z-index:1000; display:none; align-items:center; justify-content:center;
  background:var(--bg); padding:max(24px, env(safe-area-inset-top)) 24px max(24px, env(safe-area-inset-bottom)); }
.lock-screen.open { display:flex; }
.lock-card { text-align:center; max-width:320px; width:100%; display:flex; flex-direction:column; gap:12px; align-items:center; }
.lock-card .logo { width:64px; height:64px; border-radius:16px; }
.lock-card .logo img { width:64px; height:64px; border-radius:16px; }
.lock-card h1 { margin:4px 0 0; font-size:24px; }
.lock-sub { color:var(--muted); font-size:14px; margin:0 0 6px; }
.lock-card .btn-primary { width:100%; justify-content:center; }
.lock-card .btn-ghost { font-size:13px; }

/* ===== Pull-to-refresh indicator ===== */
.ptr { position:absolute; top:0; left:0; right:0; display:flex; justify-content:center; pointer-events:none;
  opacity:0; transform:translateY(-8px); transition:opacity .15s ease; z-index:5; }
.ptr-spinner { width:26px; height:26px; margin-top:8px; border-radius:50%;
  border:2.5px solid var(--line-strong); border-top-color:var(--accent); }
.ptr.spinning { opacity:1 !important; transform:translateY(0) !important; }
.ptr.spinning .ptr-spinner { animation:ptr-spin .7s linear infinite; }
@keyframes ptr-spin { to { transform:rotate(360deg); } }

/* ===== "What changed" digest card (top of Overview) ===== */
.digest { position:relative; background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:12px 40px 12px 14px; margin:0 0 14px; display:flex; flex-direction:column; gap:8px;
  touch-action:pan-y; transition:transform .2s var(--ease), opacity .2s var(--ease); }
.digest[hidden] { display:none; }
.digest.digest-gone { transform:scale(.96); opacity:0; }
@media (prefers-reduced-motion:reduce) { .digest { transition:none !important; } }
.digest-x { position:absolute; top:8px; right:8px; width:28px; height:28px; min-height:0; padding:0;
  display:flex; align-items:center; justify-content:center; border:none; border-radius:999px;
  background:transparent; color:var(--muted); cursor:pointer; transition:.15s var(--ease); }
.digest-x:hover { background:var(--hover); color:var(--text); }
.digest-x svg { width:15px; height:15px; }
.digest-since { font-size:12px; font-weight:500; color:var(--muted); letter-spacing:.01em; }
.digest-delta { font-size:15px; line-height:1.2; }
.digest-delta:empty { display:none; }
.digest-badges { display:flex; flex-wrap:wrap; gap:6px; }
.digest-badges:empty { display:none; }
.digest-badge { font-size:12px; font-weight:500; padding:3px 9px; border-radius:999px;
  background:var(--surface-2); color:var(--text); white-space:nowrap; }
.digest-badge.ath, .digest-badge.streak { background:var(--accent-soft); color:var(--accent); }

/* one-time confetti burst on a new all-time high */
.confetti-bit { position:fixed; top:16%; width:8px; height:12px; border-radius:2px; z-index:60;
  pointer-events:none; opacity:0; animation:confetti 1.2s ease-out forwards; }
@keyframes confetti { 0% { opacity:1; transform:translate(0,0) rotate(0); }
  100% { opacity:0; transform:translate(var(--dx), 62vh) rotate(var(--dr)); } }

/* ===== Retirement outlook (Monte Carlo projection) ===== */
.proj-inputs { display:grid; grid-template-columns:repeat(2,1fr); gap:10px 12px; margin:0 0 14px; }
.proj-inputs label { display:flex; flex-direction:column; gap:5px; font-size:12px; font-weight:500; color:var(--muted); }
.proj-inputs input { font-size:15px; padding:10px 12px; }
.proj-stats { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin:0 0 12px; }
.proj-stat { background:var(--surface-2); border-radius:var(--radius-sm); padding:10px 13px; }
.proj-stat-label { font-size:12px; color:var(--muted); margin-bottom:3px; }
.proj-stat-value { font-size:22px; font-weight:650; letter-spacing:-.02em; }
.proj-note { font-size:11px; line-height:1.45; color:var(--muted-2); margin-top:10px; }
.scenario-actions { margin:-2px 0 10px; }
.scenario-list { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; margin-bottom:12px; }
.scenario-card { position:relative; background:var(--surface-2); border-radius:var(--radius-sm); padding:10px 34px 10px 12px; }
.scenario-name { font-size:12px; font-weight:650; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.scenario-result { font-size:12px; color:var(--muted); margin-top:3px; }
.scenario-del { position:absolute; right:7px; top:7px; border:0; background:transparent; color:var(--muted); cursor:pointer; font-size:16px; }

/* Retirement outlook → "Adjust accounts" (exclude illiquid assets like a home) */
.proj-adjust { margin:0 0 14px; }
.proj-adjust-btn { display:flex; align-items:center; gap:8px; width:100%; text-align:left;
  background:var(--surface-2); border:1px solid transparent; border-radius:var(--radius-sm);
  padding:10px 12px; cursor:pointer; color:var(--text); font-size:13px; font-weight:500; }
.proj-adjust-btn:hover { border-color:var(--line-strong); }
.proj-adjust-btn > svg { width:17px; height:17px; flex:none; color:var(--accent); }
.proj-adjust-btn > span:nth-child(2) { flex:1; }
.proj-excl-count { font-size:12px; color:var(--accent); font-weight:600; }
.proj-adjust-chev { color:var(--muted-2); transition:transform .18s var(--ease); }
.proj-adjust-btn.open .proj-adjust-chev { transform:rotate(180deg); }
.proj-accounts { display:flex; flex-direction:column; gap:6px; margin:8px 0 0; }
.proj-accounts[hidden] { display:none; }
.proj-acct { display:flex; align-items:center; gap:10px; padding:9px 11px; border-radius:11px;
  background:var(--surface-2); font-size:13px; cursor:pointer; }
.proj-acct input { width:18px; height:18px; flex:none; accent-color:var(--accent); cursor:pointer; }
.proj-acct-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.proj-acct-amt { font-weight:600; color:var(--muted); }
.proj-acct.off { opacity:.5; }
.proj-acct.off .proj-acct-name { text-decoration:line-through; }
.proj-adjust-note { font-size:11px; line-height:1.45; color:var(--muted-2); margin-top:8px; }

/* ===== Month-in-review nudge (Overview) ===== */
.wrapped-nudge { display:flex; align-items:center; gap:12px; width:100%; text-align:left;
  margin:0 0 14px; padding:12px 14px; border:1px solid var(--line); border-radius:var(--radius-sm);
  background:var(--surface); color:var(--text); cursor:pointer; transition:.15s var(--ease); }
.wrapped-nudge[hidden] { display:none; }
.wrapped-nudge:hover { background:var(--hover); }
.wrapped-nudge-spark { flex:none; width:34px; height:34px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  background:var(--accent-soft); color:var(--accent); }
.wrapped-nudge-spark svg { width:18px; height:18px; }
.wrapped-nudge-main { display:flex; flex-direction:column; gap:1px; flex:1; min-width:0; }
.wrapped-nudge-main strong { font-size:14px; font-weight:650; }
.wrapped-nudge-main span { font-size:12px; color:var(--muted); }
.wrapped-nudge-chev { color:var(--muted-2); font-size:20px; flex:none; }

/* ===== "Net Worth Wrapped" month-in-review modal ===== */
.wrapped-head { text-align:center; margin:6px 0 18px; }
.wrapped-month { font-size:clamp(22px, 7vw, 28px); font-weight:700; letter-spacing:-.02em; }
.wrapped-sub { font-size:13px; color:var(--muted); text-transform:uppercase; letter-spacing:.14em; margin-top:2px; }
.wrapped-hero { text-align:center; margin:0 0 18px; }
.wrapped-hero-label { font-size:12px; color:var(--muted); margin-bottom:4px; }
.wrapped-hero-val { font-size:clamp(28px, 9vw, 38px); font-weight:700; letter-spacing:-.03em; line-height:1.05; }
.wrapped-hero-val.up { color:var(--positive); } .wrapped-hero-val.down { color:var(--red); }
.wrapped-hero-range { font-size:13px; color:var(--muted); margin-top:6px; }
.wrapped-progress { font-size:12px; color:var(--muted-2); margin-top:8px; letter-spacing:.02em; }
.wrapped-tiles { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin:0 0 16px; }
.wrapped-tile { background:var(--surface-2); border-radius:var(--radius-sm); padding:11px 13px; }
.wrapped-tile-label { font-size:11px; color:var(--muted); margin-bottom:3px; }
.wrapped-tile-val { font-size:18px; font-weight:650; letter-spacing:-.01em; }
.wrapped-tile-val.up { color:var(--positive); } .wrapped-tile-val.down { color:var(--red); }
.wrapped-performer { background:var(--surface-2); border-radius:var(--radius-sm); padding:11px 13px; margin:0 0 16px; }
.wrapped-performer-label { font-size:11px; color:var(--muted); margin-bottom:8px; }
.wrapped-performer-row { display:flex; align-items:center; gap:11px; }
.wrapped-performer-row .logo-wrap { width:34px; height:34px; flex:none; }
.wrapped-performer-id { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.wrapped-performer-tick { font-size:15px; font-weight:700; letter-spacing:-.01em; }
.wrapped-performer-name { font-size:12px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.wrapped-performer-pct { font-size:17px; font-weight:700; color:var(--accent); flex:none; }

.wrapped-badges { display:flex; flex-wrap:wrap; gap:6px; justify-content:center; margin:0 0 16px; }
.wrapped-badge { font-size:12px; font-weight:500; padding:5px 12px; border-radius:999px; background:var(--accent-soft); color:var(--accent); }
.wrapped-spark { width:100%; height:96px; margin:0 0 14px; }
.wrapped-foot { text-align:center; font-size:11px; color:var(--muted-2); letter-spacing:.04em; }
.wrapped-empty { text-align:center; color:var(--muted); font-size:14px; padding:18px 0; line-height:1.5; }

/* ===== Net worth percentile by age (Fed SCF 2022) ===== */
.pct-head { display:flex; align-items:center; gap:14px; margin:0 0 16px; }
.pct-age { display:flex; flex-direction:column; gap:5px; font-size:12px; font-weight:500; color:var(--muted); flex:none; width:84px; }
.pct-age input { font-size:15px; padding:10px 12px; text-align:center; }
.pct-rank { flex:1; min-width:0; }
.pct-rank-big { font-size:clamp(26px, 8vw, 33px); font-weight:700; letter-spacing:-.02em; line-height:1.05; color:var(--accent); }
.pct-rank-big .pct-rank-word { font-size:15px; font-weight:600; color:var(--text); letter-spacing:0; }
.pct-rank-sub { font-size:12px; color:var(--muted); margin-top:4px; line-height:1.35; }
.pct-scale { position:relative; height:10px; border-radius:999px; margin:0 0 6px;
  background:linear-gradient(90deg, var(--surface-2), var(--accent-soft)); overflow:visible; }
.pct-scale-fill { height:100%; border-radius:999px; background:var(--accent); opacity:.55; transition:width .35s var(--ease); }
.pct-scale-marker { position:absolute; top:50%; width:16px; height:16px; border-radius:999px;
  background:var(--accent); border:3px solid var(--surface); transform:translate(-50%,-50%);
  box-shadow:0 1px 4px rgba(var(--shadow-color),.35); transition:left .35s var(--ease); }
.pct-ticks { display:flex; justify-content:space-between; font-size:10px; color:var(--muted-2); }

/* ===== AI copilot chat ===== */
.copilot-modal { display:flex; flex-direction:column; max-height:82vh; }
.copilot-thread { flex:1; min-height:220px; max-height:48vh; overflow-y:auto; display:flex; flex-direction:column;
  gap:10px; padding:4px 2px 10px; }
.copilot-empty { color:var(--muted); font-size:14px; line-height:1.5; text-align:center; margin:auto; padding:18px 8px; }
.copilot-msg { max-width:85%; padding:10px 13px; border-radius:16px; font-size:14px; line-height:1.45; word-wrap:break-word; overflow-wrap:anywhere; }
/* User text + plain error/fallback bubbles preserve their own line breaks; the
   assistant bubble is rendered markdown (structure comes from <p>/<ul>/<h*>). */
.copilot-msg.user { align-self:flex-end; background:var(--accent); color:#00210f; border-bottom-right-radius:5px; white-space:pre-wrap; }
[data-theme="light"] .copilot-msg.user { color:#fff; }
.copilot-msg.assistant { align-self:flex-start; background:var(--surface-2); color:var(--text); border-bottom-left-radius:5px; }
.copilot-msg.assistant.error { background:var(--red-soft); color:var(--red); white-space:pre-wrap; }
/* Rendered-markdown elements inside an assistant answer. */
.copilot-msg.assistant > :first-child { margin-top:0; }
.copilot-msg.assistant > :last-child { margin-bottom:0; }
.copilot-msg.assistant p { margin:7px 0; }
.copilot-msg.assistant h4, .copilot-msg.assistant h5, .copilot-msg.assistant h6 { font-size:14px; font-weight:650; margin:10px 0 3px; }
.copilot-msg.assistant ul, .copilot-msg.assistant ol { margin:5px 0; padding-left:20px; }
.copilot-msg.assistant li { margin:2px 0; }
.copilot-msg.assistant code { background:var(--surface); padding:1px 5px; border-radius:5px; font-size:13px; }
.copilot-msg.assistant pre { background:var(--surface); padding:9px 11px; border-radius:9px; overflow:auto; margin:7px 0; }
.copilot-msg.assistant pre code { background:none; padding:0; }
.copilot-msg.assistant a { color:var(--accent); text-decoration:underline; }
/* Blinking caret shown while the answer is still streaming in. */
.copilot-caret { display:inline-block; width:2px; height:1em; margin-left:2px; background:var(--accent); vertical-align:text-bottom; animation:copilot-caret-blink 1s step-end infinite; }
@keyframes copilot-caret-blink { 0%,100% { opacity:1; } 50% { opacity:0; } }
@media (prefers-reduced-motion:reduce) { .copilot-caret { animation:none; } }
.copilot-typing { display:inline-block; letter-spacing:2px; animation:reval-pulse 1.1s ease-in-out infinite; }
/* Trailing spacer that lets the latest question scroll to the top of the thread
   while its answer streams in below (height is managed inline by app.js). */
.copilot-spacer { flex:none; }
.copilot-input { display:flex; gap:8px; align-items:center; margin-top:6px; }
.copilot-input input { flex:1; }
.copilot-input .btn-primary.icon-only { width:44px; height:44px; flex:none; padding:0; display:flex; align-items:center; justify-content:center; }
.copilot-input .btn-primary svg { width:20px; height:20px; }

/* ===== asset performance: per-entity % badges + mini history charts ===== */
.chg { display:inline-block; font-size:11px; font-weight:600; letter-spacing:.01em; white-space:nowrap; margin-top:2px; }
.chg.good { color:var(--positive); }
.chg.bad { color:var(--red); }
/* dimmed timeframe suffix on the day-change badge ("today") */
.chg-per { color:var(--muted); font-weight:500; }
/* holdings rows are tappable: tapping opens the stock-research overlay */
.h-item { display:block; }
.h-row.tappable { cursor:pointer; }
/* account-detail block inside the edit modal: crypto coverage / DeFi note. */
.acct-hist { margin:2px 0 14px; padding:12px; background:var(--surface-2); border-radius:var(--radius-sm); }
.acct-cov { margin-top:10px; }
.acct-defi { margin-top:10px; display:flex; flex-direction:column; gap:5px; }
.acct-defi-txt { font-size:12px; color:var(--muted); line-height:1.45; }

/* ===================== AI features ===================== */
/* Flagship copilot entry. Docked just ABOVE the bottom tab bar (~53px tall), in the
   right-hand thumb arc. Icon-only round button so it never occludes a value beneath it;
   the "Ask Ascend" label rides aria-label + a one-time coachmark. */
.ai-fab {
  position:fixed; right:16px; z-index:62;
  bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  display:inline-flex; align-items:center; justify-content:center;
  width:52px; height:52px; padding:0;
  background:var(--accent); color:#00210f; border:none; cursor:pointer;
  border-radius:999px;
  box-shadow:0 6px 18px rgba(var(--shadow-color),.28);
  /* Keep on its own compositor layer so it doesn't detach/float during iOS
     momentum scroll (same fix as .tabbar). */
  transform:translate3d(0,0,0); will-change:transform; -webkit-backface-visibility:hidden;
  transition:filter .18s var(--ease), opacity .18s var(--ease), transform .18s var(--ease);
}
[data-theme="light"] .ai-fab { color:#fff; box-shadow:0 6px 16px rgba(47,125,94,.32); }
/* Icon-only so the floating control never covers a value (e.g. the bottom-right
   "Savings rate" cash-flow tile). The label lives in aria-label + the one-time
   coachmark below, so discoverability survives without occluding content. */
.ai-fab-icon svg { width:22px; height:22px; flex:none; display:block; }
.ai-fab:hover { filter:brightness(1.06); }
.ai-fab:active { transform:scale(.92); }
.ai-fab[hidden] { display:none; }
/* Scroll-to-hide: while the list is moving, tuck the icon away so it never sits over a
   right-aligned value (e.g. a holding's balance); it returns a beat after scrolling stops.
   pointer-events:none prevents a stray tap mid-scroll. */
.ai-fab.scrolling { opacity:0; transform:translate3d(0,8px,0) scale(.9); pointer-events:none; }
@media (prefers-reduced-motion:reduce) { .ai-fab.scrolling { transform:none; } }

/* One-time intro that points at the icon FAB so a first-time user knows the AI is
   here — shown once (localStorage), auto-dismisses on tap/scroll/timeout. Sits
   ABOVE the FAB, so it never covers dashboard content. */
.ai-fab-coach {
  position:fixed; right:16px; z-index:63;
  bottom:calc(var(--tabbar-h) + 52px + 12px + env(safe-area-inset-bottom));
  max-width:230px; padding:11px 13px;
  background:var(--surface); color:var(--text);
  border:1px solid var(--line); border-radius:14px;
  box-shadow:0 8px 24px rgba(var(--shadow-color),.22);
  font-size:13px; line-height:1.35;
  animation:ai-coach-in .26s var(--ease) both;
}
.ai-fab-coach strong { font-weight:650; }
.ai-fab-coach::after {
  content:""; position:absolute; right:24px; bottom:-7px;
  width:13px; height:13px; background:var(--surface);
  border-right:1px solid var(--line); border-bottom:1px solid var(--line);
  transform:rotate(45deg);
}
.ai-fab-coach[hidden] { display:none; }
@keyframes ai-coach-in { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion:reduce) { .ai-fab-coach { animation:none; } }
@media (min-width:560px) { .ai-fab-coach { right:24px; bottom:calc(78px + 52px + 12px + env(safe-area-inset-bottom)); } }
.ai-fab { animation:ai-fab-pulse 2.4s var(--ease) 1; }
@keyframes ai-fab-pulse { 0%,100% { box-shadow:0 6px 18px rgba(var(--shadow-color),.28); } 40% { box-shadow:0 6px 18px rgba(var(--shadow-color),.28), 0 0 0 7px var(--accent-soft); } }
@media (prefers-reduced-motion:reduce) { .ai-fab { animation:none; } }
@media (min-width:560px) { .ai-fab { right:24px; bottom:calc(78px + env(safe-area-inset-bottom)); } }

/* Members search box */
.members-search { display:flex; align-items:center; gap:8px; background:var(--surface-2);
  border:1px solid var(--line); border-radius:999px; padding:0 14px; margin-bottom:12px; }
.members-search svg { width:17px; height:17px; flex:none; color:var(--muted); }
.members-search input { flex:1; min-width:0; background:none; border:none; padding:11px 0; font:inherit; color:var(--text); }
.members-search input:focus { outline:none; }
/* The input suppresses its own outline, so surface keyboard focus on the wrapper border. */
.members-search:focus-within { border-color:var(--accent); }

/* Proactive insight card (Overview). */
.insight-card { position:relative; display:flex; gap:11px; align-items:flex-start;
  background:linear-gradient(135deg, var(--accent-soft), var(--surface)); border:1px solid var(--line);
  border-radius:var(--radius-sm); padding:13px 38px 13px 13px; margin:0 0 14px; }
.insight-card[hidden] { display:none; }
.insight-spark { flex:none; width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  background:var(--accent); color:#00210f; }
[data-theme="light"] .insight-spark { color:#fff; }
.insight-spark svg { width:18px; height:18px; }
.insight-main strong { display:block; font-size:14px; margin-bottom:2px; }
.insight-main p { margin:0; font-size:13px; color:var(--muted); line-height:1.45; }
.insight-close { position:absolute; top:8px; right:8px; width:28px; height:28px; min-height:0; padding:0;
  display:flex; align-items:center; justify-content:center; border:none; border-radius:999px;
  background:transparent; color:var(--muted); cursor:pointer; transition:.15s var(--ease); }
.insight-close:hover { background:var(--hover); color:var(--text); }
.insight-close svg { width:15px; height:15px; }

/* ---------- Weekly Rundown: entry card + full report ---------- */
.rundown-card { position:relative; display:flex; align-items:center; gap:13px; width:100%; text-align:left; cursor:pointer;
  background:linear-gradient(135deg, var(--accent-soft), var(--surface)); border:1px solid var(--line);
  border-radius:var(--radius-sm); padding:14px; margin:0 0 14px; transition:.15s var(--ease); }
.rundown-card[hidden] { display:none; }
.rundown-card:hover { border-color:var(--line-strong); }
.rundown-card.unseen { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent-soft); }
.rundown-card-open { display:flex; align-items:center; gap:13px; min-width:0; flex:1; padding:0;
  border:0; background:transparent; color:inherit; text-align:left; cursor:pointer; }
.rundown-card-dismiss { width:30px; height:30px; min-height:0; padding:0; flex:none; display:flex;
  align-items:center; justify-content:center; border:0; border-radius:999px; background:transparent;
  color:var(--muted); cursor:pointer; }
.rundown-card-dismiss:hover { background:var(--hover); color:var(--text); }
.rundown-card-dismiss svg { width:15px; height:15px; }
.rundown-card-icon { flex:none; width:38px; height:38px; border-radius:11px; display:flex; align-items:center; justify-content:center;
  background:var(--accent); color:#00210f; }
[data-theme="light"] .rundown-card-icon { color:#fff; }
.rundown-card-icon svg { width:20px; height:20px; }
.rundown-card-main { display:flex; flex-direction:column; gap:2px; flex:1; min-width:0; }
.rundown-card-main strong { font-size:14px; font-weight:650; }
.rundown-card-main span { font-size:12px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rundown-card-chev { color:var(--muted-2); font-size:22px; flex:none; }

/* ---------- Pro teasers: locked previews shown to free users ---------- */
.pro-pill { flex:none; display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:650;
  letter-spacing:.02em; color:#00210f; background:var(--accent); border-radius:999px; padding:3px 9px 3px 7px; }
[data-theme="light"] .pro-pill { color:#fff; }
.pro-pill svg { width:13px; height:13px; }
.pro-teaser { position:relative; border-radius:var(--radius-sm); overflow:hidden; }
/* Honest label so the blurred example never reads as the user's withheld data. */
.pro-teaser-label { position:absolute; top:8px; right:10px; z-index:2; font-size:11px; font-weight:600;
  color:var(--muted-2); background:var(--surface); border:1px solid var(--line); border-radius:999px; padding:2px 9px; }
.pro-teaser-blur { filter:blur(5px); -webkit-filter:blur(5px); pointer-events:none; user-select:none; opacity:.85; }
.pro-lock { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; gap:7px; padding:18px; background:rgba(21,25,22,.60);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px); }
[data-theme="light"] .pro-lock { background:rgba(243,238,227,.62); }
.pro-lock-icon { flex:none; width:42px; height:42px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:var(--accent); color:#00210f; margin-bottom:2px; }
[data-theme="light"] .pro-lock-icon { color:#fff; }
.pro-lock-icon svg { width:22px; height:22px; }
.pro-lock strong { font-size:15px; font-weight:650; }
.pro-lock > span { font-size:12px; color:var(--muted); max-width:34ch; line-height:1.45; }
.pro-lock .btn-primary { margin-top:6px; }

/* Free "discovery shelf": tappable chips for stocks that already have a cached
   brief, so a free user can read + share a real teaser without guessing a ticker. */
.research-shelf { margin-bottom:14px; }
/* Collapsed "Browse research" disclosure: a toggle row that opens a searchable list,
   so the chip list scales instead of spilling every cached ticker open at once. */
.research-shelf-toggle { display:flex; align-items:center; gap:8px; width:100%; padding:8px 0; border:none;
  background:none; cursor:pointer; color:var(--muted); text-align:left; }
.research-shelf-toggle:hover { color:var(--text); }
.research-shelf-head { font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:inherit; margin:0; }
.research-shelf-count { font-size:10px; font-weight:700; line-height:1; padding:3px 7px; border-radius:999px;
  background:var(--surface-2); color:var(--muted); }
.research-shelf-chev { margin-left:auto; display:inline-flex; color:var(--muted); transition:transform .18s var(--ease); }
.research-shelf-chev svg { width:16px; height:16px; }
.research-shelf-toggle[aria-expanded="true"] .research-shelf-chev { transform:rotate(90deg); }
.research-shelf-panel { padding-top:4px; }
.research-shelf-search { display:flex; align-items:center; gap:8px; background:var(--surface-2); border:1px solid var(--line);
  border-radius:999px; padding:0 14px; margin-bottom:10px; }
.research-shelf-search svg { width:16px; height:16px; flex:none; color:var(--muted); }
.research-shelf-search input { flex:1; min-width:0; background:none; border:none; padding:10px 0; font:inherit; font-size:14px;
  color:var(--text); text-transform:uppercase; }
.research-shelf-search input::placeholder { text-transform:none; }
.research-shelf-search input:focus { outline:none; }
.research-shelf-search:focus-within { border-color:var(--accent); }
.research-shelf-empty { color:var(--muted); font-size:13px; padding:6px 2px; }
/* One horizontal, swipeable row instead of a wrapping grid — stays a clean single
   line however many briefs exist (a wrapping grid turned into a tall wall at scale).
   Scrollbar hidden; snap + edge padding so the last chip doesn't clip. When the
   search filter hides chips, [hidden] collapses them out of the row. */
.research-shelf-row { display:flex; flex-wrap:nowrap; gap:8px; overflow-x:auto; padding:1px 1px 3px;
  scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch; scrollbar-width:none; overscroll-behavior-x:contain; }
.research-shelf-row::-webkit-scrollbar { display:none; }
.research-chip { display:inline-flex; align-items:center; gap:7px; padding:6px 12px 6px 7px; border:1px solid var(--line-strong);
  border-radius:999px; background:var(--surface); color:var(--text); font-size:13px; font-weight:600; line-height:1;
  flex:none; scroll-snap-align:start; }
.research-chip[hidden] { display:none; }
.research-chip:hover { border-color:var(--accent); background:var(--hover); }
.research-chip-logo { width:20px; height:20px; border-radius:5px; overflow:hidden; flex:none; display:inline-flex; align-items:center; justify-content:center; }
/* contain (not cover) + a hair of padding so the whole brand mark fits inside the
   tiny 20px chip icon instead of being zoomed/cropped edge-to-edge ("smushed"). */
.research-chip-logo img { width:100%; height:100%; object-fit:contain; padding:2px; box-sizing:border-box; }
/* Pro lock inside a free user's teaser report (in the stock overlay). */
.research-teaser-lock { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:14px; padding:12px 14px; border-radius:13px; background:var(--accent-soft); }
.research-teaser-lock .rt-lock-svg { width:18px; height:18px; flex:none; color:var(--accent); }
.research-teaser-lock > span { flex:1 1 160px; font-size:13px; color:var(--text); line-height:1.4; }
.research-teaser-lock .btn-primary { margin-left:auto; }
.research-empty { color:var(--muted); font-size:14px; line-height:1.5; padding:10px 0; }

@media (min-width:560px){ .modal-lg { max-width:580px; } }
.rundown-head { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.rundown-head h3 { margin:0; }
.rundown-head .sub { margin:3px 0 0; }
/* Past-rundowns archive picker (PROD-05) — a subtle secondary control under the meta line. */
.rundown-week-select { margin:8px 0 0; font-size:12px; color:var(--muted); background:var(--surface-2);
  border:1px solid var(--line); border-radius:8px; padding:5px 8px; max-width:240px; cursor:pointer; }
.overlay-x { width:30px; height:30px; min-height:0; padding:0; flex:none; display:flex; align-items:center; justify-content:center;
  border:none; border-radius:999px; background:transparent; color:var(--muted); cursor:pointer; }
.overlay-x:hover { background:var(--hover); color:var(--text); }
.overlay-x svg { width:16px; height:16px; }
/* Header actions for the stock-research ("holding report") overlay: a prominent
   Share pill sits next to the close X so the share-to-grow loop is impossible to miss. */
.research-head-actions { display:flex; align-items:center; gap:8px; flex:none; }
.btn-share {
  display:inline-flex; align-items:center; gap:6px; flex:none; line-height:1;
  background:var(--accent); color:#00210f; border:none; font-weight:600; font-size:13px;
  padding:7px 13px; border-radius:999px;
}
[data-theme="light"] .btn-share { color:#fff; }
.btn-share:hover { filter:brightness(1.08); }
.btn-share svg { width:15px; height:15px; }

.rundown-body { margin-top:6px; }
.rd-summary { font-size:14px; line-height:1.5; margin:6px 0 16px; }
.rd-stats { display:flex; gap:10px; flex-wrap:wrap; margin-bottom:6px; }
.rd-stat { flex:1; min-width:90px; background:var(--surface-2); border-radius:var(--radius-sm); padding:11px 13px; }
.rd-stat-label { font-size:11px; color:var(--muted); margin-bottom:3px; }
.rd-stat-value { font-size:16px; font-weight:650; }
.rd-stat-value.green { color:var(--accent); }
.rd-stat-value.red { color:var(--red); }
.rd-sec { margin-top:20px; }
.rd-sec h4 { font-size:12px; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:0 0 9px; }
.rd-chips { display:flex; flex-wrap:wrap; gap:7px; }
.rd-chip { font-size:13px; font-weight:600; padding:5px 10px; border-radius:999px; background:var(--surface-2); }
.rd-chip.up { color:var(--accent); background:var(--accent-soft); }
.rd-chip.down { color:var(--red); background:var(--red-soft); }
.rd-alloc { display:flex; flex-direction:column; gap:8px; }
.rd-alloc-row { display:flex; align-items:center; gap:10px; }
.rd-alloc-label { font-size:13px; width:96px; flex:none; }
.rd-alloc-bar { flex:1; height:7px; background:var(--surface-2); border-radius:999px; overflow:hidden; }
.rd-alloc-bar span { display:block; height:100%; background:var(--accent); border-radius:999px; }
.rd-alloc-pct { font-size:12px; color:var(--muted); width:42px; text-align:right; flex:none; }
.rd-note { font-size:13px; color:var(--muted); line-height:1.45; margin:11px 0 0; }
.rd-holds { display:flex; flex-direction:column; gap:8px; }
.rd-hold { display:flex; flex-direction:column; gap:4px; width:100%; text-align:left; cursor:pointer;
  background:var(--surface-2); border:1px solid transparent; border-radius:var(--radius-sm); padding:11px 13px; }
.rd-hold:hover { border-color:var(--line); }
.rd-hold-top { display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.rd-hold-tkr { font-weight:650; font-size:14px; }
.rd-hold-pct { font-size:12px; color:var(--muted); }
.rd-hold-line { font-size:13px; line-height:1.4; }
.rd-hold-line.bull { color:var(--accent); }
.rd-hold-line.bear { color:var(--red); }
.rd-hold-more { font-size:12px; color:var(--muted-2); margin-top:2px; }
.rd-hold-detail { margin-top:8px; padding-top:9px; border-top:1px solid var(--line); font-size:13px; line-height:1.45; }
.rd-hold-detail[hidden] { display:none; }
.rd-hold-loading { color:var(--muted); font-size:13px; }
.rd-hd-summary { margin:0 0 8px; }
.rd-hd-personal { margin:0 0 8px; color:var(--accent); font-weight:600; }
.rd-hd-col { margin-top:8px; }
.rd-hd-col h5 { margin:0 0 4px; font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); }
.rd-hd-col.bull h5 { color:var(--accent); }
.rd-hd-col.bear h5 { color:var(--red); }
.rd-hd-col ul, .rd-list { margin:0; padding-left:18px; }
.rd-list { display:flex; flex-direction:column; gap:5px; font-size:13px; line-height:1.45; }
.rd-list li { margin:0; }
.rd-disclaimer { font-size:11px; color:var(--muted-2); margin:20px 0 0; }

/* Earnings: compact one-line rows (capped to the next few in JS) so the section
   stays short instead of mirroring the whole Holdings list. */
.earn-list { display:flex; flex-direction:column; }
.earn-row { display:flex; align-items:center; gap:10px; padding:8px 4px; border-top:1px solid var(--line); transition:.15s var(--ease); }
/* .earn-row sets display:flex, an author rule that would otherwise override the
   UA [hidden] rule — so hide collapsed "extra" rows explicitly. */
.earn-row[hidden] { display:none; }
.earn-row:first-child { border-top:none; }
.earn-row.tappable { cursor:pointer; }
.earn-row.tappable:hover { background:var(--hover); }
.earn-row .logo-wrap { width:24px; height:24px; border-radius:7px; }
.earn-row .logo-fallback { font-size:10px; }
.earn-ticker { flex:1; min-width:0; font-size:14px; font-weight:600; letter-spacing:-.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.earn-when { flex:none; font-size:12px; color:var(--muted); white-space:nowrap; }
/* "+N more" is a real <button> (toggles the hidden rows); strip the UA chrome. */
.earn-more { display:block; width:100%; text-align:left; padding:8px 4px; font-size:12px; color:var(--muted-2);
  background:none; border:none; border-top:1px solid var(--line); cursor:pointer; transition:color .15s var(--ease); }
.earn-more:hover { color:var(--text); }
/* Earnings row → stock research affordance + the research overlay header. */
.earn-chev { color:var(--muted-2); font-size:20px; flex:none; margin-left:4px; align-self:center; }

/* ---- consolidated "Across your holdings" digest ---- */
/* Weekly AI "what matters" note — sits above the factual blocks. */
.digest-note { background:var(--accent-soft); border-radius:12px; padding:13px 15px; margin-bottom:18px; }
.digest-note-head { font-size:14px; font-weight:700; letter-spacing:-.01em; margin-bottom:4px; }
.digest-note-summary { margin:0; font-size:13px; line-height:1.5; color:var(--text); }
.digest-note-bullets { margin:8px 0 0; padding-left:18px; }
.digest-note-bullets li { font-size:13px; line-height:1.45; margin:2px 0; }
.digest-note-foot { margin-top:9px; font-size:10px; color:var(--muted-2); }
.digest-block + .digest-block { margin-top:18px; }
.digest-h { margin:0 0 6px; font-size:12px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--muted-2); }
.digest-kind { font-size:11px; font-weight:600; color:var(--muted); letter-spacing:0; }
.digest-cats { list-style:none; margin:0; padding:0; }
.digest-cats li { padding:7px 4px; font-size:13px; line-height:1.45; color:var(--text); }
/* Separator BETWEEN visible rows only — so filtering (which hides rows) never
   leaves a stray top border above the first shown row or a gap where one is hidden. */
.digest-cats li:not([hidden]) ~ li:not([hidden]) { border-top:1px solid var(--line); }
/* Per-holding filter chips above the catalyst list. One scrollable row (the list can
   now cover every holding), so a long book scrolls sideways instead of stacking. */
.digest-cat-filter { display:flex; flex-wrap:nowrap; gap:6px; margin:0 0 10px; overflow-x:auto;
  -webkit-overflow-scrolling:touch; scrollbar-width:none; padding-bottom:2px; }
.digest-cat-filter::-webkit-scrollbar { display:none; }
.digest-cat-chip { flex:0 0 auto; font:inherit; font-size:11px; font-weight:700; letter-spacing:.3px; padding:4px 10px;
  border:none; border-radius:999px; cursor:pointer; background:var(--surface-2); color:var(--muted); transition:.15s var(--ease); }
.digest-cat-chip:hover { color:var(--text); }
.digest-cat-chip.active { background:var(--accent-soft); color:var(--accent); }
.digest-cats-empty { color:var(--muted); font-size:13px; padding:8px 4px; }
.digest-cat-tk { display:inline-block; font-weight:700; font-size:11px; color:var(--accent); background:var(--accent-soft);
  padding:1px 7px; border-radius:999px; margin-right:6px; letter-spacing:.3px; vertical-align:1px; }
.digest-news-tk { font-weight:700; color:var(--accent); }
.stock-research-title { display:flex; align-items:center; gap:11px; min-width:0; }
.stock-research-title h3 { margin:0; }
.stock-research-title .sub { margin:2px 0 0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.stock-research-logo { flex:none; display:flex; align-items:center; }
/* Breathing room between the overlay header and the research body so the title
   block and the disclaimer banner don't crowd / overlap. */
#stockResearchBody { margin-top:16px; }

/* ---- research overlay: Finnhub key stats / earnings track / news ---- */
#stockResearchFacts:not(:empty) { margin-top:16px; }
.kstat-meta { font-size:12px; color:var(--muted); margin-bottom:9px; }
.kstat-grid { display:grid; grid-template-columns:repeat(2, 1fr); gap:8px; }
@media (min-width:420px){ .kstat-grid { grid-template-columns:repeat(3, 1fr); } }
.kstat { background:var(--surface-2); border-radius:var(--radius-sm); padding:9px 11px; display:flex; flex-direction:column; gap:2px; min-width:0; }
.kstat-label { font-size:11px; color:var(--muted); white-space:nowrap; }
.kstat-val { font-size:14px; font-weight:650; letter-spacing:-.01em; }
.kstat-val .kstat-chg { font-size:11px; font-weight:600; }
.kstat-chg.up { color:var(--positive); } .kstat-chg.down { color:var(--red); }
.kstat-label { display:inline-flex; align-items:center; gap:3px; min-width:0; }
/* Truncate the label TEXT on the inner span so overflow:hidden never clips the info
   button's 44px tap expander (which lives in the flex row, outside this span). */
.kstat-label-txt { min-width:0; overflow:hidden; text-overflow:ellipsis; }
.kstat-info { position:relative; display:inline-flex; align-items:center; justify-content:center; width:15px; height:15px; padding:0; border:1px solid var(--line-strong); border-radius:50%; background:transparent; color:var(--muted); font-size:10px; font-weight:700; line-height:1; cursor:pointer; flex:none; }
/* Expand the tap target to ~44px without changing the visible 15px dot (a11y). */
.kstat-info::before { content:""; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:44px; height:44px; }
.kstat-info:hover { color:var(--text); border-color:var(--muted); }
.kstat-info.active { background:var(--accent); color:#00210f; border-color:var(--accent); }
[data-theme="light"] .kstat-info.active { color:#fff; }
.kstat-def { margin-top:9px; background:var(--accent-soft); color:var(--accent); font-size:12px; line-height:1.45; padding:9px 11px; border-radius:var(--radius-sm); }
.kstat-def-label { font-weight:650; }
.research-extra { margin-top:18px; }
.research-extra > h4 { font-size:12px; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:0 0 9px; }
.etrack-headline { font-size:14px; font-weight:600; margin-bottom:8px; }
.etrack-sub { font-weight:400; color:var(--muted); font-size:12px; }
.etrack-chips { display:flex; flex-wrap:wrap; gap:7px; }
.etrack-chip { font-size:12px; font-weight:600; padding:4px 9px; border-radius:999px; background:var(--surface-2); white-space:nowrap; }
.etrack-chip.up { color:var(--accent); background:var(--accent-soft); }
.etrack-chip.down { color:var(--red); background:var(--red-soft); }
.news-list { display:flex; flex-direction:column; }
.news-item { display:flex; flex-direction:column; gap:2px; padding:9px 2px; border-top:1px solid var(--line); text-decoration:none; color:var(--text); }
.news-item:first-child { border-top:none; }
.news-item:hover .news-headline { color:var(--accent); }
.news-headline { font-size:13px; line-height:1.35; font-weight:500; }
.news-meta { font-size:11px; color:var(--muted); }

/* Admin AI kill-switch toggles. */
.ai-flag-list { display:flex; flex-direction:column; gap:2px; }
.ai-flag-row { display:flex; align-items:center; gap:12px; padding:11px 4px; cursor:pointer; position:relative; }
.ai-flag-row + .ai-flag-row { border-top:1px solid var(--line); }
.ai-flag-row.master .ai-flag-title { font-weight:600; }
/* Admin "Generate signal now" affordance under the flag list. */
.ai-run-row { display:flex; align-items:center; gap:12px; margin-top:12px; padding-top:12px; border-top:1px solid var(--line); flex-wrap:wrap; }
.ai-run-row .hint { flex:1; min-width:160px; font-size:12px; color:var(--muted); }
.ai-flag-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.ai-flag-title { font-size:14px; }
.ai-flag-sub { font-size:12px; color:var(--muted); }
.ai-flag-toggle { position:absolute; opacity:0; width:0; height:0; }
.ai-flag-switch { flex:none; width:42px; height:25px; border-radius:999px; background:var(--surface-2);
  border:1px solid var(--line-strong); position:relative; transition:background .18s var(--ease); }
.ai-flag-switch::after { content:""; position:absolute; top:2px; left:2px; width:19px; height:19px; border-radius:50%;
  background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.3); transition:transform .18s var(--ease); }
.ai-flag-toggle:checked ~ .ai-flag-switch { background:var(--accent); border-color:transparent; }
.ai-flag-toggle:checked ~ .ai-flag-switch::after { transform:translateX(17px); }
.ai-flag-toggle:focus-visible ~ .ai-flag-switch { outline:2px solid var(--accent); outline-offset:2px; }
@media (prefers-reduced-motion:reduce) { .ai-flag-switch, .ai-flag-switch::after { transition:none !important; } }

/* Stock research. */
.research-bar { display:flex; gap:8px; margin-bottom:10px; }
.research-bar input { flex:1; min-width:0; text-transform:uppercase; }
.research-result:empty { display:none; }
.research-loading, .research-err { font-size:13px; color:var(--muted); padding:8px 2px; }
.research-brief { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-sm); padding:14px; }
.research-ticker { font-size:18px; font-weight:700; margin-bottom:6px; }
.research-summary { margin:0 0 10px; font-size:13px; line-height:1.5; }
.research-personal { margin:0 0 10px; font-size:13px; font-weight:500; color:var(--accent); }
.research-col { margin-bottom:10px; }
.research-col h4 { margin:0 0 4px; font-size:13px; }
.research-col.bull h4 { color:var(--accent); }
.research-col.bear h4 { color:var(--red); }
.research-col ul { margin:0; padding-left:18px; }
.research-col li { font-size:13px; line-height:1.5; margin-bottom:3px; }
.research-disclaimer { font-size:11px; color:var(--muted-2); margin-top:8px; font-style:italic; }
/* Prominent, consistent "not advice" banner shown at the TOP of every AI surface. */
.ai-disclaimer { font-size:12px; line-height:1.4; color:var(--muted); background:var(--surface-2);
  border:1px solid var(--line); border-left:3px solid var(--accent); border-radius:var(--radius-sm);
  padding:8px 11px; margin:0 0 12px; }
.ai-disclaimer.sm { font-size:11px; padding:6px 9px; margin:0 0 10px; }
.research-sources { font-size:11px; color:var(--muted); margin-top:6px; }
.research-sources a { color:var(--accent); }

/* Copilot suggestion chips + memory box + wrapped narration. */
.copilot-suggest { display:flex; flex-wrap:wrap; gap:7px; margin-top:12px; }
.copilot-chip { font:inherit; font-size:12px; padding:7px 12px; border-radius:999px; cursor:pointer;
  background:var(--surface-2); border:1px solid var(--line); color:var(--text); min-height:36px; }
.copilot-chip:hover { border-color:var(--accent); color:var(--accent); }
.memory-box { background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:13px; font-size:13px; line-height:1.55; white-space:pre-wrap; min-height:80px; max-height:300px; overflow:auto; }
.wrapped-narration { background:var(--accent-soft); border-radius:var(--radius-sm); padding:12px 14px;
  font-size:13px; line-height:1.55; margin:4px 0 0; }
.wrapped-narration[hidden] { display:none; }
.wrapped-narrate-btn[hidden] { display:none; }
.wrapped-narrate-btn { width:100%; justify-content:center; margin-top:8px; }

/* Upgrade-to-Pro sheet */
.pro-perks { list-style:none; margin:2px 0 14px; padding:0; display:grid; gap:9px; }
.pro-perks li { display:flex; gap:9px; align-items:flex-start; font-size:13px; line-height:1.4; color:var(--text); }
.pro-perks li svg { flex:none; width:18px; height:18px; color:var(--accent); margin-top:1px; }
.plan-options { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:0 0 6px; }
.plan-option { text-align:left; border:1.5px solid var(--line); background:var(--surface); border-radius:var(--radius-sm);
  padding:12px; cursor:pointer; display:flex; flex-direction:column; gap:2px; transition:border-color .12s var(--ease), box-shadow .12s var(--ease); }
.plan-option.selected { border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent); }
.plan-option:active { transform:scale(.98); }
.plan-option:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.plan-option .plan-name { font-weight:600; font-size:13px; color:var(--muted); }
.plan-option .plan-price { font-size:20px; font-weight:700; color:var(--text); }
.plan-option .plan-per { font-size:12px; font-weight:600; color:var(--muted); }
.plan-option .plan-note { font-size:12px; color:var(--accent); min-height:15px; }
.settings-row.is-pro .settings-row-title { color:var(--accent); }

/* Returns vs the market (Pro) */
.returns-head { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:4px; }
.returns-figure { display:flex; flex-direction:column; gap:2px; }
.returns-twr { font-size:clamp(26px, 8vw, 33px); font-weight:700; line-height:1.05; color:var(--text); letter-spacing:-0.01em; }
.returns-sub { font-size:12px; color:var(--muted); }
.returns-verdict { font-size:14px; color:var(--text); margin:2px 0 10px; }
.returns-chart { width:100%; height:170px; display:block; color:var(--muted); }
.returns-legend { display:flex; gap:16px; margin-top:6px; font-size:12px; color:var(--muted); }
.returns-legend .lg-you::before { content:""; display:inline-block; width:14px; height:0; border-top:2.5px solid var(--accent); vertical-align:middle; margin-right:6px; }
.returns-legend .lg-bench::before { content:""; display:inline-block; width:14px; height:0; border-top:1.6px dashed var(--muted); vertical-align:middle; margin-right:6px; }
/* Chart-less fallback: two plain comparison chips (no line swatches) when there's no
   index series to draw, so the legend can't dangle over empty space. */
.returns-compare { display:flex; gap:10px; margin-top:10px; }
.returns-compare .rc-stat { flex:1; display:flex; flex-direction:column; gap:2px; padding:9px 12px; background:var(--surface-2); border-radius:var(--radius-sm); }
.returns-compare .rc-k { font-size:11px; color:var(--muted); }
.returns-compare .rc-v { font-size:16px; font-weight:650; color:var(--text); font-variant-numeric:tabular-nums; }
.returns-note { font-size:11px; color:var(--muted-2); margin-top:8px; line-height:1.45; }

/* ---- zero-state action card (Overview, no accounts yet) ---- */
.empty-hero { text-align:center; background:linear-gradient(135deg, var(--accent-soft), var(--surface));
  border:1px solid var(--line); border-radius:var(--radius); padding:24px 20px; margin:4px 0 18px; }
.empty-hero[hidden] { display:none; }
.empty-hero h2 { margin:0 0 6px; font-size:18px; }
.empty-hero p { margin:0 auto 16px; max-width:34ch; color:var(--muted); font-size:14px; line-height:1.45; }
.empty-hero-actions { display:flex; gap:10px; justify-content:center; flex-wrap:wrap; }
.empty-hero-foot { margin:14px auto 0; font-size:12px; color:var(--muted); opacity:.85; }

/* ---- "why pay" positioning line in the upgrade sheet ---- */
.upgrade-why { margin:2px 0 14px; padding:10px 12px; border-radius:var(--radius-sm);
  background:var(--hover); border:1px solid var(--line); color:var(--muted); font-size:12px; line-height:1.45; }

/* ---- crypto coverage honesty (major-tokens chip + DeFi disclosure) ---- */
.cov-chip { display:inline-block; font-size:10px; font-weight:700; letter-spacing:.02em; text-transform:uppercase;
  color:var(--muted); background:var(--hover); border:1px solid var(--line); border-radius:6px; padding:1px 6px; margin-left:6px; vertical-align:middle; }
/* "DeFi not counted" reads as upside ("your true total may be higher"), so it takes the
   brand accent rather than the neutral major-tokens grey — a soft nudge, not an error. */
.cov-chip.defi { color:var(--accent); background:var(--accent-soft); border-color:transparent; }
.crypto-coverage-note { margin-top:10px; }

/* ---- admin: DeFi demand backlog (read-only build-order signal) ---- */
.defi-backlog { display:flex; flex-direction:column; gap:8px; }
.defi-bk-item { display:flex; flex-direction:column; }
.defi-bk-row { display:flex; align-items:center; gap:12px; width:100%; padding:10px 12px; background:var(--surface-2);
  border:1px solid var(--line); border-radius:var(--radius-sm); text-align:left; font:inherit; color:inherit; cursor:pointer; }
.defi-bk-row:hover { background:var(--hover); }
.defi-bk-main { flex:1; min-width:0; }
.defi-bk-title { font-weight:650; font-size:14px; }
.defi-bk-pattern { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.02em;
  color:var(--muted); background:var(--hover); border-radius:6px; padding:1px 6px; margin-left:7px; vertical-align:middle; }
.defi-bk-ex { font-size:12px; color:var(--muted); margin-top:3px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.defi-bk-stats { display:flex; flex-direction:column; align-items:flex-end; gap:1px; flex:none; font-size:12px; color:var(--muted); }
.defi-bk-stat b { color:var(--text); font-size:14px; }
.defi-bk-chev { flex:none; color:var(--muted); font-size:18px; line-height:1; transition:transform .15s ease; }
.defi-bk-row[aria-expanded="true"] .defi-bk-chev { transform:rotate(90deg); }
.defi-bk-detail { display:flex; flex-direction:column; gap:1px; padding:4px 6px 2px; }
/* `display:flex` above outranks the UA `[hidden]{display:none}` (same specificity,
   later wins), so toggling the detail's `hidden` failed to collapse it. Restore it. */
.defi-bk-detail[hidden] { display:none; }
.defi-bk-note { font-size:12px; color:var(--muted); padding:8px 6px; }
.defi-pos { display:flex; align-items:center; gap:10px; padding:7px 8px; border-radius:8px; text-decoration:none; color:inherit; }
.defi-pos:hover { background:var(--surface-2); }
.defi-pos-sym { font-weight:600; font-size:13px; flex:none; max-width:40%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.defi-pos-addr { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:var(--muted); }
.defi-pos-meta { margin-left:auto; font-size:12px; color:var(--muted); white-space:nowrap; }
.defi-pos-ext { flex:none; color:var(--muted); font-size:11px; }

/* ---- cash-flow tile (money in vs out) ---- */
.cashflow-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:4px; }
.cf-cell { background:var(--hover); border:1px solid var(--line); border-radius:var(--radius-sm); padding:11px 13px; }
.cf-label { font-size:12px; color:var(--muted); margin-bottom:3px; }
.cf-value { font-size:19px; font-weight:700; color:var(--text); }
.cf-value.green { color:var(--accent); }
.cf-value.red { color:var(--red); }
@media (min-width:560px) { .cashflow-grid { grid-template-columns:repeat(4,1fr); } }

/* ---- copilot cap → inline upgrade card (instead of a dead red error) ---- */
.copilot-msg.upsell { background:linear-gradient(135deg, var(--accent-soft), var(--surface));
  border:1px solid var(--line-strong); display:flex; flex-direction:column; align-items:flex-start; gap:10px; }
.copilot-upsell-text { margin:0; font-size:14px; line-height:1.45; color:var(--text); }
.copilot-upsell-btn { align-self:stretch; }
/* A Pro-tool upsell button appended under a normal assistant answer bubble. */
.copilot-msg.assistant .copilot-upsell-btn { display:block; margin-top:10px; }
/* Free-tier message meter under the copilot input. */
.copilot-quota { margin:8px 2px 0; text-align:center; font-size:12px; }

/* ---- X Signal Report (Pro) ---- */
.signal-theme { font-size:14px; font-weight:600; color:var(--text); margin:2px 0 12px; }
/* read-time intelligence layer (Tier A+B): lead headline, portfolio rollup, and the
   per-post direction / size / NEW / corroboration / claim / catalyst affordances. */
.signal-lead { font-size:15px; font-weight:600; line-height:1.45; color:var(--text); margin:2px 0 10px; }
/* Tier C — the synthesized cross-account narrative ("Today's story"), above the lead. */
.signal-synth { border:1px solid var(--line); border-radius:14px; background:var(--surface-2); padding:12px 14px; margin:2px 0 14px; }
.signal-synth-head { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--accent); margin-bottom:6px; }
.signal-synth-headline { font-size:15px; font-weight:600; line-height:1.4; color:var(--text); margin:0 0 8px; }
.signal-synth-story { padding:8px 0; border-top:1px solid var(--line); }
.signal-synth-story:last-child { padding-bottom:0; }
.signal-synth-title { font-size:13px; font-weight:600; color:var(--text); display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.signal-synth-summary { font-size:13px; line-height:1.5; color:var(--muted); margin:3px 0 0; }
.signal-synth-accts { font-size:11px; color:var(--muted); margin-top:4px; }
.signal-synth-stance { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.3px; padding:1px 7px; border-radius:999px; background:var(--hover); color:var(--muted); }
.signal-synth-stance.bullish { background:var(--accent-soft); color:var(--positive); }
.signal-synth-stance.bearish { background:var(--red-soft); color:var(--red); }
.signal-synth-stance.mixed { background:var(--hover); color:var(--muted); }
.signal-synth-pending { font-size:13px; color:var(--muted); font-style:italic; margin:2px 0 12px; }
.signal-rollup { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 14px; }
.signal-rollup:empty { display:none; }
.signal-roll-chip { font-size:11px; font-weight:600; padding:2px 9px; border-radius:999px; background:var(--hover); color:var(--muted); }
.signal-roll-chip.bear { background:var(--red-soft); color:var(--red); }
.signal-roll-chip.bull { background:var(--accent-soft); color:var(--accent); }
.signal-badges { display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:1px 0 5px; }
.signal-dir { font-size:11px; font-weight:700; }
.signal-dir.bear { color:var(--red); }
.signal-dir.bull { color:var(--positive); }
.signal-chip { font-size:11px; font-weight:600; padding:1px 7px; border-radius:999px; background:var(--hover); color:var(--muted); }
.signal-chip.new { background:var(--accent-soft); color:var(--accent); letter-spacing:.3px; }
.signal-claim { font-size:11px; font-weight:700; padding:1px 7px; border-radius:999px; background:var(--accent-soft); color:var(--accent); }
.signal-corr { font-size:12px; font-weight:600; color:var(--muted); margin:1px 0 4px; }
.signal-cat { font-size:12px; font-weight:600; color:var(--text); margin:1px 0 4px; }
.signal-also { font-size:11px; color:var(--muted); margin-top:5px; }
.signal-item.echo { opacity:.82; }
.signal-item.echo .signal-syn { font-size:13px; }
.signal-item { padding:12px 0; border-top:1px solid var(--line); }
.signal-item:first-of-type { border-top:none; }
.signal-item-head { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:4px; }
.signal-handle { font-weight:600; font-size:13px; color:var(--text); }
.signal-tk { font-size:11px; font-weight:600; padding:1px 7px; border-radius:999px; background:var(--hover); color:var(--muted); }
.signal-tk.held { background:var(--accent); color:#00210f; }
[data-theme="light"] .signal-tk.held { color:#fff; }
.signal-syn { font-size:14px; line-height:1.5; color:var(--text); }
.signal-why { font-size:13px; line-height:1.45; color:var(--muted); margin-top:3px; }
.signal-item-foot { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:7px; }
.signal-foot-left { display:flex; align-items:center; gap:10px; min-width:0; flex:1 1 auto; }
.signal-time { font-size:12px; color:var(--muted); white-space:nowrap; flex:none; }
.signal-eng { font-size:12px; color:var(--muted); letter-spacing:.2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.signal-src { font-size:12px; font-weight:600; color:var(--accent); text-decoration:none; white-space:nowrap; }
.signal-src:hover { text-decoration:underline; }
.signal-item-actions { display:flex; align-items:center; gap:14px; flex:none; }
.signal-share { appearance:none; -webkit-appearance:none; background:none; border:none; padding:0; cursor:pointer;
  font:inherit; font-size:12px; font-weight:600; color:var(--muted); white-space:nowrap; }
.signal-share:hover { color:var(--text); text-decoration:underline; }
/* Free teaser: counts + theme above the Pro lock (reuses .research-teaser-lock). */
.signal-teaser-lead { font-size:14px; line-height:1.5; color:var(--text); margin:2px 0 14px; }
/* Overlay-header actions: a "Manage" shortcut to the (bottom-of-sheet) account editor,
   beside the close X. A quiet outlined pill — a nav shortcut, not a primary CTA. */
.signal-head-actions { display:flex; align-items:center; gap:8px; flex:none; }
.signal-manage-btn { display:inline-flex; align-items:center; gap:6px; flex:none; line-height:1;
  background:var(--surface-2); color:var(--text); border:1px solid var(--line); font-weight:600;
  font-size:13px; padding:6px 12px; border-radius:999px; cursor:pointer; min-height:0; }
.signal-manage-btn:hover { border-color:var(--muted); }
.signal-manage-btn:active { transform:scale(.97); }
.signal-manage-btn svg { width:15px; height:15px; }
/* On very narrow screens collapse to the icon so the headline never wraps. */
@media (max-width:360px) { .signal-manage-btn span { display:none; } .signal-manage-btn { padding:6px; } }
/* Brief history nav in the overlay header (‹ Today ›). */
.signal-day-nav { display:flex; align-items:center; gap:10px; margin-top:6px; }
.signal-day-arrow { appearance:none; -webkit-appearance:none; width:24px; height:24px; padding:0; line-height:1;
  border:1px solid var(--line); border-radius:7px; background:var(--surface-2); color:var(--text);
  font-size:15px; cursor:pointer; }
.signal-day-arrow:hover:not(:disabled) { border-color:var(--muted); }
.signal-day-arrow:disabled { opacity:.4; cursor:default; }
.signal-day-label { font-size:12px; font-weight:600; color:var(--muted); min-width:54px; text-align:center; }
/* manage-accounts panel */
.signal-manage { margin-top:16px; padding-top:14px; border-top:1px solid var(--line); }
.signal-manage-head { font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin-bottom:8px; }
.signal-list { display:flex; flex-direction:column; gap:6px; }
.signal-handle-row { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:7px 10px; border-radius:10px; background:var(--surface); font-size:13px; }
/* `display:flex` above is an author rule, so it outranks the UA `[hidden]{display:none}`
   (author origin wins regardless of specificity) — without this the collapsed "+N more"
   extra rows render anyway, so the list starts fully expanded and the toggle does nothing.
   Mirrors the same fix on .earn-row / .defi-bk-detail. */
.signal-handle-row[hidden] { display:none; }
.signal-handle-id { display:flex; align-items:center; gap:10px; min-width:0; }
.signal-handle-id .signal-av { width:30px; height:30px; }
.signal-handle-at { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.signal-remove { border:none; background:transparent; color:var(--muted); font-size:12px; font-weight:600; cursor:pointer; padding:2px 4px; }
.signal-remove:hover { color:var(--red); }
/* Touch a11y for the small signal controls: press feedback everywhere (iOS has no
   :hover) + a 44pt hit-area on the icon day-arrows. Inline text buttons get feedback
   only (a 44pt ::before would overlap their neighbours). */
.signal-share:active, .signal-remove:active { opacity:.6; }
.signal-day-arrow:active:not(:disabled) { transform:scale(.9); }
.signal-day-arrow { position:relative; }
.signal-day-arrow::before { content:""; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:44px; height:44px; }
.signal-add { display:flex; gap:8px; margin-top:10px; }
.signal-add input { flex:1; min-width:0; padding:9px 12px; border-radius:10px; border:1px solid var(--line); background:var(--bg); color:var(--text); font-size:14px; }
.signal-add input:focus { outline:none; border-color:var(--accent); }
.signal-add-hint { font-size:12px; color:var(--muted); margin:8px 2px 0; min-height:1em; }
.signal-sec-head { font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--accent); margin:14px 0 2px; }
.signal-sec-head.muted { color:var(--muted); }
.signal-sec-head:first-of-type { margin-top:4px; }
/* ---- add-account typeahead ---- */
.signal-suggest { margin-top:8px; border:1px solid var(--line); border-radius:12px; overflow-y:auto; -webkit-overflow-scrolling:touch; touch-action:pan-y; max-height:46vh; background:var(--bg); }
.signal-sg-head { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); padding:9px 12px 4px; }
.signal-sg-row { display:flex; align-items:center; gap:10px; width:100%; text-align:left; padding:9px 11px; border:none; border-top:1px solid var(--line); background:transparent; cursor:pointer; color:var(--text); }
.signal-sg-row:first-child { border-top:none; }
.signal-sg-head + .signal-sg-row { border-top:none; }
.signal-sg-row:hover:not(:disabled) { background:var(--hover); }
.signal-sg-row:disabled { cursor:default; opacity:.55; }
.signal-av { position:relative; flex:none; width:34px; height:34px; border-radius:50%; overflow:hidden; background:var(--hover); display:grid; place-items:center; }
.signal-av b { font-size:14px; font-weight:700; color:var(--muted); }
/* No background on the img: the parent .signal-av supplies the grey ring, so a 0×0
   broken img can't paint an opaque disc over the monogram before it's removed. */
.signal-av img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.signal-av.search { font-size:17px; color:var(--muted); }
.signal-sg-main { display:flex; flex-direction:column; min-width:0; flex:1; }
.signal-sg-name { font-size:14px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.signal-sg-sub { font-size:12px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.signal-sg-plus { flex:none; font-size:20px; line-height:1; font-weight:600; color:var(--accent); }
.signal-sg-following { flex:none; font-size:11px; color:var(--muted); }
.signal-sg-empty { padding:12px; font-size:13px; color:var(--muted); }
.signal-sg-search .signal-sg-name { color:var(--accent); }
/* ---- Explore: browse the full catalog by category ---- */
.signal-explore-chips { display:flex; flex-wrap:nowrap; gap:6px; overflow-x:auto; padding:9px 10px;
  border-bottom:1px solid var(--line); -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.signal-explore-chips::-webkit-scrollbar { display:none; }
.signal-explore-chip { flex:0 0 auto; font:inherit; font-size:11px; font-weight:700; letter-spacing:.3px; padding:5px 11px;
  border:none; border-radius:999px; cursor:pointer; background:var(--surface-2); color:var(--muted); transition:.15s var(--ease); }
.signal-explore-chip:hover { color:var(--text); }
.signal-explore-chip.active { background:var(--accent-soft); color:var(--accent); }
.signal-explore-list { max-height:320px; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.signal-explore-list .signal-sg-head:first-child { border-top:none; }

/* ===================== Podcast "Tape" ===================== */
#podcastsBody { display:flex; flex-direction:column; gap:10px; }
.podcast-eps { display:flex; flex-direction:column; gap:10px; }
/* per-show filter chips */
.podcast-filter { display:flex; flex-wrap:nowrap; gap:6px; overflow-x:auto; padding-bottom:2px;
  -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.podcast-filter::-webkit-scrollbar { display:none; }
.podcast-chip { flex:0 0 auto; font:inherit; font-size:11px; font-weight:700; letter-spacing:.3px; padding:5px 11px;
  border:none; border-radius:999px; cursor:pointer; background:var(--surface-2); color:var(--muted); transition:.15s var(--ease); }
.podcast-chip:hover { color:var(--text); }
.podcast-chip.active { background:var(--accent-soft); color:var(--accent); }
.podcast-showmore { align-self:flex-start; font:inherit; font-size:13px; font-weight:600; cursor:pointer;
  background:none; border:none; color:var(--accent); padding:4px 2px; }
.podcast-showmore:hover { text-decoration:underline; }
.podcast-empty { text-align:center; padding:14px 8px 6px; color:var(--muted); font-size:14px; line-height:1.5; }
.podcast-empty .btn-primary { margin-top:12px; }
.podcast-card { display:flex; gap:12px; align-items:flex-start; width:100%; text-align:left; cursor:pointer;
  background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius-sm); padding:10px; font:inherit;
  transition:border-color .15s var(--ease), transform .04s var(--ease); }
.podcast-card:hover { border-color:var(--accent); }
.podcast-card:active { transform:scale(.995); }
.podcast-thumb { width:96px; height:54px; flex:0 0 auto; border-radius:10px; overflow:hidden;
  background:var(--surface-2); display:block; }
.podcast-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.podcast-card-main { min-width:0; flex:1; }
.podcast-show { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.4px; color:var(--muted);
  display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.podcast-title { font-size:14px; font-weight:600; color:var(--text); line-height:1.35; margin:3px 0 0;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
/* The episode-overlay heading is a raw YouTube title (uncontrolled, routinely
   80-120+ chars); clamp it to 2 lines so it can't push the player down the sheet. */
#podcastEpTitle { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.podcast-lead { font-size:13px; color:var(--accent); font-weight:600; margin-top:4px; line-height:1.4; }
.podcast-held { color:var(--accent); font-weight:700; }
.podcast-date { color:var(--muted-2); font-weight:600; text-transform:none; letter-spacing:0; }
.podcast-date::before { content:"·"; margin-right:6px; color:var(--muted-2); }
.podcast-status { color:var(--muted-2); font-weight:600; text-transform:none; letter-spacing:0; }
.podcast-callcount { color:var(--muted-2); font-weight:600; text-transform:none; letter-spacing:0; }

/* episode overlay */
.podcast-player { width:100%; aspect-ratio:16/9; background:#000; border-radius:12px; overflow:hidden; margin-bottom:12px; }
.podcast-player iframe, .podcast-player #ytPlayerMount { width:100%; height:100%; border:0; }
.podcast-linkout { display:flex; align-items:center; justify-content:center; width:100%; height:100%; color:#fff;
  text-decoration:none; font-weight:700; font-size:15px; }
.podcast-foryou { font-size:15px; font-weight:600; line-height:1.45; color:var(--text); margin:0 0 12px; }
/* Demo-tour placeholder where the real YouTube player mounts (no video in the offline tour). */
.podcast-demo-player { display:grid; place-items:center; text-align:center; aspect-ratio:16/9; border-radius:12px;
  background:var(--surface-2); border:1px dashed var(--line); color:var(--muted); font-size:13px; padding:16px; }
.podcast-call { border-top:1px solid var(--line); padding:12px 0; }
.podcast-call:first-of-type { border-top:none; }
.podcast-call-head { display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:14px; }
.podcast-name { font-weight:700; color:var(--text); }
.podcast-heldchip { font-size:10px; font-weight:800; letter-spacing:.4px; padding:3px 8px; border-radius:999px;
  background:var(--accent-soft); color:var(--accent); }
.podcast-tickerchip { font-size:11px; font-weight:700; padding:2px 7px; border-radius:999px; background:var(--surface-2); color:var(--muted); }
.podcast-nametag { font-size:11px; font-weight:600; color:var(--muted-2); font-style:italic; }
.podcast-stance { font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.4px; padding:2px 7px; border-radius:999px; }
.podcast-stance.bullish { background:var(--accent-soft); color:var(--accent); }
.podcast-stance.bearish { background:var(--red-soft); color:var(--red); }
.podcast-conv { font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.4px; color:var(--red); }
.podcast-quote { margin:8px 0 0; padding:0 0 0 12px; border-left:3px solid var(--accent-soft);
  font-size:14px; line-height:1.5; color:var(--text); font-style:italic; }
.podcast-quote.blurred { filter:blur(4px); user-select:none; border-left-color:var(--line); font-style:normal; }
.podcast-call-foot { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:8px; }
.podcast-speaker { font-size:12px; color:var(--muted); font-weight:600; }
.podcast-jump { font:inherit; font-size:12px; font-weight:700; cursor:pointer; padding:4px 10px; border-radius:999px;
  border:1px solid var(--line); background:var(--surface-2); color:var(--accent); }
.podcast-jump:hover { border-color:var(--accent); }
.podcast-more { margin-top:6px; }
.podcast-more > summary { cursor:pointer; font-size:13px; font-weight:600; color:var(--muted); padding:8px 0; list-style:none; }
.podcast-more > summary::-webkit-details-marker { display:none; }
.podcast-lock { text-align:center; padding:14px 8px; color:var(--muted); font-size:13px; line-height:1.5;
  border-top:1px solid var(--line); margin-top:4px; }
.podcast-lock .btn-primary { margin-top:10px; }

/* manage/catalog sheet */
.podcast-catalog-list { max-height:60vh; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.podcast-cat-row { display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:11px 2px; border-top:1px solid var(--line); }
.podcast-cat-row:first-child { border-top:none; }
.podcast-cat-name { font-size:14px; font-weight:600; color:var(--text); }
.podcast-cat-cat { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.4px; color:var(--muted-2); margin-top:2px; }
.podcast-follow.on { color:var(--accent); border-color:var(--accent); }
