/* CountAhead application foundations. The public Landing keeps its dedicated
   stylesheet; these tokens serve authenticated and auth product surfaces. */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/vendor/inter/InterVariable.woff2") format("woff2");
}

:root,
[data-theme="light"] {
  color-scheme: light;
  /* E12-05 Visual Vitality: "warm paper" -- a three-level surface model
     (chrome --sidebar-bg, lighter than the canvas; canvas --app-bg; cards
     --surface) on barely-perceptible warm neutrals, so cards read by tone
     rather than by a border on every edge. (E12-05-016 introduced the
     canvas step; this retunes it warm.) */
  --app-bg: #f4f2ee;
  --surface: #ffffff;
  --surface-alt: #f7f5f2;
  --surface-raised: #ffffff;
  --surface-hover: #f3f1ed;
  --surface-selected: #efece7;
  --sidebar-bg: #fbfaf8;
  --sidebar-text: #5f5a54;
  --sidebar-text-active: #1b1a18;
  --sidebar-hover-bg: #f3f1ed;
  --sidebar-border: #e7e3dd;
  --border: #e7e3dd;
  --text: #1b1a18;
  /* E12-05 text tiers: primary (headings, names, figures), secondary
     (body and table data), muted (metadata, helper, column headers --
     genuinely tertiary), faint (placeholders, disabled). */
  --text-secondary: #3f3c38;
  --text-muted: #6b6660;
  --text-faint: #9a948c;
  --brand-orange: #fc4801;
  --accent: #c2410c;
  --accent-hover: #a3360a;
  --accent-contrast: #ffffff;
  --action-primary: #2f6fed;
  --action-primary-hover: #2559c4;
  --action-primary-contrast: #ffffff;
  --focus: #c2410c;
  --data-blue: #2f6fed;
  --data-teal: #0d9488;
  /* E11-NEXTFIX-009/011 root cause: these 8 series colors were only ever
     defined scoped to `.investment-category-panel` (the Portfolio
     Overview category donut), never as global tokens. WealthCast Value
     History and Performance History (presenters/wealthcast.py) render
     their line/point colors as `var(--investment-chart-N)` on pages
     that never carry that class -- an undefined custom property makes
     `stroke` resolve to nothing, so the chart geometry (points, axes)
     was always correct but literally invisible. Promoted to :root so
     every chart that references them renders correctly everywhere.
     Same values as before -- no visual change to the donut that already
     used them. */
  --investment-chart-1: hsl(217 91% 60%);
  --investment-chart-2: hsl(142 71% 45%);
  --investment-chart-3: hsl(38 92% 50%);
  --investment-chart-4: hsl(0 72% 51%);
  --investment-chart-5: hsl(262 83% 58%);
  --investment-chart-6: hsl(188 86% 42%);
  --investment-chart-7: hsl(326 78% 49%);
  --investment-chart-8: hsl(84 81% 44%);
  /* WD-01: the categorical IDENTITY palette for WealthCast History series
     and Portfolio Overview charts -- 20 measured, mutually distinct steps,
     each with its own Light and Dark value and the ink that stays readable
     on it. A slot means "which one", never gain or loss. Slots are assigned
     by stable identity (domain/chart_palette.py), never by list position.
     The eight tokens above are the older sequence other charts still use. */
  /* investment-chart-series:light:start */
  --investment-chart-series-1: #3b82f6;
  --investment-chart-series-1-ink: #000000;
  --investment-chart-series-2: #22c55e;
  --investment-chart-series-2-ink: #000000;
  --investment-chart-series-3: #ef4444;
  --investment-chart-series-3-ink: #000000;
  --investment-chart-series-4: #f97f16;
  --investment-chart-series-4-ink: #000000;
  --investment-chart-series-5: #eab308;
  --investment-chart-series-5-ink: #000000;
  --investment-chart-series-6: #06b6d4;
  --investment-chart-series-6-ink: #000000;
  --investment-chart-series-7: #ec4899;
  --investment-chart-series-7-ink: #000000;
  --investment-chart-series-8: #a3d312;
  --investment-chart-series-8-ink: #000000;
  --investment-chart-series-9: #0d9488;
  --investment-chart-series-9-ink: #000000;
  --investment-chart-series-10: #1d4ed8;
  --investment-chart-series-10-ink: #ffffff;
  --investment-chart-series-11: #15803d;
  --investment-chart-series-11-ink: #ffffff;
  --investment-chart-series-12: #c026d3;
  --investment-chart-series-12-ink: #ffffff;
  --investment-chart-series-13: #8b5cf6;
  --investment-chart-series-13-ink: #000000;
  --investment-chart-series-14: #9f1239;
  --investment-chart-series-14-ink: #ffffff;
  --investment-chart-series-15: #7cc4f5;
  --investment-chart-series-15-ink: #000000;
  --investment-chart-series-16: #8a4a1e;
  --investment-chart-series-16-ink: #ffffff;
  --investment-chart-series-17: #b08a12;
  --investment-chart-series-17-ink: #000000;
  --investment-chart-series-18: #b3a0f2;
  --investment-chart-series-18-ink: #000000;
  --investment-chart-series-19: #fb9a8a;
  --investment-chart-series-19-ink: #000000;
  --investment-chart-series-20: #5b21b6;
  --investment-chart-series-20-ink: #ffffff;
  /* investment-chart-series:light:end */
  /* Total is the one neutral series: black here, white in Dark. Neither is
     one of the 20 series colours in its theme. */
  --investment-chart-total: #000000;
  /* The grouped remainder of a ranked chart ("Other") is not an identity. */
  --investment-chart-other: #b3ada4;
  --danger: #bf2640;
  --danger-bg: #fbe9ec;
  --success: #1f7a4d;
  --success-bg: #e9f6ef;
  --warning: #8a5a00;
  --warning-bg: #fbf1de;
  /* `--warning` is tuned as a small text/icon color against `--warning-bg`
     (e.g. `.badge-warning`) -- used as a large solid fill (a composition
     bar segment or chart swatch) it reads as muddy brown rather than an
     obvious amber warning. `--warning-fill` is the same warning semantic,
     just a brighter tone meant specifically for solid-fill contexts. */
  --warning-fill: #d97706;
  /* E12-04 Summary Card DOMAIN IDENTITY tokens (one set per domain:
     edge = 3px inset identity edge, label = uppercase summary label ink,
     tint = card surface, border = card border). Identity only -- never a
     financial state -- and deliberately independent of the semantic
     success/warning/danger tokens above, so a status retune can never
     recolor a domain (and vice versa). Identities: Accounts Sapphire,
     Income Jade, Loans Ocean (approved "gemstone" anchors); Bills Copper,
     Savings Gold ("metal" identities, approved); One-Time Clay Rose
     (visual-smoke candidate): a muted, cool red at ~half the saturation
     of `--danger` -- identity, never an error/negative state. */
  --domain-accounts-edge: #2451b8;
  --domain-accounts-label: #1d418f;
  --domain-accounts-tint: #f3f6fc;
  --domain-accounts-border: #d6def2;
  --domain-income-edge: #0f8a64;
  --domain-income-label: #0b6b4e;
  --domain-income-tint: #f0f8f5;
  --domain-income-border: #cfe8de;
  --domain-bills-edge: #a55127;
  --domain-bills-label: #7c3d1d;
  --domain-bills-tint: #f9f4f0;
  --domain-bills-border: #ead7cd;
  --domain-savings-edge: #a77f1b;
  --domain-savings-label: #6f5712;
  --domain-savings-tint: #f9f6eb;
  --domain-savings-border: #e9dfc4;
  --domain-loans-edge: #107093;
  --domain-loans-label: #0d5873;
  --domain-loans-tint: #eff7fa;
  --domain-loans-border: #c8e1ea;
  --domain-one-time-edge: #a6595d;
  --domain-one-time-label: #723b3e;
  --domain-one-time-tint: #faf5f5;
  --domain-one-time-border: #e7d5d5;
  --domain-investments-edge: #6a8230;
  --domain-investments-label: #4a5d1d;
  --domain-investments-tint: #f6f9f1;
  --domain-investments-border: #dee6cc;
  --domain-investment-accounts-edge: #874085;
  --domain-investment-accounts-label: #5e265c;
  --domain-investment-accounts-tint: #f9f3f9;
  --domain-investment-accounts-border: #e6d1e5;
  /* E12-04 Family: a leaf green, distinct from Income's emerald and
     Contribution Room's moss; a slightly stronger tint so the identity
     stays visible on the neutral page. */
  --domain-family-edge: #2f8a3e;
  --domain-family-label: #1d6329;
  --domain-family-tint: #e9f5eb;
  --domain-family-border: #bcdcc3;
  --badge-neutral-bg: #efece7;
  --badge-neutral-text: #4a453f;
  --shadow: 0 1px 2px rgba(30, 25, 20, 0.05);
  --shadow-menu: 0 12px 30px rgba(30, 25, 20, 0.12), 0 2px 8px rgba(30, 25, 20, 0.06);
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;

  /* E12-05 Orange grammar: Orange marks POSITION (active navigation, the
     selected view/range, current/today, focus) -- drawn as a rail, bar,
     dot or tint, never as body text and never on an amount, badge, chart
     series or warning. Blue (--action-primary) stays the ACTION language
     (buttons, links, checked form controls). The one shared selected-view
     recipe below is what every tab / range / view control consumes. */
  --brand-tint: color-mix(in srgb, var(--brand-orange) 7%, var(--surface));
  --brand-line: color-mix(in srgb, var(--brand-orange) 45%, var(--border));
  --selected-ink: var(--text);
  --selected-tint: var(--brand-tint);
  --selected-line: var(--brand-line);
  --selected-mark: var(--brand-orange);
  /* E12-05: one financial-direction language (MonthCast amounts, Calendar
     edges, One-Time direction cue) -- the semantic green / red softened
     toward the text colour. Never Orange. */
  --flow-inflow: color-mix(in srgb, var(--success) 78%, var(--text));
  --flow-outflow: color-mix(in srgb, var(--danger) 72%, var(--text));
  /* E12-05: the strong-warning step of a red..amber semantic scale
     (Financial Health "Needs Attention") -- a half-saturation terracotta,
     deliberately distinct from the vivid brand Orange. */
  --warning-strong: #a65238;
  --bg-subtle: var(--surface-alt);
  /* E12-05 typography roles (Inter; see docs/DESIGN_SYSTEM.md). */
  --fs-2xs: 0.6875rem;
  --fs-xs: 0.75rem;
  --fs-sm: 0.8125rem;
  --fs-base: 0.875rem;
  --fs-md: 1rem;
  --fs-lg: 1.125rem;
  --fs-xl: 1.5rem;
  --fs-2xl: clamp(1.75rem, 3vw, 2.125rem);
  --fw-regular: 450;
  --fw-medium: 540;
  --fw-semibold: 620;
  --fw-bold: 700;
  --lh-tight: 1.15;
  --lh-snug: 1.35;
  --lh-body: 1.5;
  --tracking-body: -0.006em;
  --tracking-title: -0.015em;
  --tracking-figure: -0.03em;
  --tracking-caps: 0.04em;
  /* E12-05 surfaces: on the warm canvas a card reads by tone, so its edge
     is a softened hairline in Light (full strength in Dark). */
  --card-border: color-mix(in srgb, var(--border) 62%, transparent);
}

[data-theme="dark"] {
  color-scheme: dark;
  --app-bg: #121110;
  /* E12-05 Dark refinement: the canvas and chrome keep their warm charcoal,
     but card / raised / hover surfaces (and the hairline they use) are
     NEUTRAL charcoal -- layered by luminance, not hue -- so cards and chart
     plots never read brown or reddish. */
  --surface: #1c1c1d;
  --surface-alt: #161617;
  --surface-raised: #232324;
  --surface-hover: #28282a;
  --surface-selected: #2c2c2e;
  --sidebar-bg: #0d0c0b;
  --sidebar-text: #a39d94;
  --sidebar-text-active: #f1eee8;
  --sidebar-hover-bg: #1f1d1a;
  --sidebar-border: #2f2b27;
  --border: #303033;
  --text: #f1eee8;
  --text-secondary: #c9c4bc;
  --text-muted: #9a948b;
  --text-faint: #6c665e;
  --brand-orange: #fc4801;
  --accent: #ff6a2b;
  --accent-hover: #ff8050;
  --accent-contrast: #0d0c0b;
  --action-primary: #5088f7;
  --action-primary-hover: #6d9cf9;
  --action-primary-contrast: #06090f;
  --focus: #ff6a2b;
  --data-blue: #6d9cf9;
  --data-teal: #2dd4bf;
  /* investment-chart-series:dark:start */
  --investment-chart-series-1: #60a5fa;
  --investment-chart-series-1-ink: #000000;
  --investment-chart-series-2: #4ade80;
  --investment-chart-series-2-ink: #000000;
  --investment-chart-series-3: #f87171;
  --investment-chart-series-3-ink: #000000;
  --investment-chart-series-4: #fb923c;
  --investment-chart-series-4-ink: #000000;
  --investment-chart-series-5: #facc15;
  --investment-chart-series-5-ink: #000000;
  --investment-chart-series-6: #22d3ee;
  --investment-chart-series-6-ink: #000000;
  --investment-chart-series-7: #f472b6;
  --investment-chart-series-7-ink: #000000;
  --investment-chart-series-8: #bef264;
  --investment-chart-series-8-ink: #000000;
  --investment-chart-series-9: #14b8a6;
  --investment-chart-series-9-ink: #000000;
  --investment-chart-series-10: #4f6ff0;
  --investment-chart-series-10-ink: #000000;
  --investment-chart-series-11: #1f9d55;
  --investment-chart-series-11-ink: #000000;
  --investment-chart-series-12: #e879f9;
  --investment-chart-series-12-ink: #000000;
  --investment-chart-series-13: #a78bfa;
  --investment-chart-series-13-ink: #000000;
  --investment-chart-series-14: #e0366f;
  --investment-chart-series-14-ink: #000000;
  --investment-chart-series-15: #9cc8f8;
  --investment-chart-series-15-ink: #000000;
  --investment-chart-series-16: #b9713a;
  --investment-chart-series-16-ink: #000000;
  --investment-chart-series-17: #b8a23a;
  --investment-chart-series-17-ink: #000000;
  --investment-chart-series-18: #cdb8fb;
  --investment-chart-series-18-ink: #000000;
  --investment-chart-series-19: #fdb0a3;
  --investment-chart-series-19-ink: #000000;
  --investment-chart-series-20: #8647ef;
  --investment-chart-series-20-ink: #ffffff;
  /* investment-chart-series:dark:end */
  --investment-chart-total: #ffffff;
  --investment-chart-other: #6b6762;
  --danger: #f06674;
  --danger-bg: #2e1519;
  --success: #5fce97;
  --success-bg: #10281c;
  --warning: #e5b567;
  --warning-bg: #2a2110;
  --warning-fill: #f0b429;
  --domain-accounts-edge: #6f98f5;
  --domain-accounts-label: #a9c1fa;
  --domain-accounts-tint: #172238;
  --domain-accounts-border: #2c3f66;
  --domain-income-edge: #3fcf9b;
  --domain-income-label: #8fe3c2;
  --domain-income-tint: #132822;
  --domain-income-border: #235443;
  --domain-bills-edge: #dd8d5f;
  --domain-bills-label: #f3d0ba;
  --domain-bills-tint: #2b1e17;
  --domain-bills-border: #5d4232;
  --domain-savings-edge: #dfb749;
  --domain-savings-label: #f1e2b1;
  --domain-savings-tint: #292414;
  --domain-savings-border: #5d502d;
  --domain-loans-edge: #50bbe2;
  --domain-loans-label: #b8e4f5;
  --domain-loans-tint: #122830;
  --domain-loans-border: #2b5564;
  --domain-one-time-edge: #cb9093;
  --domain-one-time-label: #ebcbcd;
  --domain-one-time-tint: #2d1f20;
  --domain-one-time-border: #623c3e;
  --domain-investments-edge: #b0cb72;
  --domain-investments-label: #dae8ba;
  --domain-investments-tint: #222717;
  --domain-investments-border: #556138;
  --domain-investment-accounts-edge: #d284cf;
  --domain-investment-accounts-label: #ebc2e9;
  --domain-investment-accounts-tint: #271726;
  --domain-investment-accounts-border: #613860;
  --domain-family-edge: #5ec46f;
  --domain-family-label: #aee4b7;
  --domain-family-tint: #16301c;
  --domain-family-border: #2e6139;
  --badge-neutral-bg: #262320;
  --badge-neutral-text: #c2bcb3;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-menu: 0 16px 36px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.35);
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;

  /* E12-05: Dark uses the brighter accent as the mark and a slightly
     stronger tint than Light (9% vs 7%): enough to read as a warm wash on
     the darkest chrome without turning the active item brown. */
  --brand-tint: color-mix(in srgb, var(--brand-orange) 9%, var(--surface));
  --brand-line: color-mix(in srgb, var(--accent) 55%, var(--border));
  --selected-mark: var(--accent);
  --warning-strong: #d98a66;
  --card-border: var(--border);
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

.app-main {
  width: 100%;
  max-width: 100rem;
  margin-inline: auto;
}

body {
  background-color: var(--app-bg);
  color: var(--text);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  font-weight: var(--fw-regular);
  letter-spacing: var(--tracking-body);
  font-optical-sizing: auto;
}

/* E12-05 typography: the vendored Tailwind weight utilities follow the
   role scale (app.css loads after Tailwind, and component rules below
   still take precedence exactly as before). `.font-bold` is left as-is. */
.font-normal { font-weight: var(--fw-regular); }
.font-medium { font-weight: var(--fw-medium); }
.font-semibold { font-weight: var(--fw-semibold); }


a {
  color: inherit;
}

/* E7-SMOKE-UX-07/UX-11: a restrained, consistent affordance for primary
   entity links across the Admin Panel (e.g. a User email opening User
   Detail, a Family name opening Family Detail) -- recognizable as
   clickable before hover, without turning every link into a loud call to
   action. Reuses the same accent already used for "Manage ->" links
   elsewhere, and a translucent underline so the signal never depends on
   color alone. */
.entity-link {
  color: var(--action-primary);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--action-primary) 35%, transparent);
  text-underline-offset: 0.15em;
}

.entity-link:hover,
.entity-link:focus-visible {
  text-decoration-color: currentColor;
}

/* Shared keyboard focus */

:where(a, button, input, select, textarea, summary):focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 100;
  padding: 0.55rem 0.8rem;
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  color: var(--text);
  box-shadow: var(--shadow-menu);
  transform: translateY(-160%);
}

.skip-link:focus {
  transform: translateY(0);
}

.app-icon,
.sidebar-link__icon,
.sidebar-control-icon,
.account-menu__chevron {
  width: 1.15rem;
  height: 1.15rem;
  flex: 0 0 auto;
}

/* Sidebar */

.sidebar-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 2.5rem;
  padding: 0.45rem 0.7rem;
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--sidebar-text);
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.app-sidebar {
  position: sticky;
  top: 0;
  z-index: 20;
  width: 16rem;
  height: 100vh;
  overflow: visible;
  border-right: 1px solid var(--sidebar-border);
  background-color: var(--sidebar-bg);
  transition: width 0.18s ease;
}

.sidebar-nav > div + div {
  padding-top: 0.8rem;
  border-top: 0;
}

.sidebar-link:hover {
  background-color: var(--sidebar-hover-bg);
  color: var(--sidebar-text-active);
}

.sidebar-link.active {
  background-color: var(--selected-tint);
  color: var(--sidebar-text-active);
  font-weight: var(--fw-semibold);
}

.sidebar-link.active .app-icon {
  color: var(--selected-mark);
}

.sidebar-link.active::before {
  position: absolute;
  left: 0;
  width: 3px;
  height: 1.25rem;
  border-radius: 0 2px 2px 0;
  background: var(--selected-mark);
  content: "";
}

.nav-section-label {
  padding: 0 0.7rem;
  margin-bottom: 0.25rem;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  color: var(--text-muted);
}

.nav-icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--surface);
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
}

.nav-icon-button:hover {
  background-color: var(--surface-hover);
}

.nav-icon-button:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

:root {
  --app-mobile-header-height: calc(0.75rem + 2.5rem + 0.75rem + 1px);
  --app-desktop-header-height: 4rem;
  --app-sticky-offset: var(--app-mobile-header-height);
  --app-mobile-toast-gap: 0.625rem;
}

@media (min-width: 768px) {
  :root {
    --app-sticky-offset: var(--app-desktop-header-height);
  }
}

/* Mobile bottom nav */

.mobile-nav-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.125rem;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  text-decoration: none;
  min-height: 3.5rem;
  padding: 0.4rem 0.5rem;
  border-radius: var(--radius-md);
  flex: 1;
  text-align: center;
}

.mobile-nav-link.active {
  color: var(--accent);
  font-weight: var(--fw-semibold);
}

.mobile-nav-link.active .app-icon {
  color: var(--selected-mark);
}

.mobile-nav-link .app-icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* Cards & surfaces */

.card {
  background-color: var(--surface);
  border: 1px solid var(--card-border);
  border-radius: 0.75rem;
  box-shadow: var(--shadow);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.card:hover {
  border-color: color-mix(in srgb, var(--text-muted) 22%, var(--card-border));
}

.card.overflow-hidden {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}

.summary-card {
  display: flex;
  min-height: 6.25rem;
  justify-content: center;
  flex-direction: column;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.summary-card:hover,
a.card:hover {
  border-color: color-mix(in srgb, var(--text-muted) 28%, var(--border));
}

/* E12-04 Batch 1 (refined in the density/pre-freeze passes): shared
   active-only summary card -- Bills/Income "Total Monthly" and Accounts
   "Total Active Balance". Domain identity is a pastel color variant only
   (see _entity_macros.html::entity_summary_card for the component
   contract); each variant is the same restrained semantic-tone pair
   badges already use (never a saturated fill), so light/dark contrast is
   inherited rather than re-tuned per usage.

   Compact horizontal strip at EVERY width, not just desktop: label+note
   grouped on the left, value(s) on the right, vertically centered against
   each other -- a flat tinted strip, never a tall stacked card. Grid areas
   (not DOM order) place label/note/value, so this is CSS-only and no
   macro/template change is needed. The `.card` elevation shadow is
   replaced by the E12-04 inset domain edge (no drop shadow); the 1px
   border stays (from `.card`, domain-tinted per variant below). The mobile-first
   rule is deliberately tighter (smaller type, snugger padding, no
   max-width) than the desktop override, which only widens/loosens it --
   the composition itself is identical at both widths. */
.entity-summary-card {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "label value" "note value";
  align-items: center;
  column-gap: 0.75rem;
  row-gap: 0.05rem;
  padding: 0.55rem 0.85rem;
  min-height: 0;
  /* E12-05 (approved Decision 2): a NEUTRAL strip -- the shared card
     surface and hairline -- whose domain identity is the 3px left edge
     (an INSET shadow, so size, padding and alignment are unchanged) plus
     the domain label ink. The domain tint/border hooks are still mapped by
     each variant but are no longer painted, so no management page reads as
     a separate colour system; CountAhead Orange stays the product mark. */
  background-color: var(--surface);
  border-color: var(--card-border);
  box-shadow: inset 3px 0 0 var(--summary-edge, transparent);
}

/* Not interactive: the hairline does not react to hover like `.card`. */
.entity-summary-card:hover {
  border-color: var(--card-border);
}

.entity-summary-card__label {
  grid-area: label;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  color: var(--summary-label, var(--text-muted));
}

.entity-summary-card__value {
  grid-area: value;
  align-self: center;
  text-align: right;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: 1.25;
  color: var(--text);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.015em;
}

/* Decorative currency-identity flag (Accounts only, via `currency_flag`),
   shown only when 2+ currency rows are present (see accounts/list.html --
   a single displayed currency needs no disambiguation). Sized relative to
   the value's own font-size rather than a fixed size so it scales
   naturally between the mobile/desktop value type-scale above and the
   stacked multi-currency scale; clearly recognizable and baseline-aligned
   with the amount, but the amount's own larger, bold weight keeps it the
   dominant element. aria-hidden in the markup -- the adjacent formatted
   money text (already carrying the currency code/symbol) is the real
   accessible content. */
.entity-summary-card__value-flag {
  font-size: 1.15em;
  vertical-align: -0.12em;
}

/* Optional per-line label (`line_labels`): small, muted, and not part of
   the neutral amount's typography, so each separate total stays
   identified without competing with its value. */
.entity-summary-card__value-tag {
  margin-right: 0.35rem;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.entity-summary-card__value--stacked {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.1rem;
  font-size: var(--fs-base);
  white-space: nowrap;
}

.entity-summary-card__note {
  grid-area: note;
  font-size: var(--fs-2xs);
  color: var(--text-muted);
}

/* Tablet/desktop: same horizontal composition, just a bounded width
   (never full-page) and more generous type/spacing than the mobile-first
   rule above -- a balanced size for the content, not a stretch. */
@media (min-width: 768px) {
  .entity-summary-card {
    max-width: 26rem;
    padding: 0.65rem 1.1rem;
    column-gap: 1.25rem;
    row-gap: 0.15rem;
  }

  .entity-summary-card__label { font-size: var(--fs-sm); }

  .entity-summary-card__note { font-size: var(--fs-xs); }

  .entity-summary-card__value { font-size: 1.375rem; }

  .entity-summary-card__value--stacked { font-size: var(--fs-md); }
}

/* E12-04 Summary Card domain variants: identity hooks only. The amount
   (`__value`) stays neutral `--text` and the note stays `--text-muted`
   regardless of domain or of the value's sign/size. */
.entity-summary-card--accounts {
  --summary-edge: var(--domain-accounts-edge);
  --summary-label: var(--domain-accounts-label);
  --summary-tint: var(--domain-accounts-tint);
  --summary-border: var(--domain-accounts-border);
}

.entity-summary-card--income {
  --summary-edge: var(--domain-income-edge);
  --summary-label: var(--domain-income-label);
  --summary-tint: var(--domain-income-tint);
  --summary-border: var(--domain-income-border);
}

.entity-summary-card--bills {
  --summary-edge: var(--domain-bills-edge);
  --summary-label: var(--domain-bills-label);
  --summary-tint: var(--domain-bills-tint);
  --summary-border: var(--domain-bills-border);
}

.entity-summary-card--savings {
  --summary-edge: var(--domain-savings-edge);
  --summary-label: var(--domain-savings-label);
  --summary-tint: var(--domain-savings-tint);
  --summary-border: var(--domain-savings-border);
}

.entity-summary-card--loans {
  --summary-edge: var(--domain-loans-edge);
  --summary-label: var(--domain-loans-label);
  --summary-tint: var(--domain-loans-tint);
  --summary-border: var(--domain-loans-border);
}

.entity-summary-card--one-time {
  --summary-edge: var(--domain-one-time-edge);
  --summary-label: var(--domain-one-time-label);
  --summary-tint: var(--domain-one-time-tint);
  --summary-border: var(--domain-one-time-border);
}

.entity-summary-card--investments {
  --summary-edge: var(--domain-investments-edge);
  --summary-label: var(--domain-investments-label);
  --summary-tint: var(--domain-investments-tint);
  --summary-border: var(--domain-investments-border);
}

.entity-summary-card--investment-accounts {
  --summary-edge: var(--domain-investment-accounts-edge);
  --summary-label: var(--domain-investment-accounts-label);
  --summary-tint: var(--domain-investment-accounts-tint);
  --summary-border: var(--domain-investment-accounts-border);
}

.entity-summary-card--family {
  --summary-edge: var(--domain-family-edge);
  --summary-label: var(--domain-family-label);
  --summary-tint: var(--domain-family-tint);
  --summary-border: var(--domain-family-border);
}

/* The Family name is the label here: show it exactly as stored, at
   double the shared label size. */
.entity-summary-card--family .entity-summary-card__label {
  text-transform: none;
  font-size: 1.25rem;
  line-height: 1.25;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Long names: 20-40 characters at 75%, over 40 at 50%. */
.family-summary--name-long .entity-summary-card--family .entity-summary-card__label {
  font-size: 0.9375rem;
}

.family-summary--name-xlong .entity-summary-card--family .entity-summary-card__label {
  font-size: 0.625rem;
}

@media (min-width: 768px) {
  .entity-summary-card--family .entity-summary-card__label {
    font-size: 1.375rem;
  }

  .family-summary--name-long .entity-summary-card--family .entity-summary-card__label {
    font-size: 1.03125rem;
  }

  .family-summary--name-xlong .entity-summary-card--family .entity-summary-card__label {
    font-size: 0.6875rem;
  }
}

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.page-header > .flex {
  flex-wrap: wrap;
  justify-content: flex-end;
}

.page-title {
  font-size: clamp(1.25rem, 1rem + 1.2vw, var(--fs-xl));
  font-weight: var(--fw-semibold);
  color: var(--text);
  letter-spacing: var(--tracking-title);
  line-height: var(--lh-tight);
}

/* E12-04: a separate modifier, not a change to `.page-title` itself, so
   every heading that renders without an icon (most auth/settings/error
   pages) keeps its exact current layout. */
.page-title--with-icon {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.page-title__icon {
  width: 1.3rem;
  height: 1.3rem;
  flex: 0 0 auto;
  color: var(--text-muted);
}

/* E12-06 (MOBILE-FINDING-03): only headings that opt into fitting. A Family
   Name may be one unbroken 255-character token, which normal wrapping has no
   opportunity to break, so the heading would grow past the viewport and push
   the whole page sideways. Breaking inside such a word keeps the complete
   name visible -- nothing is truncated, ellipsised or clipped -- and lets the
   heading report its real width, which is what the fitter measures against.
   `min-width: 0` stops the flex item's automatic minimum from doing the same
   stretching before the break can apply. */
[data-fit-title] > [data-fit-title-text] {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* E12-04: Dashboard card titles -- deliberately smaller than
   `.page-title__icon` (1.3rem) and the Sidebar's own icon (1.15rem), so a
   card heading never competes with a Page Title. One shared size for
   every card title that opts in, same as `.page-title--with-icon` is a
   separate modifier that leaves each card's own heading class untouched. */
.dashboard-card-title--with-icon {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.dashboard-card-title__icon {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
  color: var(--text-muted);
}

.page-subtitle {
  font-size: var(--fs-base);
  color: var(--text-muted);
  margin-top: 0.25rem;
}

.admin-subscription-detail-header__cta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.35rem;
  text-align: right;
  max-width: 18rem;
}

.admin-subscription-detail-header__cta .settings-help {
  margin: 0;
}

@media (max-width: 767px) {
  .admin-subscription-detail-header__cta {
    align-items: flex-start;
    text-align: left;
    max-width: 100%;
  }
}

/* Buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.btn:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.btn-primary {
  background-color: var(--action-primary);
  color: var(--action-primary-contrast);
}

.btn-primary:hover {
  background-color: var(--action-primary-hover);
}

.btn-secondary {
  background-color: transparent;
  border-color: var(--border);
  color: var(--text);
}

.btn-secondary:hover {
  background-color: var(--surface-hover);
}

.btn-danger {
  background-color: transparent;
  border-color: var(--danger, #dc2626);
  color: var(--danger, #dc2626);
}

.btn-danger:hover {
  background-color: var(--danger, #dc2626);
  color: white;
}

.btn-ghost {
  background-color: transparent;
  border-color: transparent;
  color: var(--text-muted);
  padding: 0.4rem 0.65rem;
}

.btn-ghost:hover {
  background-color: var(--surface-hover);
  color: var(--text);
}

.btn-icon {
  min-width: 2.5rem;
  min-height: 2.5rem;
  padding: 0.4rem;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn.htmx-request {
  opacity: 0.7;
  pointer-events: none;
}

/* Form fields */

.field-label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text);
  margin-bottom: 0.35rem;
}

.field-input {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  border: 1px solid var(--border);
  background-color: var(--surface);
  color: var(--text);
  font-size: var(--fs-base);
  min-height: 2.5rem;
}

/* iOS Safari zooms focused controls below 16px. Keep user zoom enabled. */
@media (max-width: 1023px) {
  input.field-input,
  select.field-input,
  textarea.field-input {
    font-size: 16px;
  }
}

.money-input-compact {
  width: 8rem;
}

.field-input:focus {
  outline: none;
  border-color: var(--focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 18%, transparent);
}

.field-hint {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-top: 0.25rem;
}

/* References are muted italic placeholders, never entered values. */
.wealthcast-field { display: inline-block; width: 100%; max-width: 16rem; }
.wealthcast-performance-bar { --performance-color: var(--success); fill: var(--performance-color); stroke: var(--performance-color); }
.wealthcast-performance-bar--negative { --performance-color: var(--danger); }
.wealthcast-performance-bar--light { fill: color-mix(in srgb, var(--performance-color) 35%, var(--surface)); }
.wealthcast-performance-bar--medium-light { fill: color-mix(in srgb, var(--performance-color) 55%, var(--surface)); }
.wealthcast-performance-bar--medium { fill: color-mix(in srgb, var(--performance-color) 78%, var(--surface)); }
.wealthcast-performance-zero { stroke: var(--text-muted); stroke-width: 3; }
.wealthcast-performance-composition { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
.wealthcast-performance-composition > * { min-width: 0; margin-bottom: 0; }
.wealthcast-performance-columns { display: none; }
.wealthcast-performance-year { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .25rem; }
.value-history-primary-controls { display: flex; flex-wrap: wrap; align-items: end; gap: .5rem .75rem; }
.value-history-primary-controls__row { display: flex; flex-wrap: wrap; align-items: end; gap: .5rem .75rem; }
.value-history-period-control { display: flex; align-items: center; }
.value-history-filter { position: relative; }
.value-history-filter > summary { cursor: pointer; min-width: 6.5rem; padding: .5rem .75rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); font-size: var(--fs-base); }
.value-history-filter-panel { display: grid; gap: .75rem; min-width: min(20rem, calc(100vw - 2rem)); margin-top: .35rem; padding: .75rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-md); }
/* SMOKE-007: groups are never capped -- a fixed per-group height hid the
   fifth and later options behind a nested (often invisible) scrollbar. */
.value-history-filter-panel fieldset { display: grid; gap: .35rem; }
.value-history-filter-panel fieldset + fieldset { border-top: 1px solid var(--border); padding-top: .75rem; }
.value-history-filter-panel legend { margin-bottom: .25rem; color: var(--text-muted); font-size: var(--fs-xs); font-weight: var(--fw-medium); }
.value-history-filter-panel label { display: flex; align-items: center; gap: .5rem; font-size: var(--fs-base); }
@media (min-width: 768px) {
  /* SMOKE-007: the floating panel scrolls as a whole only when it would
     exceed the viewport; mobile keeps normal page flow. */
  .value-history-filter-panel {
    position: absolute;
    z-index: 20;
    max-height: calc(100vh - 4rem);
    max-height: calc(100dvh - 4rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}
.wealthcast-value-composition { min-width: 0; }
.wealthcast-line-key { color: var(--text-muted); font-size: var(--fs-xs); display: flex; flex-wrap: wrap; gap: .4rem 1rem; margin-top: .75rem; }
.wealthcast-line-key > span { display: flex; gap: .35rem; align-items: center; white-space: nowrap; }
.wealthcast-line-key svg { width: 1.75rem; height: .625rem; flex: none; }
.wealthcast-line-key line { stroke: currentColor; stroke-width: 2; }
.analytics-chart-legend--interactive { margin: .5rem 0 0; }
.wealthcast-chart-tooltip {
  position: fixed;
  z-index: 30;
  max-width: min(20rem, calc(100vw - 2rem));
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow-md);
  color: var(--text);
  font-size: var(--fs-xs);
  pointer-events: none;
}
.wealthcast-chart-tooltip[hidden] { display: none; }

/* E12-06 (MOBILE-FINDING-02): scrubbed inspection of the Value History
   chart -- the crosshair and active points the finger or pointer selects,
   and the readout that lists every visible series at that date. The touch
   readout sits under the chart, where a finger cannot cover it; a pointer
   or the keyboard uses the floating tooltip above instead. */
.wealthcast-value-composition[data-wealthcast-scrub-surface] {
  touch-action: pan-y;
}
.wealthcast-chart-hit {
  cursor: crosshair;
}
/* E12-06 (MOBILE-FINDING-05): a scrub takes focus itself, so the chart is
   keyboard-ready straight after a tap. The focus ring stays a keyboard
   affordance: it is suppressed only while focus came from a pointer, and
   returns the moment the keyboard is used or the chart is tabbed back to.
   Applies to every scrubbed chart, MonthCast Forecast included. */
[data-scrub-pointer-focus]:focus,
[data-scrub-pointer-focus]:focus-visible {
  outline: none;
}
.wealthcast-chart-crosshair {
  stroke: var(--text-muted);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  opacity: 0.7;
  pointer-events: none;
}
.wealthcast-chart-crosshair[hidden] { display: none; }
.wealthcast-chart-active-point {
  stroke: var(--surface);
  stroke-width: 2;
  pointer-events: none;
}
.wealthcast-chart-active-point--carried {
  fill-opacity: 0.45;
}
.wealthcast-chart-readout {
  margin-top: 0.5rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-subtle, var(--surface));
  font-size: var(--fs-xs);
}
.wealthcast-chart-readout[hidden] { display: none; }
.wealthcast-chart-readout__date {
  margin: 0 0 0.35rem;
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
}
.wealthcast-chart-readout__rows {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.2rem;
}
.wealthcast-chart-readout__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.45rem;
}
.wealthcast-chart-readout__swatch {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  flex: 0 0 auto;
}
.wealthcast-chart-readout__label {
  min-width: 0;
  overflow-wrap: anywhere;
}
.wealthcast-chart-readout__value {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.wealthcast-chart-readout__empty {
  color: var(--text-muted);
}
/* E12-06 (MOBILE-FINDING-04): a carried row shows its figure like any other
   and says "Last known" beside it, the same wording the table and the line
   key use. Only the qualifier is muted, so the value stays readable. */
.wealthcast-chart-readout__carried-note {
  color: var(--text-muted);
}
.wealthcast-chart-readout__empty { margin: 0; }
@media (min-width: 1024px) {
  .wealthcast-performance-composition { grid-template-columns: minmax(0, 62fr) minmax(0, 38fr); }
  .wealthcast-performance-composition .data-table th,
  .wealthcast-performance-composition .data-table td { padding: .6rem .5rem; font-size: var(--fs-xs); }
  .wealthcast-performance-table-card { container: wealthcast-performance-table / inline-size; }
  /* E12-06 UI-07: beside the chart this table has about 425px to work
     with, which fixed percentages cannot divide safely -- "2026 LATEST",
     "YTD Performance" and the WealthCast badge each need a different
     share. The table sizes itself from its own content instead, the way
     the app's other data tables do, and the cells that must never break
     say so. No per-column widths to keep in sync. */
  .wealthcast-performance-table { table-layout: auto; }
  .wealthcast-performance-composition .wealthcast-performance-table th,
  .wealthcast-performance-composition .wealthcast-performance-table td { padding: .55rem .375rem; }
  .wealthcast-performance-composition .wealthcast-performance-table th { font-size: var(--fs-2xs); letter-spacing: .01em; white-space: normal; }
  /* A badge is one word to the reader: Legacy, WealthCast and the Year
     cell's LATEST never wrap mid-label. */
  .wealthcast-performance-table .badge { padding-inline: .3rem; white-space: nowrap; }
  .wealthcast-performance-table td:first-child { white-space: nowrap; }
  .wealthcast-performance-year { flex-wrap: nowrap; }
}
/* Only prevent wrapping when the table itself has room, not just the viewport. */
@container wealthcast-performance-table (min-width: 22rem) {
  .wealthcast-performance-composition .wealthcast-performance-table th,
  .wealthcast-performance-table td:nth-child(2),
  .wealthcast-performance-table td:nth-child(4) { white-space: nowrap; }
  .wealthcast-performance-table td:first-child,
  .wealthcast-performance-table td:first-child .badge { white-space: nowrap; }
}
@media (max-width: 767px) {
  .wealthcast-line-key { gap: .4rem 1rem; margin-top: .5rem; }

  /* Compact controls wrap naturally: inactive status stays with grouping
     and Filter instead of owning a dedicated mobile row. */
  .value-history-primary-controls__row { width: auto; flex-wrap: wrap; align-items: center; }
  .value-history-groupby { flex-wrap: nowrap; }
  .value-history-groupby-btn { justify-content: center; min-width: 2.75rem; padding-inline: .65rem; }
  .value-history-groupby-btn__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .value-history-filter-control { margin-left: 0; flex: none; }
  .value-history-filter > summary { display: inline-flex; align-items: center; min-height: 2.75rem; min-width: 0; }
}
.wealthcast-account-picker { position: relative; width: min(22rem, 100%); }
.wealthcast-account-picker .field-input { width: 100%; min-height: 2.75rem; padding-left: 2.25rem; }
.wealthcast-account-picker__icon { position: absolute; top: 50%; left: 0.65rem; transform: translateY(-50%); width: 1.1rem; height: 1.1rem; color: var(--text-muted); pointer-events: none; }
.wealthcast-chart-segment { pointer-events: stroke; }
.wealthcast-chart-point { stroke: var(--surface); stroke-width: 1; }
.wealthcast-chart-point:focus { outline: none; stroke: var(--action-primary); stroke-width: 3; }
.wealthcast-field .field-input { width: 100%; }
.wealthcast-field .field-input::placeholder { font-style: italic; color: var(--text-muted); opacity: 1; }
@media (max-width: 1023px) {
  .entity-list-table .wealthcast-field { max-width: 100%; }
  .entity-list-table .wealthcast-field .field-input { width: 100%; text-align: left; }
}

.field-label-with-help {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.field-label-with-help label {
  margin-bottom: 0;
}

.field-help-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  min-width: 2rem;
  height: 2rem;
  min-height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
}

.field-help-trigger:hover {
  background: var(--surface-alt);
  color: var(--text);
}

.field-help-trigger:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.field-help-content {
  max-width: 100%;
  overflow-wrap: anywhere;
}

.field-help-content[aria-hidden="true"] {
  display: none;
}

/* E11-SMOKE-009: no hover-only reveal -- a hover-capable desktop must
   not gain an affordance a touch device doesn't have. Visibility is
   driven entirely by aria-hidden (click/tap/keyboard, via
   initializeFieldHelp in app.js), identically on every input type. */

/* E10 MonthCast Notifications: threshold snap-stepper + lead-time slider.
   Presentation only -- server-side min/max remain authoritative. */
.threshold-stepper {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  width: min(100%, 19rem);
}

.threshold-stepper__input {
  flex: 1;
  min-width: 0;
  text-align: center;
}

.threshold-stepper__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  min-width: 2.75rem;
  height: 2.75rem;
  min-height: 2.75rem;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background-color: var(--surface);
  color: var(--text);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.threshold-stepper__btn:hover:not(:disabled) {
  background-color: var(--surface-alt);
  border-color: var(--action-primary);
}

.threshold-stepper__btn:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.threshold-stepper__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

@media (max-width: 480px) {
  .threshold-stepper__btn {
    width: 2.5rem;
    min-width: 2.5rem;
    height: 2.5rem;
    min-height: 2.5rem;
  }
}

/* Settings -> Notifications: Delivery time.
   `input[type="time"]` carries a UA widget whose intrinsic width (the
   hour/minute fields plus the AM/PM segment and spinner) does not shrink with
   `width: 100%`, so on narrow phones it pushed past the right edge of the
   notification card. Constraining it the same way the threshold stepper is
   constrained keeps the existing design and leaves it comfortably inside the
   card at supported mobile widths. */
.settings-notifications-panel input[type="time"].field-input {
  width: min(100%, 11rem);
  max-width: 100%;
  min-width: 0;
}

.lead-time-slider {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

@media (min-width: 768px) { .lead-time-slider { max-width: 28rem; } }
.monthcast-notification-dependent.is-disabled { opacity: 0.52; }
.monthcast-notification-dependent.is-disabled .field-input { background: var(--surface-alt); cursor: not-allowed; }

/* E12-05 (PO density refinement): Settings -> Notifications reads compact,
   not compressed. Only the accumulated spacing is tightened, scoped to
   this panel: the card's vertical padding, the gap between reminder
   blocks, helper-text rhythm, and the help icon's contribution to its
   label row. Toggle rows (2.75rem), the stepper buttons, the slider track
   and every help icon keep their full hit areas. */
.settings-notifications-panel {
  padding-block: 0.875rem;
}

.settings-notifications-panel .space-y-4 > :not([hidden]) ~ :not([hidden]) {
  margin-top: 0.75rem;
}

/* A toggle row is already 2.75rem tall (~0.6rem of its own whitespace
   above and below the switch), so blocks next to a toggle row take a
   smaller gap -- the same visible rhythm as between two text blocks. */
.settings-notifications-panel .space-y-4 > .boolean-field + :not([hidden]),
.settings-notifications-panel .space-y-4 > :has(> .boolean-field:only-child) + :not([hidden]),
.settings-notifications-panel .space-y-4 > :not([hidden]) + :has(> .boolean-field:only-child) {
  margin-top: 0.375rem;
}

/* The first visible block follows only the hidden CSRF input. */
.settings-notifications-panel .space-y-4 > input[type="hidden"]:first-child + :not([hidden]) {
  margin-top: 0;
}

.settings-notifications-panel .settings-help {
  margin-top: 0.125rem;
  line-height: var(--lh-snug);
}

.settings-notifications-panel .field-label {
  margin-bottom: 0.25rem;
}

/* The 2rem help icon keeps its hit area but no longer sets the label
   row's height (it overlaps the row's own spacing instead). */
.settings-notifications-panel .field-label-with-help .field-help-trigger {
  margin-block: -0.375rem;
}

/* A second field inside the same reminder block (Minimum payment amount
   under Upcoming Payment) is visibly its own field. */
.settings-notifications-panel .field-help-group + .field-label {
  margin-top: 0.625rem;
}

.settings-notifications-panel .lead-time-slider {
  gap: 0.25rem;
}

.settings-notifications-panel .settings-autosave-status {
  margin-top: 0.5rem;
}

.lead-time-slider__value {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.lead-time-slider__track {
  width: 100%;
  min-height: 2.75rem;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
}

.lead-time-slider__track:focus-visible {
  outline: none;
}

.lead-time-slider__track::-webkit-slider-runnable-track {
  height: 0.375rem;
  border-radius: 999px;
  background: var(--border);
}

.lead-time-slider__track::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.375rem;
  height: 1.375rem;
  margin-top: -0.5rem;
  border-radius: 999px;
  border: 2px solid var(--surface);
  background: var(--action-primary);
  box-shadow: 0 0 0 1px var(--border);
  cursor: pointer;
}

.lead-time-slider__track:focus-visible::-webkit-slider-thumb {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.lead-time-slider__track::-moz-range-track {
  height: 0.375rem;
  border-radius: 999px;
  background: var(--border);
}

.lead-time-slider__track::-moz-range-progress {
  height: 0.375rem;
  border-radius: 999px;
  background: var(--action-primary);
}

.lead-time-slider__track::-moz-range-thumb {
  width: 1.375rem;
  height: 1.375rem;
  border: 2px solid var(--surface);
  border-radius: 999px;
  background: var(--action-primary);
  box-shadow: 0 0 0 1px var(--border);
  cursor: pointer;
}

.lead-time-slider__track:focus-visible::-moz-range-thumb {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.lead-time-slider__ticks {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.boolean-field {
  min-width: 0;
}

.boolean-field__row {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2.75rem;
}

.toggle-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 2.75rem;
  cursor: pointer;
  user-select: none;
}

.toggle-switch__input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.toggle-switch__track {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 1.55rem;
  padding: 0.18rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-selected);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.toggle-switch__thumb {
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 999px;
  background: var(--text-muted);
  box-shadow: var(--shadow);
  transition: background-color 0.15s ease, transform 0.15s ease;
}

.toggle-switch__input:checked + .toggle-switch__track {
  border-color: var(--action-primary);
  background: color-mix(in srgb, var(--action-primary) 18%, var(--surface));
}

.toggle-switch__input:checked + .toggle-switch__track .toggle-switch__thumb {
  background: var(--action-primary);
  transform: translateX(1.18rem);
}

.toggle-switch__input:focus-visible + .toggle-switch__track {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.toggle-switch__label {
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

.toggle-switch__state {
  min-width: 1.5rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
}

.toggle-switch__state-on {
  display: none;
  color: var(--action-primary);
}

.toggle-switch__input:checked ~ .toggle-switch__state .toggle-switch__state-off {
  display: none;
}

.toggle-switch__input:checked ~ .toggle-switch__state .toggle-switch__state-on {
  display: inline;
}

.toggle-switch:hover .toggle-switch__track {
  border-color: var(--text-muted);
}

.toggle-switch--disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.toggle-switch--disabled:hover .toggle-switch__track {
  border-color: var(--border);
}

/* E11-SMOKE-003: compact variant for inline filter-bar placements
   (e.g. WealthCast Value History's "Show inactive accounts") -- same
   shared toggle-switch markup/behavior, just sized down. */
.toggle-switch--compact {
  gap: 0.4rem;
  min-height: auto;
}

.toggle-switch--compact .toggle-switch__track {
  width: 2.1rem;
  height: 1.15rem;
  padding: 0.14rem;
}

.toggle-switch--compact .toggle-switch__thumb {
  width: 0.78rem;
  height: 0.78rem;
}

.toggle-switch--compact .toggle-switch__input:checked + .toggle-switch__track .toggle-switch__thumb {
  transform: translateX(0.87rem);
}

.toggle-switch--compact .toggle-switch__label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.field-input[aria-invalid="true"] {
  border-color: var(--danger);
}

.field-error {
  margin-top: 0.3rem;
  color: var(--danger);
  font-size: var(--fs-xs);
}

.table-controls {
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  background-color: var(--surface);
  box-shadow: var(--shadow);
}

.table-controls .field-input {
  min-width: 10rem;
}

.table-edit-button {
  padding: 0.25rem 0.75rem;
}

.responsive-table-wrap {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/*
  Opt-in entity-list primitives (Accounts, Income, Bills, Contributions, …).
  Do not attach these classes to Cash Position / Monthly Update ledgers,
  Quick Update, Create Month, Audit Log, or Dashboard investment tables.
*/
.entity-list {
  max-width: 100%;
}

.entity-list-table {
  width: 100%;
  max-width: 100%;
}

.entity-list-field-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 1023px) {
  .entity-list.card:has(.entity-list-table) {
    background: transparent;
    border: none;
    box-shadow: none;
    overflow: visible;
  }

  .entity-list-table,
  .entity-list-table thead,
  .entity-list-table tbody,
  .entity-list-table tr,
  .entity-list-table th,
  .entity-list-table td {
    display: block;
    width: 100% !important;
    max-width: 100%;
  }

  .entity-list-table thead {
    display: none;
  }

  .entity-list-table .entity-list-row {
    display: flex;
    flex-direction: column;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    box-shadow: var(--shadow);
    margin-bottom: 0.75rem;
    padding: 0.85rem 1rem 1rem;
  }

  .entity-list-table .entity-list-row:last-child {
    margin-bottom: 0;
  }

  .entity-list-table td {
    border: 0;
    padding: 0.28rem 0;
    white-space: normal;
    text-align: left;
  }

  .entity-list-table .entity-list-row td.hidden {
    display: flex !important;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.35rem 0.75rem;
  }

  .entity-list-identity {
    order: 1;
    padding-bottom: 0.45rem;
  }

  .entity-list-value {
    order: 2;
    font-size: var(--fs-md);
    font-weight: var(--fw-semibold);
  }

  .entity-list-status {
    order: 3;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.75rem;
  }

  .entity-list-meta {
    order: 4;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.35rem 0.75rem;
  }

  .entity-list-actions {
    order: 5;
    width: 100%;
    padding-top: 0.75rem;
    margin-top: 0.45rem;
    border-top: 1px solid var(--border);
    text-align: left;
  }

  .entity-list-actions .btn {
    min-height: 2.25rem;
    white-space: nowrap;
  }

  .entity-list-field-label {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    clip: auto;
    overflow: visible;
    white-space: normal;
    font-size: var(--fs-xs);
    font-weight: var(--fw-regular);
    color: var(--text-muted);
    min-width: 5.5rem;
  }

  .entity-list-group,
  .entity-list-subgroup {
    background: transparent;
    border: 0;
    box-shadow: none;
    margin: 0.85rem 0 0.4rem;
    padding: 0;
  }

  .entity-list-table .entity-list-group:first-child {
    margin-top: 0;
  }

  .entity-list-group td,
  .entity-list-subgroup th,
  .entity-list-subgroup td {
    background: transparent;
    padding: 0.1rem 0.15rem 0.25rem;
  }

  .entity-list-group .owner-group-heading {
    background: transparent;
    padding: 0.1rem 0.15rem 0.2rem;
  }

  .entity-list .bills-data-table,
  .entity-list .loans-data-table,
  .entity-list .module-data-table {
    min-width: 0;
    table-layout: auto;
  }
}

@media (min-width: 1024px) {
  .entity-list .bills-data-table {
    min-width: 50rem;
    table-layout: fixed;
  }

  .entity-list .bills-data-table th:nth-child(1),
  .entity-list .bills-data-table td:nth-child(1) {
    width: 34%;
  }

  .entity-list .bills-data-table th:nth-child(2),
  .entity-list .bills-data-table td:nth-child(2) {
    width: 14%;
  }

  .entity-list .bills-data-table th:nth-child(3),
  .entity-list .bills-data-table td:nth-child(3) {
    width: 15%;
  }

  .entity-list .bills-data-table th:nth-child(4),
  .entity-list .bills-data-table td:nth-child(4) {
    width: 14%;
  }

  .entity-list .bills-data-table th:nth-child(5),
  .entity-list .bills-data-table td:nth-child(5) {
    width: 13%;
  }

  .entity-list .bills-data-table th:nth-child(6),
  .entity-list .bills-data-table td:nth-child(6) {
    width: 10%;
  }

  /* E12-04 One-Time Money list: 4 columns (Item / Amount / Due / Action)
     after removing Type; overrides `.bills-data-table`'s 5-column widths. */
  .entity-list .one-time-data-table th:nth-child(1),
  .entity-list .one-time-data-table td:nth-child(1) {
    width: 46%;
  }

  .entity-list .one-time-data-table th:nth-child(2),
  .entity-list .one-time-data-table td:nth-child(2) {
    width: 24%;
  }

  .entity-list .one-time-data-table th:nth-child(3),
  .entity-list .one-time-data-table td:nth-child(3) {
    width: 20%;
  }

  .entity-list .one-time-data-table th:nth-child(4),
  .entity-list .one-time-data-table td:nth-child(4) {
    width: 10%;
  }

  .entity-list .loans-data-table {
    min-width: 56rem;
    table-layout: fixed;
  }

  .entity-list .loans-data-table th:nth-child(1),
  .entity-list .loans-data-table td:nth-child(1) {
    width: 38%;
  }

  .entity-list .loans-data-table th:nth-child(2),
  .entity-list .loans-data-table td:nth-child(2) {
    width: 13%;
  }

  .entity-list .loans-data-table th:nth-child(3),
  .entity-list .loans-data-table td:nth-child(3) {
    width: 17%;
  }

  .entity-list .loans-data-table th:nth-child(4),
  .entity-list .loans-data-table td:nth-child(4) {
    width: 14%;
  }

  .entity-list .loans-data-table th:nth-child(5),
  .entity-list .loans-data-table td:nth-child(5) {
    width: 10%;
  }

  .entity-list .loans-data-table th:nth-child(6),
  .entity-list .loans-data-table td:nth-child(6) {
    width: 8%;
  }

  /* DATA-01: the action column holds up to three icon actions (Edit ·
     Deactivate/Activate · Delete), so it has a fixed width that fits them
     instead of a share of the table; the identity column gives up the
     difference by taking whatever space is left. Mobile cards do not use
     these widths. */
  .entity-list .bills-data-table th:first-child,
  .entity-list .bills-data-table td:first-child {
    width: auto;
  }

  .entity-list .bills-data-table th:last-child,
  .entity-list .bills-data-table td:last-child {
    width: var(--entity-row-actions-column);
  }
}

.card table tbody tr {
  transition: background-color 0.12s ease;
}

.card table tbody tr:hover {
  background-color: var(--surface-hover);
}

.module-data-table {
  table-layout: fixed;
}

.bills-data-table {
  min-width: 0;
}

.loans-data-table {
  min-width: 0;
}

/* E12-04 Family refinement: Members list, member pages and the POST
   sibling of the pencil/eye row action. Replaces the legacy Family
   drawers, "More" row menu and bottom action row. */

/* A row action that is a POST (Invite/Resend/Revoke/...) uses the same
   bordered icon button as the pencil/eye link. */
.icon-action-form {
  display: inline-flex;
  margin: 0;
}

button.icon-action-btn {
  padding: 0;
  font: inherit;
  cursor: pointer;
}

.icon-action-btn--danger:hover,
.icon-action-btn--danger:focus-visible {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
  background: var(--danger-bg);
}

/* DATA-01: a financial record's row actions (Edit / Deactivate or Activate
   / Delete) as one icon cluster in the action cell -- the same "rows with
   several legitimate actions" treatment as Family Members. Desktop: one
   line in the table's action column. Mobile cards: one compact horizontal
   row in the approved top-right corner, never a vertical stack and never a
   bottom action row. */
:root {
  /* Three 36px icon actions, two gaps and the cell's horizontal padding. */
  --entity-row-actions-column: 9.75rem;
  --entity-row-actions-gap: 0.35rem;
}

.entity-row-actions {
  display: inline-flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--entity-row-actions-gap);
  vertical-align: middle;
}

@media (max-width: 1023px) {
  /* How many actions a list's rows can carry: Edit, Deactivate / Activate,
     Delete. A list without a lifecycle (Contribution Room: Edit, Delete)
     says so on its own table. */
  .entity-list-table {
    --entity-row-action-slots: 3;
    /* The mobile touch target of `.icon-action-btn`. */
    --entity-row-action-size: 2.5rem;
    --entity-row-actions-width: calc(
      var(--entity-row-action-slots) * var(--entity-row-action-size) +
      (var(--entity-row-action-slots) - 1) * var(--entity-row-actions-gap)
    );
  }

  .contribution-room-list-table {
    --entity-row-action-slots: 2;
  }

  /* Fixed slots, filled from the left in the approved order, so an action
     is always in the same place: when Delete is not available its slot is
     simply empty -- Edit and Deactivate / Activate do not slide over to
     where Delete sits on the next card. */
  .entity-list-table .entity-row-actions:has(> :nth-child(2)) {
    display: inline-grid;
    grid-template-columns: repeat(var(--entity-row-action-slots), var(--entity-row-action-size));
    justify-content: start;
  }

  /* The cluster sits over the card's top-right corner, level with the title;
     the card's own right padding already clears one action, so the title
     makes room for the rest. Only what is level with the row gives way: a
     plain title block is short and simply narrows, while a richer identity
     (`.identity-copy`: detail line, summary, a Loan's balance) wraps around
     the row and keeps the card's full width below it. The amount and every
     detail line are never narrowed. */
  .entity-list-table {
    /* The row's width, less the one action the card's padding already
       clears, plus a 0.5rem breathing gap before the first action. */
    --entity-row-actions-clearance: calc(
      var(--entity-row-actions-width) - var(--entity-row-action-size) + 0.75rem
    );
  }

  .entity-list-table .entity-list-row:has(.entity-row-actions > :nth-child(2)) .entity-list-identity:not(:has(.identity-copy)) {
    padding-right: var(--entity-row-actions-clearance);
  }

  .entity-list-table .entity-list-row:has(.entity-row-actions > :nth-child(2)) .entity-list-identity .identity-copy::before {
    content: "";
    float: right;
    width: var(--entity-row-actions-clearance);
    height: calc(var(--entity-row-action-size) - 0.1rem);
  }
}


.family-members-list-table .family-member-identity__inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}

.family-members-list-table .identity-copy {
  min-width: 0;
}

.family-member-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.4rem;
  overflow-wrap: anywhere;
}

.family-member-full-name {
  margin-top: 0.1rem;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.badge-you {
  background: var(--domain-family-tint);
  color: var(--domain-family-label);
  border: 1px solid var(--domain-family-border);
}

.family-member-email {
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.family-member-email__link {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--border);
  text-underline-offset: 2px;
}

.family-member-email__link:hover {
  text-decoration-color: currentColor;
}

.family-member-muted {
  color: var(--text-muted);
}

.family-member-access__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
}

.family-member-access__body .badge,
.family-member-status .badge,
.family-member-name .badge {
  white-space: nowrap;
}

.family-member-access__note {
  font-size: var(--fs-xs);
  line-height: 1.35;
  color: var(--text-muted);
}

.family-member-actions {
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  align-items: center;
  gap: 0.35rem;
}

.family-members-list-table .family-member-actions-cell {
  width: 1%;
  white-space: nowrap;
}

/* Member pages: paired fields, one column on narrow screens. */
.family-member-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.9rem 1rem;
}

.family-member-grid__wide {
  grid-column: 1 / -1;
}

.family-member-access-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0.75rem 0 0.5rem;
  padding: 0;
  border: 0;
}

.family-member-access-choices legend {
  width: 100%;
  margin-bottom: 0.35rem;
}

/* Add Member access level: the shared choice cards (Contribution Room
   pattern), two options at every width. No `display` on the fieldset, so
   its `hidden` state (app access off) is honoured. */
.family-member-access-cards {
  margin: 0.75rem 0 0.25rem;
  padding: 0;
  border: 0;
  min-width: 0;
}

.family-member-access-cards legend {
  margin-bottom: 0.35rem;
}

.account-type-choices.family-access-choices {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 24rem;
}

.family-access-choice .account-type-choice__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.05rem;
  line-height: 1;
}

.family-member-access-choice {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--fs-base);
  color: var(--text);
}

@media (max-width: 639px) {
  .family-member-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .account-type-choices.family-access-choices {
    max-width: none;
  }
}

@media (min-width: 1024px) {
  /* An email keeps a readable column instead of collapsing to a few
     characters per line; a very long one still wraps. */
  .family-members-list-table .family-member-email {
    min-width: 10rem;
  }
}

@media (min-width: 1024px) and (max-width: 1279px) {
  /* Narrow desktop: the table keeps its columns, cells tighten and the
     action cluster wraps (at most three per line, as on the mobile card).
     Anything still wider scrolls instead of being clipped. */
  .entity-list.family-members-list {
    overflow-x: auto;
  }

  .family-members-list-table th,
  .family-members-list-table td {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }

  .family-members-list-table .family-member-email {
    min-width: 8rem;
  }

  .family-members-list-table th:first-child,
  .family-members-list-table td:first-child {
    padding-left: 1rem;
  }

  .family-members-list-table th:last-child,
  .family-members-list-table td:last-child {
    padding-right: 1rem;
  }

  /* Three 2.25rem icons + two 0.35rem gaps. */
  .family-members-list-table .family-member-actions {
    flex-wrap: wrap;
    width: 7.45rem;
    margin-left: auto;
  }
}

@media (max-width: 1023px) {
  /* Members mobile card: the approved corner-action placement (spec
     ACC-LIST-007) generalized for several actions -- identity top-left,
     the action cluster top-right in the card header (wrapping), then
     Email / App access / Status. Never a separate bottom action row. */
  .family-members-list-table .entity-list-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 0.75rem;
    align-items: start;
  }

  .family-members-list-table .entity-list-identity {
    grid-column: 1;
    grid-row: 1;
    padding-bottom: 0.45rem;
  }

  .family-members-list-table .family-member-actions-cell {
    grid-column: 2;
    grid-row: 1;
    width: auto !important;
    padding: 0 !important;
    margin: 0;
    border-top: none;
  }

  .family-members-list-table .family-member-actions {
    flex-wrap: wrap;
    max-width: 8.4rem;
  }

  .family-members-list-table .family-member-email,
  .family-members-list-table .family-member-access,
  .family-members-list-table .family-member-status {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.35rem 0.75rem;
  }

  .family-members-list-table .family-member-access__body {
    flex: 1 1 12rem;
  }

  .family-members-list-table .icon-action-btn__tooltip {
    right: 0;
    left: auto;
    max-width: min(14rem, calc(100vw - 4rem));
  }
}

.institution-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  height: 1.5rem;
  padding: 0 0.4rem;
  border-radius: 0.375rem;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  color: #fff;
  letter-spacing: 0.02em;
}

.owner-group-heading {
  padding: 0.75rem 1rem 0.4rem;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: normal;
  color: var(--text-secondary);
  background-color: var(--bg-subtle, rgba(127, 127, 127, 0.05));
}

/* E12-05-027: in a list grouped twice (owner, then type or category), the
   levels are told apart by type and space, not by more shades of grey:
   the owner reads as a section heading (the approved Accounts owner
   treatment -- title case, text colour, a hairline rule, no tint), and
   the type / category beneath it as a quieter, indented small-caps label.
   Single-level lists keep their headings exactly as they were. */
.entity-list-table--nested .owner-group-heading {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text);
  background-color: transparent;
}

.entity-list-table--nested .entity-list-subgroup-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  color: var(--text-muted);
  background-color: transparent;
}

@media (min-width: 1024px) {
  .entity-list-table--nested .owner-group-heading {
    padding: 1.1rem 1rem 0.3rem;
    border-top: 1px solid var(--border);
  }

  .entity-list-table--nested .entity-list-group:first-child .owner-group-heading {
    padding-top: 0.5rem;
    border-top: 0;
  }

  .entity-list-table--nested .entity-list-subgroup-label {
    padding-top: 0.45rem;
    padding-bottom: 0.25rem;
    padding-left: 1.75rem;
  }
}

/* E12-04: an inactive owner's heading reads exactly "Name (inactive)" --
   the name's own casing and a lowercase marker, never uppercased (as on
   the Accounts / Contribution Room owner headings). */
.owner-group-heading--inactive {
  text-transform: none;
  letter-spacing: normal;
}

/* E12-04 List group headings (Bills category, One-Time type): one
   decorative emoji before the heading text -- the same native emoji
   language as Add/Edit. Same markup on desktop table rows and the mobile
   stacked layout; the emoji is not letter-spaced/uppercased with the
   heading text. */
.entity-list-group-title {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

/* E12-05 category / domain glyph (`icons.category_icon`): one CountAhead
   line icon in a restrained neutral circle -- never a platform emoji,
   never a domain or brand colour. */
.cat-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  background: var(--surface-alt);
  box-shadow: inset 0 0 0 1px var(--card-border);
  color: var(--text-muted);
  vertical-align: middle;
}

.cat-icon__svg {
  width: 0.875rem;
  height: 0.875rem;
}

.cat-icon--sm {
  width: 1.25rem;
  height: 1.25rem;
}

.cat-icon--sm .cat-icon__svg {
  width: 0.75rem;
  height: 0.75rem;
}

.cat-icon--lg {
  width: 2.25rem;
  height: 2.25rem;
}

.cat-icon--lg .cat-icon__svg {
  width: 1.1rem;
  height: 1.1rem;
}

/* A category name beside its glyph (list rows, read-only values). */
.cat-label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

/* E12-04 One-Time Money: subtle inflow / outflow cue on the Type heading
   only (same 2px left-border language as MonthCast calendar occurrences);
   the heading text always names the type, so color is never the only cue. */
.entity-list-group[data-direction] .one-time-group-heading {
  border-left: 2px solid transparent;
}

.entity-list-group[data-direction="inflow"] .one-time-group-heading {
  border-left-color: var(--flow-inflow);
}

.entity-list-group[data-direction="outflow"] .one-time-group-heading {
  border-left-color: var(--flow-outflow);
}

@media (max-width: 1023px) {
  .entity-list-group[data-direction] .one-time-group-heading {
    padding-left: 0.5rem;
  }
}

/* Badges */

.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  background-color: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
}

.badge-success {
  background-color: var(--success-bg);
  color: var(--success);
}

.badge-warning {
  background-color: var(--warning-bg);
  color: var(--warning);
}

.badge-danger {
  background-color: var(--danger-bg);
  color: var(--danger);
}

.badge-info {
  background-color: color-mix(in srgb, var(--data-blue) 14%, var(--surface));
  color: var(--data-blue);
  border: 1px solid color-mix(in srgb, var(--data-blue) 38%, var(--border));
}

/* Flash messages */

.flash {
  padding: 0.625rem 0.875rem;
  border-radius: 0.5rem;
  font-size: var(--fs-base);
  border: 1px solid var(--border);
  margin-bottom: 0.75rem;
}

.flash-success {
  background-color: var(--success-bg);
  color: var(--success);
  border-color: var(--success);
}

.flash-error {
  background-color: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}

/* E12-06 UI-11: the Email MFA recommendation is the one flash that carries
   actions, so it -- and only it -- gets a row layout. Inline flow used to
   line-break the two actions independently, dropping "Not now" onto a line
   of its own at common phone widths (365-470px). The message has a flex
   basis instead: with room to spare everything sits on one line, and when
   there is not, the message takes the first line and the action group
   stays together on the second. No typography change, no fixed breakpoint. */
.mfa-suggestion {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.mfa-suggestion__message {
  flex: 1 1 16rem;
  min-width: 0;
  margin: 0;
}

.mfa-suggestion__actions {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
}

.flash-info {
  background-color: var(--surface);
  color: var(--text);
}

.flash-warning {
  background-color: var(--warning-bg);
  color: var(--warning);
  border-color: var(--warning);
}

.flash-toast-host {
  position: fixed;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  pointer-events: none;
  box-sizing: border-box;
}

/* A request-problem notice raised while a modal <dialog> is open lives in
   the dialog (the page host is inert and behind the top layer there). It
   sits in the dialog's own flow, above its content; the page host's fixed
   viewport placement (including the breakpoint rules) does not apply. */
.flash-toast-host.flash-toast-host--in-dialog {
  position: sticky;
  top: 0;
  left: auto;
  right: auto;
  width: auto;
  max-width: none;
  transform: none;
  z-index: 1;
  padding: 0.75rem 1rem 0;
}

.flash-toast-host.flash-toast-host--in-dialog:empty {
  display: none;
}

.flash-toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem 0.85rem;
  border-radius: 0.75rem;
  border: 1px solid var(--border);
  background-color: var(--surface);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: var(--fs-base);
  line-height: 1.4;
}

.flash-toast[data-flash-toast-dismissible] {
  cursor: pointer;
}

.flash-toast-success {
  background-color: var(--success-bg);
  color: var(--success);
  border-color: var(--success);
}

.flash-toast-info {
  background-color: color-mix(in srgb, var(--data-blue) 8%, var(--surface));
  color: var(--text);
  border-color: color-mix(in srgb, var(--data-blue) 32%, var(--border));
}

.flash-toast-warning {
  background-color: var(--warning-bg);
  color: var(--warning);
  border-color: var(--warning);
}

.flash-toast-error {
  background-color: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}

.flash-toast-copy {
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

.flash-toast-dismiss {
  position: relative;
  flex: 0 0 auto;
  align-self: center;
  min-width: 2.75rem;
  min-height: 2.25rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid color-mix(in srgb, currentColor 28%, var(--border));
  border-radius: 0.5rem;
  background-color: color-mix(in srgb, currentColor 8%, var(--surface));
  color: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.flash-toast-dismiss::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  transform: translate(-50%, -50%);
}

.flash-toast-dismiss:hover {
  background-color: color-mix(in srgb, currentColor 14%, var(--surface));
  border-color: color-mix(in srgb, currentColor 42%, var(--border));
}

.flash-toast-dismiss:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
  background-color: color-mix(in srgb, currentColor 14%, var(--surface));
}

@media (max-width: 767px) {
  .flash-toast-host {
    top: calc(
      env(safe-area-inset-top, 0px) + var(--app-mobile-header-height) + var(--app-mobile-toast-gap)
    );
    left: 50%;
    right: auto;
    width: min(20rem, 82vw);
    max-width: calc(100vw - 1.5rem - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px));
    transform: translateX(-50%);
  }

  .flash-toast {
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.5rem 0.4rem 0.7rem;
  }

  .flash-toast-copy {
    overflow-wrap: anywhere;
  }

  .flash-toast-dismiss {
    min-width: 0;
    min-height: 0;
    padding: 0.15rem 0.4rem;
  }
}

@media (min-width: 768px) {
  html {
    --app-sidebar-offset: 16rem;
  }

  html[data-sidebar-collapsed="true"] {
    --app-sidebar-offset: 4.75rem;
  }

  html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] {
    --app-sidebar-offset: 16rem;
  }

  .flash-toast-host {
    top: 1rem;
    left: var(--app-sidebar-offset);
    right: 0;
    width: auto;
    align-items: center;
    padding-inline: 1rem;
  }

  .flash-toast {
    width: min(24rem, 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .flash-toast {
    transition: none;
  }
}

/* Cash Position / create-month advisory — noticeable, not an error. */
.advisory {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.875rem 1rem;
  margin-bottom: 1rem;
  border-radius: 0.75rem;
  border: 1px solid var(--warning);
  background-color: var(--warning-bg);
  box-shadow: inset 3px 0 0 var(--warning);
}

.advisory-icon {
  flex-shrink: 0;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  color: var(--warning);
}

.advisory-content {
  min-width: 0;
  flex: 1;
}

.advisory-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.01em;
  color: var(--warning);
}

.advisory-body {
  margin-top: 0.2rem;
  font-size: var(--fs-base);
  line-height: 1.45;
  color: var(--text);
}

.advisory-cta {
  margin-top: 0.7rem;
}

/* E12-05-015: informational context (a Historical month is read-only by
   design) -- the neutral surface and text tokens, not the warning ones. */
.advisory--info {
  border-color: var(--border);
  background-color: var(--surface-alt);
  box-shadow: inset 3px 0 0 var(--text-muted);
}

.advisory--info .advisory-icon {
  color: var(--text-muted);
}

.advisory--info .advisory-title {
  color: var(--text);
}

/* Shared Cash Position / Monthly Update item columns.
   Trailing columns keep a stable share so Amount / Account / Status / Actions
   line up across category tables. A normal block wrapper inside the action
   cell is the size container (not the <td>): nowrap while the cluster fits,
   wrap if only the wide cluster overflows, stack only when a short
   cluster such as Reopen + More no longer fits. */
.item-ledger-wrap {
  container-type: inline-size;
  container-name: item-ledger;
  overflow: visible;
}

.item-ledger-table {
  table-layout: fixed;
  width: 100%;
}

.item-ledger-col-name {
  width: 22%;
}

.item-ledger-col-amount {
  width: 14%;
}

.item-ledger-col-account {
  width: 20%;
}

.item-ledger-col-status {
  width: 12%;
}

.item-ledger-col-actions {
  width: 32%;
}

/* E12-04: the unified One-Time Money table has no Account column. */
.item-ledger-table--no-account .item-ledger-col-name {
  width: 42%;
}

.item-ledger-table th,
.item-ledger-table td {
  overflow-wrap: anywhere;
  vertical-align: top;
}

.item-ledger-table .item-ledger-col-amount,
.item-ledger-table .item-ledger-col-status {
  overflow-wrap: normal;
  word-break: normal;
}

.item-ledger-amount-value,
.item-ledger-status-badge {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.item-ledger-table .item-ledger-col-actions {
  overflow-wrap: normal;
  white-space: nowrap;
  /* The cluster wraps rather than overlapping, which drops its min-content
     width to the widest single chip -- so the 32% column above could be
     allocated far less than a three-action row (Mark Paid + Skip +
     Remaining/Override) actually needs, leaving it wrapped and pinned hard
     against the right edge. This floor gives that row real room, so it wraps
     only when the width is genuinely insufficient rather than routinely. */
  min-width: 17rem;
}

.item-ledger-field-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* E12-MCS-UX-013/014: the occurrence action cluster. Compact Icon + Label
   controls, the same set and the same words on Desktop and on a phone, and
   the same cluster in the Category view and in the Timeline. Nothing here
   is full-width or display-sized: the primary action carries the only
   filled treatment, the rest are quiet bordered controls beside it, and
   the label is always present so no action is identified by its icon
   alone. */
/* E12-MCS: one row, at every width. The set is at most three controls, so
   rather than wrapping (which buried Override on a second line) they share
   the row and give up label padding first. */
/* The action cluster shared by MonthCast Category and Timeline.
   Previously `nowrap` combined with shrinkable items: when the column got
   tight (notably around the desktop/mobile transition, or at browser zoom),
   each item shrank below the intrinsic width of its own `white-space: nowrap`
   label, so adjacent controls visibly collided. Items now keep their
   intrinsic width and the cluster wraps instead -- it runs out of row before
   it runs out of space. The phone rules below deliberately restore a single
   row, where the chips are already sized down for it. */
.occurrence-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  row-gap: 0.3rem;
  justify-content: flex-end;
  align-items: center;
  min-width: 0;
}

.occurrence-action {
  display: inline-flex;
  /* Never shrink below the label: shrinking is what produced the overlap. */
  flex: 0 0 auto;
}

/* Two classes deliberately: these controls build on the shared `.btn` /
   `.btn-compact` primitives, whose own rules sit later in this file, so the
   occurrence sizing has to out-specify them rather than rely on order. */
.occurrence-actions .occurrence-action__btn {
  gap: 0.3rem;
  padding: 0.3rem 0.6rem;
  min-height: 2.25rem;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  text-decoration: none;
}

.occurrence-action__icon {
  width: 0.9rem;
  height: 0.9rem;
  flex-shrink: 0;
}

/* E12-05-005: first in the hierarchy -- the action this occurrence is
   waiting for (Mark Paid / Received / Completed) -- carried by the action
   colour on an outlined control, so a long list of rows is not a wall of
   solid primaries. */
.occurrence-actions .occurrence-action__btn--lead {
  border-color: color-mix(in srgb, var(--action-primary) 55%, var(--border));
  color: var(--action-primary);
}

.occurrence-actions .occurrence-action__btn--lead:hover,
.occurrence-actions .occurrence-action__btn--lead:focus-visible {
  border-color: var(--action-primary);
  background-color: color-mix(in srgb, var(--action-primary) 8%, var(--surface));
}

/* Third in the hierarchy: present and legible, but never competing with
   the action this occurrence is actually waiting for.

   The trailing amount control is "Remaining" on an adjustable estimate and
   "Override" elsewhere. Those labels are different widths, so without a
   shared floor the whole right-aligned cluster shifted horizontally from row
   to row and read as ragged. A minimum width gives both labels the same slot
   (it is a floor, never a clamp, so nothing is truncated). */
.occurrence-actions .occurrence-action__btn--quiet {
  border-color: transparent;
  color: var(--text-muted);
  min-width: 6.75rem;
  justify-content: center;
}

.occurrence-actions .occurrence-action__btn--quiet:hover,
.occurrence-actions .occurrence-action__btn--quiet:focus-visible {
  border-color: var(--border);
  color: var(--text);
}

.occurrence-amount-error {
  margin-top: 0.2rem;
  color: var(--danger);
  font-weight: var(--fw-medium);
  text-align: right;
}

.month-list-field-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.month-list-state {
  margin-left: 0.4rem;
  vertical-align: middle;
}

/* E12-MCS-UX-002 / E12-WC-UX-001..004: both lists that share this
   `.month-list-*` layer -- MonthCast's months and WealthCast's snapshots --
   use the row-action cluster every other CountAhead entity list uses:
   compact icon controls with their own accessible label and tooltip, and
   the destructive one marked as such. The `entity-list-actions` marker on
   the cell is what opts a row into it. */
.month-list-actions.entity-list-actions {
  white-space: nowrap;
}

.month-list-actions.entity-list-actions .icon-action-btn,
.month-list-actions.entity-list-actions .icon-action-form {
  display: inline-flex;
  vertical-align: middle;
}

.month-list-actions.entity-list-actions .icon-action-form + .icon-action-form,
.month-list-actions.entity-list-actions .icon-action-btn + .icon-action-form,
.month-list-actions.entity-list-actions .icon-action-btn + .icon-action-btn {
  margin-left: 0.35rem;
}

/* Deleting a month or a snapshot destroys recorded work, so it reads as
   destructive at rest here and not only under the pointer. */
.month-list-actions.entity-list-actions .icon-action-btn--danger {
  border-color: color-mix(in srgb, var(--danger) 46%, var(--border));
  color: var(--danger);
}

.month-list-name {
  font-weight: var(--fw-medium);
  color: var(--text);
}

/* E12-05-014: a WealthCast's cadence, said quietly under its date. */
.wealthcast-list-cadence {
  display: block;
  margin-top: 0.1rem;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.month-years {
  container-type: inline-size;
  container-name: month-years;
  display: grid;
  gap: 1rem;
}

.month-year-group {
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  background-color: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.month-year-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.8rem 1rem;
  cursor: pointer;
  list-style: none;
  background-color: var(--surface-alt);
  border-bottom: 1px solid var(--border);
}

.month-year-heading::-webkit-details-marker {
  display: none;
}

.month-year-label {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.month-year-count {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.month-list-table .month-list-row {
  border-bottom: 1px solid var(--border);
}

.month-list-table .month-list-row:last-child {
  border-bottom: 0;
}

.month-list-table .month-list-row.is-latest {
  background-color: color-mix(in srgb, var(--surface-selected) 58%, var(--surface));
  box-shadow: inset 3px 0 color-mix(in srgb, var(--text-muted) 62%, var(--border));
}

.month-list-state--current {
  border: 1px solid var(--selected-line);
  background: var(--selected-tint);
  color: var(--selected-ink);
}

.month-list-state--current::before {
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  margin-right: 0.35rem;
  border-radius: 999px;
  background: var(--selected-mark);
  vertical-align: 0.08em;
  content: "";
}

.month-list-state--historical {
  border: 1px solid transparent;
}

/* E12-WC-UX-006: WealthCast's `Migrated` marks a snapshot the migration
   created once from prior Investment Account data -- a provenance note,
   not MonthCast's Historical lifecycle state. It keeps the design
   system's neutral badge treatment; only its meaning is its own, so it
   can change later without touching MonthCast. */
.month-list-state--migrated {
  border: 1px solid transparent;
}

/* D2 / E12-MCS-UX-001: the attention marker on the Latest month only. It
   says what it means in words, in the ordinary badge vocabulary, so the
   icon and the colour are both supplements to the label rather than the
   only signal. */
.month-list-overdue {
  margin-left: 0.35rem;
  gap: 0.25rem;
  vertical-align: middle;
}

.month-list-overdue__icon {
  width: 0.8rem;
  height: 0.8rem;
  flex-shrink: 0;
}

.advisory[data-historical-period-banner] {
  padding: 0.6rem 0.85rem;
  margin-bottom: 0.75rem;
  gap: 0.5rem;
}

.advisory[data-historical-period-banner] .advisory-body {
  margin-top: 0.1rem;
  font-size: var(--fs-sm);
  line-height: 1.35;
}

.advisory[data-historical-period-banner] .advisory-cta {
  margin-top: 0.55rem;
}

/*
  Dedicated financial-ledger cards when the ledger itself is too narrow
  for a dense 5-column table (sidebar already present on md+).
  Keep the table row as the HTMX swap root. Do not flatten rows.
  Do not reuse .entity-list. Do not apply these rules to Quick Update or
  Create Month preview tables.
  */
@container item-ledger (max-width: 54rem) {
  .item-ledger-table {
    table-layout: auto;
    border-collapse: separate;
    border-spacing: 0 0.75rem;
  }

  .item-ledger-table thead {
    display: none;
  }

  .item-ledger-table tbody {
    display: block;
  }

  .item-ledger-table .item-ledger-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "name status"
      "amount amount"
      "account account"
      "actions actions";
    gap: 0.4rem 0.75rem;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    box-shadow: var(--shadow);
    padding: 0.9rem 1rem 1rem;
    margin: 0;
  }

  .item-ledger-table .item-ledger-row-readonly {
    grid-template-areas:
      "name status"
      "amount amount"
      "account account";
    padding: 0.55rem 0.75rem 0.65rem;
    gap: 0.2rem 0.5rem;
    box-shadow: none;
  }

  .item-ledger-table .item-ledger-col-name,
  .item-ledger-table .item-ledger-col-amount,
  .item-ledger-table .item-ledger-col-account,
  .item-ledger-table .item-ledger-col-status,
  .item-ledger-table .item-ledger-col-actions {
    width: auto;
    /* The table-mode floor above must not push a card wider than the phone:
       here the actions span the card's own full row and wrap within it. */
    min-width: 0;
    max-width: 100%;
    padding: 0;
    text-align: left;
    border: 0;
  }

  .item-ledger-table .item-ledger-col-name {
    grid-area: name;
    overflow-wrap: anywhere;
  }

  .item-ledger-table .item-ledger-col-status {
    grid-area: status;
    justify-self: end;
    align-self: start;
    white-space: nowrap;
    overflow-wrap: normal;
  }

  .item-ledger-table .item-ledger-col-amount {
    grid-area: amount;
    text-align: left;
    font-size: var(--fs-md);
    white-space: nowrap;
    overflow-wrap: normal;
    word-break: normal;
  }

  .item-ledger-table .item-ledger-col-account {
    grid-area: account;
    display: block;
  }

  .item-ledger-table .item-ledger-col-actions {
    grid-area: actions;
    white-space: normal;
  }

  .item-ledger-table .item-ledger-row-readonly .item-ledger-col-actions {
    display: none;
  }

  .item-ledger-field-label {
    position: static;
    width: auto;
    height: auto;
    margin: 0 0 0.15rem;
    overflow: visible;
    clip: auto;
    display: block;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
  }

  .item-ledger-col-status .item-ledger-field-label,
  .item-ledger-col-name .item-ledger-field-label {
    display: none;
  }

  .item-ledger-amount-value {
    display: inline-block;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }

  .item-ledger-status-badge {
    display: inline-flex;
    white-space: nowrap;
    writing-mode: horizontal-tb;
  }

  .item-ledger-table .item-ledger-col-actions {
    white-space: normal;
  }

  /* E12-MCS-UX-014: the card keeps the same controls in the same words as
     the table -- one row of compact Icon + Label chips, left aligned with
     the rest of the card. No stack of full-width buttons, nothing pushed
     to a second line, and the touch target stays 2.5rem tall. The chips
     give up horizontal padding before they give up the row. */
  .occurrence-actions {
    /* The chips give up horizontal padding (below) before the row, so a
       normal cluster still reads as one row here. `flex-wrap` is deliberately
       NOT forced back to `nowrap`: items no longer shrink below their label
       (`flex: 0 0 auto`), so in this narrow container a long cluster -- e.g.
       Mark Received + Skip + Remaining -- had no way to fit and overflowed
       the card instead. Inheriting the global `wrap` keeps one row whenever
       the controls genuinely fit and wraps cleanly when they do not, rather
       than clipping. */
    justify-content: flex-start;
    gap: 0.3rem;
    margin-top: 0.15rem;
  }

  /* The shared desktop floor would force a phone chip wider than the row. */
  .occurrence-actions .occurrence-action__btn--quiet {
    min-width: 0;
  }

  .occurrence-actions .occurrence-action__btn {
    min-height: 2.5rem;
    padding: 0.4rem 0.45rem;
    font-size: var(--fs-sm);
  }

  .occurrence-action__icon {
    width: 1rem;
    height: 1rem;
  }

  .occurrence-amount-error {
    text-align: left;
  }

  .item-ledger-table--no-account .item-ledger-row {
    grid-template-areas:
      "name status"
      "amount amount"
      "actions actions";
  }

  .item-ledger-table--no-account .item-ledger-row-readonly {
    grid-template-areas:
      "name status"
      "amount amount";
  }

  /* E12-05-017: on a phone an occurrence is a compact row of the section's
     list -- divided from the next, not a card inside the section's card --
     and it reads in two lines before its actions:
       Name                      $Amount
       Owner · date / account      Status
     The per-field captions a table header would give are dropped; each
     value's place (and the name/amount pairing) already says what it is. */
  .item-ledger-table {
    border-spacing: 0;
  }

  .item-ledger-table .item-ledger-row,
  .item-ledger-table .item-ledger-row-readonly {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "name amount"
      "account status"
      "actions actions";
    gap: 0.2rem 0.75rem;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    background-color: transparent;
    padding: 0.7rem 0.1rem 0.75rem;
  }

  .item-ledger-table .item-ledger-row-readonly {
    grid-template-areas:
      "name amount"
      "account status";
  }

  .item-ledger-table tbody .item-ledger-row:last-child {
    border-bottom: 0;
  }

  .item-ledger-table .item-ledger-col-amount {
    justify-self: end;
    align-self: start;
    text-align: right;
    font-size: var(--fs-md);
  }

  .item-ledger-table .item-ledger-col-status {
    align-self: center;
  }

  .item-ledger-table .item-ledger-col-account {
    align-self: center;
    font-size: var(--fs-sm);
    overflow-wrap: anywhere;
  }

  .item-ledger-table .item-ledger-col-amount .item-ledger-field-label,
  .item-ledger-table .item-ledger-col-account .item-ledger-field-label {
    display: none;
  }

  .item-ledger-table .occurrence-actions {
    margin-top: 0.35rem;
  }

  .item-ledger-table--no-account .item-ledger-row {
    grid-template-areas:
      "name amount"
      ". status"
      "actions actions";
  }

  .item-ledger-table--no-account .item-ledger-row-readonly {
    grid-template-areas:
      "name amount"
      ". status";
  }
}

@container month-years (max-width: 54rem) {
  .month-year-group {
    background: transparent;
    border: none;
    box-shadow: none;
    overflow: visible;
  }

  .month-year-heading {
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    margin-bottom: 0.65rem;
  }

  .month-year-group[open] .month-year-heading {
    border-bottom-left-radius: 0.75rem;
    border-bottom-right-radius: 0.75rem;
  }

  .month-list-table thead,
  .month-list-table .month-list-meta {
    display: none;
  }

  .month-list-table,
  .month-list-table tbody {
    display: block;
    width: 100%;
  }

  .month-list-table .month-list-row {
    display: flex;
    flex-direction: column;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    box-shadow: var(--shadow);
    margin-bottom: 0.75rem;
    padding: 0.85rem 0.95rem 0.95rem;
  }

  .month-list-table .month-list-row:last-child {
    margin-bottom: 0;
    border-bottom: 1px solid var(--border);
  }

  .month-list-table .month-list-identity,
  .month-list-table .month-list-value,
  .month-list-table .month-list-actions {
    display: block;
    width: 100%;
    padding: 0.2rem 0;
    text-align: left;
    border: 0;
  }

  /* E12-WC-UX-008: Completeness is not MonthCast's Created / Last updated
     bookkeeping -- it is the one thing a WealthCast row describes about
     itself, so the mobile card keeps it, between the Date and the
     actions. Scoped to WealthCast's own cell, so MonthCast's meta
     columns stay hidden exactly as before. */
  .month-list-table .wealthcast-list-completeness {
    display: block;
    width: 100%;
    padding: 0.2rem 0;
    text-align: left;
    border: 0;
    order: 2;
  }

  .month-list-identity {
    order: 1;
  }

  .month-list-value {
    order: 2;
  }

  .month-list-actions {
    order: 3;
  }

  .month-list-name {
    display: block;
    font-size: var(--fs-md);
  }

  .month-list-state {
    display: inline-flex;
    margin: 0.35rem 0 0;
  }

  .month-list-field-label {
    position: static;
    width: auto;
    height: auto;
    margin: 0 0 0.15rem;
    overflow: visible;
    clip: auto;
    display: block;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
  }

  .month-list-identity .month-list-field-label {
    display: none;
  }

  .month-list-spendable {
    display: inline-block;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-size: var(--fs-md);
  }

  /* E12-MCS-UX-002 / E12-WC-UX-004: a mobile card keeps the same icon
     controls as its table row, sitting together at the end of the card
     rather than becoming a stack of full-width buttons. */
  .month-list-table .month-list-actions.entity-list-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.55rem;
    padding-top: 0.55rem;
    border-top: 1px solid var(--border);
  }

  .month-list-actions.entity-list-actions .icon-action-btn {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* Empty state */

.empty-state {
  text-align: center;
  padding: 2.5rem 1rem;
  color: var(--text-muted);
}

.empty-state > :first-child {
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}

.empty-state > :first-child + p {
  max-width: 34rem;
  margin-inline: auto;
  line-height: 1.5;
}

.empty-state .btn {
  margin-top: 0.85rem;
}

.audit-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  padding: 0.85rem 1rem;
  border-top: 1px solid var(--border);
}

.audit-pagination-status {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-base);
}

.audit-pagination-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.audit-pagination-disabled {
  opacity: 0.45;
  pointer-events: none;
  cursor: default;
}

.audit-page-size {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
  font-size: var(--fs-base);
}

.audit-page-size a {
  color: var(--action-primary);
  text-decoration: none;
  font-weight: var(--fw-semibold);
}

.audit-page-size a:hover {
  text-decoration: underline;
}

.audit-page-size [aria-current="true"] {
  color: var(--text);
  font-weight: var(--fw-semibold);
  box-shadow: inset 0 -2px 0 var(--selected-mark);
}

.more-nav-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) repeat(2, minmax(10rem, 1fr));
  gap: 1rem;
}

.more-nav-group {
  min-width: 0;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.625rem;
  background-color: var(--surface-alt);
}

.more-nav-group h3 {
  margin: 0 0 0.5rem 0.75rem;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
}

.more-nav-links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.2rem;
}

.global-loading {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 60;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background-color: var(--surface);
  box-shadow: var(--shadow);
  pointer-events: none;
}

.global-loading.htmx-indicator {
  display: none;
}

.global-loading.htmx-request,
.htmx-request .global-loading {
  display: flex;
}

.global-loading-spinner {
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--border);
  border-top-color: var(--action-primary);
  border-radius: 999px;
  animation: global-loading-spin 0.7s linear infinite;
}

@keyframes global-loading-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .global-loading-spinner {
    animation: none;
  }
}

/* Monthly Update visual shell */

.monthly-shell-section {
  margin-bottom: 0.75rem;
  overflow: hidden;
}

.monthly-shell-section-header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.875rem;
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  list-style: none;
}

.monthly-shell-section-header::-webkit-details-marker {
  display: none;
}

.monthly-shell-section-header::marker {
  content: "";
}

.monthly-shell-section-header:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: -3px;
}

.monthly-shell-section[open] {
  border-color: color-mix(in srgb, var(--text-muted) 28%, var(--border));
}

.monthly-shell-section-title-group,
.monthly-shell-section-meta {
  display: flex;
  align-items: center;
  min-width: 0;
}

.monthly-shell-section-title-group {
  gap: 0.75rem;
  flex: 1 1 auto;
}

.monthly-shell-section-meta {
  flex: 0 0 auto;
  gap: 0.625rem;
}

.monthly-shell-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background-color: var(--surface-alt);
  color: var(--text-muted);
  font-size: 0.95rem;
  font-weight: 800;
}

.monthly-shell-icon svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.monthly-shell-section-title {
  min-width: 0;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  line-height: 1.25;
  overflow-wrap: anywhere;
  letter-spacing: var(--tracking-title);
}

.monthly-shell-badge {
  display: inline-flex;
  align-items: center;
  min-height: 1.5rem;
  padding: 0.125rem 0.625rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background-color: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.monthly-shell-chevron {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-size: 1.125rem;
  line-height: 1;
  transition: transform 0.15s ease;
}

.monthly-shell-section[open] > .monthly-shell-section-header .monthly-shell-chevron {
  transform: rotate(180deg);
}

.monthly-shell-section-body {
  padding: 1rem;
}

.monthly-shell-table-wrap {
  overflow-x: auto;
}

.monthly-shell-table-wrap.item-ledger-wrap {
  overflow: visible;
}

.monthly-shell-table-heading {
  border-bottom: 1px solid var(--border);
}

.monthly-shell-table-th {
  color: var(--text-muted);
}

.monthly-accounts-layout {
  container-type: inline-size;
  container-name: monthly-accounts;
}

@container monthly-accounts (max-width: 54rem) {
  .responsive-table-wrap {
    overflow: visible;
  }

  table,
  thead,
  tbody,
  tr,
  th,
  td {
    display: block;
    width: 100%;
    max-width: 100%;
  }

  thead {
    display: none;
  }

  tbody tr,
  .quick-update-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "name type"
      "fields fields";
    gap: 0.4rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    background-color: var(--surface);
    box-shadow: var(--shadow);
    padding: 0.9rem 1rem 1rem;
    margin: 0 0 0.75rem;
  }

  tbody tr:last-child,
  .quick-update-row:last-child {
    margin-bottom: 0;
  }

  .quick-update-col-name,
  .quick-update-col-type,
  .quick-update-col-fields {
    width: auto;
    max-width: 100%;
    padding: 0;
    border: 0;
  }

  .quick-update-col-name {
    grid-area: name;
    font-size: var(--fs-md);
    overflow-wrap: anywhere;
  }

  .quick-update-col-type {
    grid-area: type;
    justify-self: end;
    align-self: start;
    color: var(--text-muted);
    white-space: nowrap;
  }

  .quick-update-col-fields {
    grid-area: fields;
  }

  .quick-update-col-name .item-ledger-field-label {
    display: none;
  }

  .item-ledger-field-label {
    position: static;
    width: auto;
    height: auto;
    margin: 0 0 0.15rem;
    overflow: visible;
    clip: auto;
    display: block;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
  }

  /* E12-05-009: on a card the formula reads as three compact lines --
     "Credit limit  $8,500.00" / "− Available credit [____]" /
     "= Balance owing  $8,500.00" -- each operator beside the line it
     introduces rather than alone on a row of its own. */
  .monthly-accounts-layout .credit-card-balance-formula {
    grid-template-columns: 1rem minmax(0, 1fr);
    grid-template-rows: auto;
    min-width: 0;
    gap: 0.35rem 0.4rem;
  }

  .monthly-accounts-layout .credit-card-balance-field,
  .monthly-accounts-layout .credit-card-balance-field:nth-child(1),
  .monthly-accounts-layout .credit-card-balance-field:nth-child(3),
  .monthly-accounts-layout .credit-card-balance-field:nth-child(5) {
    grid-column: 2;
    grid-row: auto;
    justify-self: stretch;
    grid-template-rows: none;
  }

  .monthly-accounts-layout .credit-card-balance-field:nth-child(1) { grid-row: 1; }
  .monthly-accounts-layout .credit-card-balance-operator:nth-child(2),
  .monthly-accounts-layout .credit-card-balance-field:nth-child(3) { grid-row: 2; }
  .monthly-accounts-layout .credit-card-balance-operator:nth-child(4),
  .monthly-accounts-layout .credit-card-balance-field:nth-child(5) { grid-row: 3; }

  .monthly-accounts-layout .credit-card-balance-operator,
  .monthly-accounts-layout .credit-card-balance-operator:nth-child(2),
  .monthly-accounts-layout .credit-card-balance-operator:nth-child(4) {
    grid-column: 1;
    align-self: end;
    justify-self: center;
    line-height: 2.5rem;
  }

  .monthly-accounts-layout .credit-card-balance-field--static {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
  }

  .monthly-accounts-layout .credit-card-balance-field--static .credit-card-static-value {
    min-height: 2rem;
  }

  /* The second operator introduces the static result line. */
  .monthly-accounts-layout .credit-card-balance-operator:nth-child(4) {
    line-height: 2rem;
  }

  /* E12-05-RO-001: read-only rows are all static lines, so both operators
     sit on the shorter static-line height. */
  .monthly-accounts-layout .quick-update-readonly .credit-card-balance-operator:nth-child(2) {
    line-height: 2rem;
  }

  .monthly-accounts-layout .quick-update-money {
    max-width: none;
  }
}

/* E12-AQU-UX-001: which currency a Quick Update amount is in, said beside
   the account's type. Secondary metadata -- it never competes with the
   type or the amount, and it never implies conversion. */
.quick-update-currency {
  margin-left: 0.35rem;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

.credit-card-balance-formula {
  display: grid;
  grid-template-columns: minmax(8rem, 1fr) auto minmax(8rem, 1fr) auto minmax(8rem, 1fr);
  grid-template-rows: auto auto;
  align-items: stretch;
  gap: 0.625rem;
}

.credit-card-balance-field {
  display: grid;
  grid-row: 1 / 3;
  grid-template-rows: subgrid;
  row-gap: 0;
  min-width: 0;
}

.credit-card-balance-field:nth-child(1) {
  grid-column: 1;
}

.credit-card-balance-field:nth-child(3) {
  grid-column: 3;
}

.credit-card-balance-field:nth-child(5) {
  grid-column: 5;
}

.credit-card-balance-control {
  min-width: 0;
}

.credit-card-balance-operator {
  grid-row: 2;
  align-self: center;
  color: var(--text-muted);
  font-size: 1.125rem;
  font-weight: 700;
}

.credit-card-balance-operator:nth-child(2) {
  grid-column: 2;
}

.credit-card-balance-operator:nth-child(4) {
  grid-column: 4;
}

/* E12-05-009: a value the row shows but does not ask for (a credit limit,
   the formula's result) is plain text on the row, aligned with the inputs
   beside it -- never a filled box that reads as a disabled field. The
   result is a step stronger than the limit. */
.credit-card-static-value {
  display: flex;
  align-items: center;
  min-height: 2.5rem;
  color: var(--text);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.credit-card-static-value--result {
  font-weight: var(--fw-semibold);
}

/* E12-05-023: a destructive Admin action is set apart below the page's
   normal actions -- a divider and a quiet heading, not a louder control. */
.admin-danger-zone {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.admin-danger-zone__title {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--text);
}

/* E12-05-003: a row's own autosave state, said quietly right after the
   account name -- inline, so it reserves no space and never moves the
   row. Saved fades away on its own; Not saved stays until the next save. */
.quick-update-row-status {
  margin-left: 0.45rem;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  white-space: nowrap;
}

.quick-update-row-status[data-state="saved"] {
  color: var(--success);
  animation: quick-update-row-saved 2.4s ease forwards;
}

.quick-update-row-status[data-state="error"] {
  color: var(--danger);
}

@keyframes quick-update-row-saved {
  0%, 70% { opacity: 1; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .quick-update-row-status[data-state="saved"] {
    animation: none;
  }
}

/* E12-05-010: an editable Quick Update / MonthCast amount -- right-aligned
   tabular figures in a bounded field, with the Family's currency marker
   beside it (never inside the value, which stays the plain parsed form). */
.quick-update-money {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.4rem;
  max-width: 15rem;
}

.quick-update-money > .field-input {
  flex: 1 1 0;
  min-width: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.quick-update-money__marker {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.quick-update-money > .field-error {
  flex-basis: 100%;
  margin-top: 0;
}

.credit-card-balance-formula .quick-update-money {
  max-width: none;
}

@media (max-width: 760px) {
  /* E12-05-017: the pinned section header gives the list a little more of
     the phone's height (it stays sticky; only its vertical padding eases). */
  .monthly-shell-section-header {
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.55rem 0.75rem;
  }

  .monthly-shell-section-title-group {
    gap: 0.625rem;
  }

  .monthly-shell-section-meta {
    gap: 0.375rem;
  }

  .monthly-shell-section-body {
    padding: 0.75rem;
  }

  .monthly-shell-badge {
    font-size: var(--fs-2xs);
    padding-inline: 0.5rem;
  }

  /* E12-05-009: both pages that draw the formula (Quick Update and
     MonthCast Accounts & Credit) sit in `.monthly-accounts-layout`, whose
     container query lays it out compactly at this width. */
}

/* E12-05-010: a MonthCast amount is the row's figure -- tabular, one step
   heavier than the name beside it; "overridden" / "of $X" stay muted. */
.item-ledger-amount-value,
.cp-timeline-amount-value {
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

/* E12-05-011: a quiet directional cue on every MonthCast amount (Timeline
   and Category) -- the semantic green / red softened toward the text colour,
   in both themes. Where a list mixes directions the word is also spoken
   (sr-only), so colour is never the only cue. */
.amount-flow--inflow {
  color: var(--flow-inflow);
}

.amount-flow--outflow {
  color: var(--flow-outflow);
}

/* Historical Cash Position timeline */

.cp-timeline-wrap {
  container-type: inline-size;
  container-name: cp-timeline;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  overflow: visible;
  background-color: var(--surface);
}

/* Same reasoning as the ledger's actions column: a wrapping cluster's
   min-content width is only its widest chip, so auto table layout could
   allocate a three-action row far less than it needs and leave it cramped
   against the right edge. The floor is lifted in the narrow container query
   below, where the actions span the card's own full row. */
.cp-timeline-table .cp-timeline-col-actions {
  min-width: 17rem;
}

.cp-timeline-table {
  width: 100%;
  border-collapse: collapse;
}

.cp-timeline-head,
.cp-timeline-row,
.cp-timeline-today {
  border-bottom: 1px solid var(--border);
}

.cp-timeline-today {
  background: var(--selected-tint);
}

/* E12-05: "Today" in a Timeline is a POSITION -- an Orange hairline with a
   small label, the same mark as the Calendar's today (was blue text). */
.cp-timeline-today__cell {
  position: relative;
  padding: 0.35rem 1rem;
  text-align: center;
}

.cp-timeline-today__cell::before {
  position: absolute;
  top: 50%;
  right: 1rem;
  left: 1rem;
  border-top: 1px solid var(--selected-line);
  content: "";
}

.cp-timeline-today__label {
  position: relative;
  padding: 0 0.6rem;
  background: var(--selected-tint);
  color: var(--accent);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

/* E12-MCS-UX-017: a date is one token -- 2026-10-01 never breaks across
   two lines to give the columns beside it a little more room. */
.cp-timeline-col-date {
  white-space: nowrap;
  width: 1%;
}

.cp-timeline-col-amount {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cp-timeline-col-status .item-ledger-status-badge {
  white-space: nowrap;
}

@container cp-timeline (max-width: 48rem) {
  .cp-timeline-table thead {
    display: none;
  }

  .cp-timeline-table,
  .cp-timeline-table tbody {
    display: block;
    width: 100%;
  }

  .cp-timeline-today,
  .cp-timeline-row {
    display: grid;
    width: 100%;
    box-sizing: border-box;
    padding: 0.75rem 0.9rem;
    border-bottom: 0;
    margin-bottom: 0.65rem;
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    background-color: var(--surface);
  }

  .cp-timeline-today {
    grid-template-columns: 1fr;
  }

  .cp-timeline-today td {
    padding: 0;
    text-align: center;
  }

  .cp-timeline-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "date status"
      "name name"
      "account amount"
      "actions actions";
    gap: 0.25rem 0.75rem;
  }

  .cp-timeline-col-date {
    grid-area: date;
    padding: 0;
    width: auto;
    white-space: nowrap;
  }

  .cp-timeline-col-status {
    grid-area: status;
    padding: 0;
    justify-self: end;
  }

  .cp-timeline-col-name {
    grid-area: name;
    padding: 0;
    overflow-wrap: anywhere;
  }

  .cp-timeline-col-account {
    grid-area: account;
    padding: 0;
    min-width: 0;
  }

  .cp-timeline-col-amount {
    grid-area: amount;
    padding: 0;
    text-align: right;
  }

  /* E12-MCS-006: the card carries the same action cluster the Category
     card does -- one row, left aligned, under the figures it acts on. */
  .cp-timeline-col-actions {
    grid-area: actions;
    padding: 0.35rem 0 0;
    /* The table-mode floor must not widen a phone card. */
    min-width: 0;
  }

  .cp-timeline-col-actions .occurrence-actions {
    justify-content: flex-start;
  }

  /* Same touch target as the Category card's chips. */
  .cp-timeline-col-actions .occurrence-action__btn {
    min-height: 2.5rem;
    padding: 0.4rem 0.45rem;
    font-size: var(--fs-sm);
  }

  /* E12-05-017: the Timeline's rows are the rows of one list on a phone --
     divided, not cards stacked inside the Timeline's own card. */
  .cp-timeline-today,
  .cp-timeline-row {
    margin-bottom: 0;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    background-color: transparent;
  }

  .cp-timeline-table tbody tr:last-child {
    border-bottom: 0;
  }
}

/* Dashboard Investment Portfolio */

.investment-portfolio {
  margin-top: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: 0;
  background-color: transparent;
  box-shadow: none;
}

.investment-portfolio-header,
.investment-portfolio-heading,
.investment-portfolio-actions,
.investment-owner-title,
.investment-allocation {
  display: flex;
  align-items: center;
}

.investment-portfolio-header {
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.investment-portfolio-heading {
  min-width: 0;
  gap: 0.4rem;
}

.investment-portfolio-heading h2 {
  color: var(--text);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
}

.investment-portfolio-actions {
  justify-content: flex-end;
  gap: 0.65rem;
  min-width: 0;
}

.investment-privacy-button {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background-color: var(--surface);
  color: var(--text-muted);
}

.investment-privacy-button:hover {
  border-color: color-mix(in srgb, var(--action-primary) 35%, var(--border));
  background-color: var(--surface-hover);
  color: var(--action-primary);
}

.investment-privacy-button:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--focus) 42%, transparent);
  outline-offset: 2px;
}

.investment-privacy-button svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
}

.investment-portfolio[data-investment-privacy="revealed"] .investment-privacy-slash {
  display: none;
}

.investment-last-updated {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  color: var(--text-muted);
  text-align: right;
  white-space: nowrap;
}

.investment-updated-label,
.investment-updated-value {
  display: inline;
}

.investment-updated-label {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
}

.investment-updated-value {
  color: var(--text);
  font-size: var(--fs-xs);
}

.investment-portfolio[data-investment-privacy="masked"] [data-investment-sensitive] {
  position: relative;
  color: transparent !important;
  user-select: none;
}

.investment-portfolio[data-investment-privacy="masked"] [data-investment-sensitive] > * {
  visibility: hidden;
}

.investment-portfolio[data-investment-privacy="masked"] [data-investment-sensitive]::after {
  content: "••••";
  position: absolute;
  top: 50%;
  left: 50%;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

.investment-portfolio[data-investment-privacy="masked"] .investment-category-donut {
  background-image: none;
}

.investment-portfolio[data-investment-privacy="masked"] .investment-category-donut::before {
  display: none;
}

.investment-empty-state {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
  padding: 1rem;
  border: 1px dashed var(--border);
  border-radius: 0.625rem;
  background-color: var(--surface-alt);
}

.investment-empty-state h3 {
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-title);
}

.investment-empty-state p,
.investment-inline-empty,
.investment-panel-empty {
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

.investment-empty-state p {
  margin-top: 0.2rem;
}

.investment-kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
}

.investment-kpi-card,
.investment-owner-card,
.investment-panel {
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 0.625rem;
  background-color: var(--surface);
  box-shadow: var(--shadow);
}

.investment-kpi-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 6.5rem;
  padding: 0.9rem;
}

.investment-kpi-label,
.investment-owner-metrics dt {
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
}

.investment-kpi-value {
  margin-top: 0.45rem;
  color: var(--text);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
}

.investment-kpi-subtitle {
  margin-top: 0.25rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
}

.investment-kpi-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 999px;
  font-size: 1.15rem;
  font-weight: 800;
}

.investment-kpi-icon-portfolio {
  background-color: var(--success-bg);
  color: var(--success);
}

.investment-kpi-icon-room {
  background-color: color-mix(in srgb, var(--data-blue) 12%, var(--surface));
  color: var(--data-blue);
}

.investment-kpi-icon-performance {
  background-color: color-mix(in srgb, var(--success) 11%, var(--surface));
  color: var(--success);
}

.investment-kpi-icon-accounts {
  background-color: color-mix(in srgb, var(--data-blue) 10%, var(--surface));
  color: var(--data-blue);
}

.investment-account-status-counts {
  margin-top: 0.45rem;
}

.investment-account-count-active {
  margin-top: 0;
}

.investment-account-count-inactive {
  margin-top: 0.2rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
}

.investment-value-positive {
  color: var(--success);
}

.investment-value-negative {
  color: var(--danger);
}

.investment-section-heading {
  margin: 1rem 0 0.55rem;
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.investment-owner-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.75rem;
}

.investment-owner-card {
  padding: 0.8rem;
}

.investment-owner-title {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--text);
  font-size: var(--fs-sm);
}

.investment-owner-avatar {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 700;
}

.investment-owner-avatar-small {
  width: 1.35rem;
  height: 1.35rem;
  margin-right: 0.35rem;
  font-size: 0.55rem;
  vertical-align: middle;
}

.investment-owner-metrics {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) auto;
  gap: 0.65rem;
  margin-top: 0.8rem;
}

.investment-owner-metrics dd {
  margin-top: 0.2rem;
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  overflow-wrap: anywhere;
}

.investment-table-grid {
  display: grid;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

/* Three equal columns. The zero minimum is what keeps them equal: a card
   is never widened by what its table would like to be, and a table that
   needs more room scrolls inside its own wrapper instead. */
.investment-table-grid-primary {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.investment-panel {
  padding: 0.8rem;
}

.investment-panel h3 {
  margin-bottom: 0.65rem;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

.investment-panel h3 small {
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
}

.investment-category-layout {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.75rem;
}

.investment-category-donut {
  position: relative;
  display: grid;
  place-items: center;
  width: 12rem;
  height: 12rem;
  margin: 0 auto;
  flex: 0 0 auto;
  border-radius: 999px;
  background-color: var(--surface-alt);
  background-image: var(--investment-category-donut);
}

/* Depth for the ring is a layer over the slices, never a change to them:
   the conic gradient above keeps its angles, radius and colours. The layer
   adds a faint light from the top left (the ring carries no text to
   protect), the same shade as a Treemap tile toward the bottom right, a
   soft shade hugging the inner edge, and a hairline rim. The centre disc
   sits above it. */
.investment-category-donut::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image:
    radial-gradient(closest-side, transparent 63%, var(--investment-chart-depth-shade) 64.5%, transparent 80%),
    linear-gradient(150deg, var(--investment-chart-depth-light) 0%, transparent 45%, transparent 52%, var(--investment-chart-depth-shade) 100%);
  box-shadow: inset 1px 1px 0 var(--investment-chart-edge-light), inset -1px -1px 0 var(--investment-chart-edge-shade);
  pointer-events: none;
}

.investment-category-donut-center {
  display: flex;
  position: absolute;
  inset: 2.15rem;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  /* The disc is a circle, so a square box's corners fall outside it. The
     inline padding keeps text off the curve rather than letting it run to
     the edge and appear clipped. */
  padding-inline: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background-color: var(--surface);
  color: var(--text);
  text-align: center;
}

/* E12-07-03G-UI-001: the centre label is a caption inside a ~7.7rem disc,
   and the name it carries has no length bound -- an "Other" category is
   "Other · " plus up to 150 characters the user typed, and the catalog
   itself reaches "Balanced / Multi-Asset". Left to wrap, a long name
   stacked two or three lines against the percentage and spilled past the
   curve. One line with an ellipsis is the same treatment this codebase
   already uses wherever a name meets a fixed box (sidebar links, the
   account menu, calendar occurrences). The full name is never lost: it
   stays canonical in the data and is shown in full in the allocation
   table directly beside this chart. */
.investment-category-donut-center small,
.investment-category-donut-center strong {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.investment-category-donut-center small {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  line-height: 1.25;
}

.investment-category-donut-center strong {
  margin-top: 0.1rem;
  font-size: var(--fs-lg);
}

.investment-category-chart-empty {
  margin: 0.75rem 0;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  text-align: center;
}

.investment-category-key {
  display: inline-block;
  width: 0.45rem;
  height: 0.45rem;
  margin-right: 0.25rem;
  border-radius: 999px;
  background-color: var(--investment-chart-color);
  vertical-align: middle;
}

.investment-chart-color-1 { --investment-chart-color: var(--investment-chart-series-1); --investment-chart-ink: var(--investment-chart-series-1-ink); }
.investment-chart-color-2 { --investment-chart-color: var(--investment-chart-series-2); --investment-chart-ink: var(--investment-chart-series-2-ink); }
.investment-chart-color-3 { --investment-chart-color: var(--investment-chart-series-3); --investment-chart-ink: var(--investment-chart-series-3-ink); }
.investment-chart-color-4 { --investment-chart-color: var(--investment-chart-series-4); --investment-chart-ink: var(--investment-chart-series-4-ink); }
.investment-chart-color-5 { --investment-chart-color: var(--investment-chart-series-5); --investment-chart-ink: var(--investment-chart-series-5-ink); }
.investment-chart-color-6 { --investment-chart-color: var(--investment-chart-series-6); --investment-chart-ink: var(--investment-chart-series-6-ink); }
.investment-chart-color-7 { --investment-chart-color: var(--investment-chart-series-7); --investment-chart-ink: var(--investment-chart-series-7-ink); }
.investment-chart-color-8 { --investment-chart-color: var(--investment-chart-series-8); --investment-chart-ink: var(--investment-chart-series-8-ink); }
.investment-chart-color-9 { --investment-chart-color: var(--investment-chart-series-9); --investment-chart-ink: var(--investment-chart-series-9-ink); }
.investment-chart-color-10 { --investment-chart-color: var(--investment-chart-series-10); --investment-chart-ink: var(--investment-chart-series-10-ink); }
.investment-chart-color-11 { --investment-chart-color: var(--investment-chart-series-11); --investment-chart-ink: var(--investment-chart-series-11-ink); }
.investment-chart-color-12 { --investment-chart-color: var(--investment-chart-series-12); --investment-chart-ink: var(--investment-chart-series-12-ink); }
.investment-chart-color-13 { --investment-chart-color: var(--investment-chart-series-13); --investment-chart-ink: var(--investment-chart-series-13-ink); }
.investment-chart-color-14 { --investment-chart-color: var(--investment-chart-series-14); --investment-chart-ink: var(--investment-chart-series-14-ink); }
.investment-chart-color-15 { --investment-chart-color: var(--investment-chart-series-15); --investment-chart-ink: var(--investment-chart-series-15-ink); }
.investment-chart-color-16 { --investment-chart-color: var(--investment-chart-series-16); --investment-chart-ink: var(--investment-chart-series-16-ink); }
.investment-chart-color-17 { --investment-chart-color: var(--investment-chart-series-17); --investment-chart-ink: var(--investment-chart-series-17-ink); }
.investment-chart-color-18 { --investment-chart-color: var(--investment-chart-series-18); --investment-chart-ink: var(--investment-chart-series-18-ink); }
.investment-chart-color-19 { --investment-chart-color: var(--investment-chart-series-19); --investment-chart-ink: var(--investment-chart-series-19-ink); }
.investment-chart-color-20 { --investment-chart-color: var(--investment-chart-series-20); --investment-chart-ink: var(--investment-chart-series-20-ink); }
.investment-chart-color-other { --investment-chart-color: var(--investment-chart-other); --investment-chart-ink: var(--text); }

/* Depth for the Portfolio Treemap and Donut only: a faint shade toward the
   bottom right, a hairline edge, and (on the Donut ring) a faint light from
   the top left -- laid over the identity colour, never replacing it. Scoped
   to the Portfolio section, so no other chart inherits it. */
[data-portfolio-charts] {
  --investment-chart-depth-light: rgba(255, 255, 255, 0.16);
  --investment-chart-depth-shade: rgba(0, 0, 0, 0.17);
  --investment-chart-edge-light: rgba(255, 255, 255, 0.4);
  --investment-chart-edge-shade: rgba(0, 0, 0, 0.2);
}

/* Dark is quieter than Light throughout: no glow on the dark card, and no
   shade deep enough to muddy a colour. */
[data-theme="dark"] [data-portfolio-charts] {
  --investment-chart-depth-light: rgba(255, 255, 255, 0.09);
  --investment-chart-depth-shade: rgba(0, 0, 0, 0.12);
  --investment-chart-edge-light: rgba(255, 255, 255, 0.2);
  --investment-chart-edge-shade: rgba(0, 0, 0, 0.2);
}

/* WD-02: each Portfolio Overview card has its own chart type. Treemap and
   Donut are two views of the same card and both are rendered; the card's
   `data-portfolio-visualization` (page state only -- never stored) decides
   which is shown. It is rendered as "treemap", so that is what every card
   starts on, and one card's choice never touches another's. */
[data-portfolio-card][data-portfolio-visualization="treemap"] [data-portfolio-view="donut"],
[data-portfolio-card][data-portfolio-visualization="donut"] [data-portfolio-view="treemap"] {
  display: none;
}

/* The card's title and its chart-type control share one line; the control
   never adds a row of its own. */
.investment-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-height: 1.75rem;
  margin-bottom: 0.65rem;
}

.investment-panel-header h3 {
  min-width: 0;
  margin-bottom: 0;
}

.investment-chart-toggle {
  display: inline-flex;
  flex: 0 0 auto;
  gap: 0.2rem;
}

.investment-chart-toggle__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 1.75rem;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}

/* The mark stays small; the target does not. It reaches 2.5rem tall into
   the header's own spacing, and a touch screen widens the button to match. */
.investment-chart-toggle__btn::before {
  content: "";
  position: absolute;
  inset: -0.375rem 0;
}

@media (pointer: coarse) {
  .investment-chart-toggle__btn { width: 2.5rem; }
}

/* Hover belongs to a pointer that can hover: on a touch screen it would
   stick after a tap and leave the tooltip lying over the chart. */
@media (hover: hover) {
  .investment-chart-toggle__btn:not([aria-pressed="true"]):hover {
    background: var(--surface-hover);
    color: var(--text);
  }

  .investment-chart-toggle__btn:hover .investment-chart-toggle__tooltip {
    opacity: 1;
    transform: translateY(0);
  }
}

.investment-chart-toggle__btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

.investment-chart-toggle__btn[aria-pressed="true"] {
  border-color: var(--selected-line);
  background: var(--selected-tint);
  color: var(--selected-mark);
}

.investment-chart-toggle__icon {
  width: 1rem;
  height: 1rem;
}

.investment-chart-toggle__tooltip {
  position: absolute;
  z-index: 20;
  top: calc(100% + 0.4rem);
  right: 0;
  width: max-content;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  box-shadow: var(--shadow-menu);
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.3;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-0.15rem);
  transition: opacity 120ms ease, transform 120ms ease;
}

.investment-chart-toggle__btn:focus-visible .investment-chart-toggle__tooltip {
  opacity: 1;
  transform: translateY(0);
}

/* One slot, one height, for both views: a card on the Donut and its
   neighbour on the Treemap start their tables on the same line. */
.investment-visualization {
  display: grid;
  min-width: 0;
  min-height: 13.5rem;
  align-items: center;
}

.investment-treemap-block {
  min-width: 0;
  align-self: start;
}

.investment-treemap {
  position: relative;
  width: 100%;
  height: 13.5rem;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background-color: var(--surface-alt);
}

/* A tile's AREA is its share of the card's Value; its colour is identity
   only. The surface-coloured border is the gap between neighbours. */
.investment-treemap__tile {
  position: absolute;
  box-sizing: border-box;
  display: block;
  margin: 0;
  padding: 0;
  border: 1px solid var(--surface);
  border-radius: 3px;
  background-color: var(--investment-chart-color);
  /* Depth is paint only: a shade toward the bottom and a hairline edge
     inside the tile's own box. The box itself -- and so the area that
     stands for the Value -- is exactly what it was. The shade never starts
     above 2.4rem, whatever the tile's shape, so the two label lines at the
     top carry the identity colour untouched and read against exactly the
     colour their ink was chosen for; a tile too short to have that much
     room is left to its edges alone. */
  background-image: linear-gradient(180deg, transparent max(42%, 2.4rem), var(--investment-chart-depth-shade) max(100%, 5.5rem));
  box-shadow: inset 1px 1px 0 var(--investment-chart-edge-light), inset -1px -1px 0 var(--investment-chart-edge-shade);
  color: var(--investment-chart-ink);
  font: inherit;
  cursor: pointer;
  container-type: size;
}

/* A sliver is still a target: every tile answers to at least 1.5rem around
   its centre, and later (smaller) tiles sit above earlier ones, so the
   smallest tile wins where two overlap. */
.investment-treemap__tile::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 1.5rem);
  height: max(100%, 1.5rem);
  transform: translate(-50%, -50%);
}

.investment-treemap__tile:hover,
.investment-treemap__tile[data-item-active] {
  filter: brightness(1.08) saturate(1.05);
}

.investment-treemap__tile[data-item-active] {
  z-index: 1;
  box-shadow: inset 0 0 0 2px var(--investment-chart-ink);
}

.investment-treemap__tile:focus-visible {
  z-index: 2;
  outline: 2px solid var(--focus);
  outline-offset: -2px;
  box-shadow: inset 0 0 0 4px var(--surface);
}

/* The label is a convenience on tiles with room for it; the tooltip is
   what identifies a tile. It is clipped to the tile and never wraps into a
   neighbour. */
.investment-treemap__label {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.3rem 0.4rem;
  overflow: hidden;
  font-size: var(--fs-2xs);
  line-height: var(--lh-tight);
  text-align: left;
  pointer-events: none;
}

.investment-treemap__name {
  overflow: hidden;
  font-weight: var(--fw-semibold);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.investment-treemap__share {
  font-variant-numeric: tabular-nums;
}

@container (max-width: 3.5rem) {
  .investment-treemap__label { display: none; }
}

@container (max-height: 1.75rem) {
  .investment-treemap__label { display: none; }
}

@container (max-height: 2.75rem) {
  .investment-treemap__share { display: none; }
}

/* The Donut's slices as interactive areas over the drawn ring. They are
   transparent: the ring's paint, its depth layer and its angles are
   untouched. A slice is shown as hovered, selected or focused by a tint
   and an outline that follow its own shape. */
.investment-donut-block {
  min-width: 0;
}

.investment-donut__segments {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.investment-donut__segment {
  fill: transparent;
  stroke: none;
  outline: none;
  cursor: pointer;
  pointer-events: all;
}

@media (hover: hover) {
  .investment-donut__segment:hover {
    fill: rgba(255, 255, 255, 0.14);
  }
}

.investment-donut__segment[data-item-active] {
  fill: rgba(255, 255, 255, 0.14);
  stroke: var(--investment-chart-ink);
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
}

.investment-donut__segment:focus-visible {
  stroke: var(--focus);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
}

/* A slice's label is its percentage, set level -- never turned, so never
   upside down -- and centred on the middle of the ring within the slice.
   Only a slice with room for it has one. The faint glow in the slice's own
   colour keeps the ink reading against that colour where the ring's depth
   layer has lightened or shaded it. */
.investment-donut__label {
  position: absolute;
  transform: translate(-50%, -50%);
  color: var(--investment-chart-ink);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: var(--lh-tight);
  white-space: nowrap;
  text-shadow:
    0 0 0.15em var(--investment-chart-color),
    0 0 0.3em var(--investment-chart-color),
    0 0 0.3em var(--investment-chart-color);
  pointer-events: none;
}

.investment-treemap-tooltip__title {
  color: var(--text);
  overflow-wrap: anywhere;
}

.investment-table-wrap {
  max-width: 100%;
  overflow-x: auto;
}

.investment-table {
  width: 100%;
  border-collapse: collapse;
  color: var(--text);
  font-size: var(--fs-2xs);
}

.investment-table th,
.investment-table td {
  padding: 0.55rem 0.35rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: middle;
}

.investment-table thead th {
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
}

.investment-table tfoot th {
  border-bottom: 0;
  color: var(--text);
  font-weight: var(--fw-semibold);
}

.investment-table .investment-number {
  text-align: right;
  white-space: nowrap;
}

/* The three Portfolio tables -- Accounts by Value, By Account Type, By
   Investment Category -- share one three-column layout: Value takes only
   the width its content needs -- the same in all three, which end in the
   same Total -- YTD has one fixed width, and the name column gets
   everything else. The cards being equal, the two figure columns line up
   from card to card. */
.investment-aggregate-table th:nth-child(2),
.investment-aggregate-table td:nth-child(2) {
  width: 1%;
}

/* YTD is one width in every table rather than whatever each table's own
   figures happen to need, so the Value column beside it starts at the same
   place in all three. It holds any return up to -100.00%. */
.investment-aggregate-table th:nth-child(3),
.investment-aggregate-table td:nth-child(3) {
  width: 4.75rem;
  white-space: nowrap;
}

/* The name column is what gives way: it may break a long name rather than
   hold the table wider than its card, so the tables keep the same
   geometry -- and nothing scrolls sideways -- at the narrowest widths too. */
.investment-aggregate-table th:first-child,
.investment-aggregate-table td:first-child {
  overflow-wrap: anywhere;
}

.investment-table a,
.investment-panel-link {
  color: var(--action-primary);
  font-weight: var(--fw-semibold);
}

/* E12-05: a Portfolio legend row's category / type glyph -- a plain muted
   line icon (the chart-colour key beside it already anchors the row, so
   no circle), sized to keep the label on the same line. */
.investment-row-icon {
  display: inline-flex;
  margin-right: 0.3rem;
  color: var(--text-muted);
  vertical-align: -0.12em;
}

.investment-row-icon__svg {
  width: 0.875rem;
  height: 0.875rem;
}

.investment-allocation {
  justify-content: flex-end;
  gap: 0.35rem;
  white-space: nowrap;
}

/* E12-06 F029: the bar gives way first when a card is narrow, so the table
   fits its card and no column header is cut off at the scroll edge. */
.investment-allocation-bar {
  flex: 1 1 3.25rem;
  width: auto;
  min-width: 1.25rem;
  max-width: 3.25rem;
  height: 0.35rem;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  background-color: var(--surface-alt);
}

.investment-allocation-bar::-webkit-progress-bar {
  background-color: var(--surface-alt);
  border-radius: 999px;
}

.investment-allocation-bar::-webkit-progress-value {
  background-color: var(--data-blue);
  border-radius: 999px;
}

.investment-allocation-bar::-moz-progress-bar {
  background-color: var(--data-blue);
  border-radius: 999px;
}

.investment-account-mask {
  display: block;
  margin-top: 0.15rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
}

.investment-panel-empty {
  padding: 1.25rem 0.5rem;
  text-align: center;
}

.investment-panel-empty .btn {
  margin-top: 0.65rem;
}

.investment-panel-link {
  display: inline-block;
  margin-top: 0.75rem;
  font-size: var(--fs-2xs);
}

.investment-incomplete-marker {
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
  margin-left: 0.15rem;
  cursor: help;
}

/* E12-05-013: the note's pointer to Investment Accounts reads as a link. */
.investment-information-note a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.investment-information-note {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  margin-top: 0.75rem;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background-color: var(--surface-alt);
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  line-height: 1.45;
}

.dashboard-bottom-grid {
  margin-top: 1.5rem;
}

.dashboard-onboarding {
  padding: 1.15rem 1.25rem 1.25rem;
}

.dashboard-onboarding-mobile {
  display: none;
}

.dashboard-onboarding-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.dashboard-onboarding-ready {
  margin: 0.85rem 0 0;
  color: var(--success);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

.dashboard-onboarding-essentials {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
  margin-top: 1rem;
}

.dashboard-onboarding-step {
  display: flex;
  min-height: 5rem;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--surface-alt);
  color: var(--text);
  font-size: var(--fs-base);
  text-decoration: none;
}

.dashboard-onboarding-step:hover {
  background-color: var(--surface-hover);
}

.dashboard-onboarding-step strong {
  color: var(--action-primary);
  font-size: var(--fs-xs);
}

/* E12-06 F011: a Read-Only viewer's steps are status, not actions -- no
   link colour and no hover affordance. */
.dashboard-onboarding-step--static:hover {
  background-color: var(--surface-alt);
}

.dashboard-onboarding-step--static[data-complete="false"] strong {
  color: var(--text-muted);
}

.dashboard-onboarding-step[data-complete="true"] {
  border-color: var(--success);
}

.dashboard-onboarding-step[data-complete="true"] strong {
  color: var(--success);
}

.dashboard-onboarding-action {
  margin-top: 1rem;
}

.dashboard-onboarding-optional {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.85rem;
  margin-top: 1rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

.dashboard-onboarding-optional a,
.dashboard-onboarding-details a {
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

.dashboard-onboarding-mobile-essentials {
  display: grid;
  gap: 0.45rem;
  margin-top: 0.85rem;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.dashboard-onboarding-details {
  margin-top: 1rem;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.dashboard-onboarding-details summary {
  cursor: pointer;
  font-weight: var(--fw-semibold);
}

.dashboard-onboarding-details > div {
  display: grid;
  gap: 0.6rem;
  margin-top: 0.75rem;
}

.dashboard-section-title {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-title);
}

.dashboard-section-helper,
.dashboard-inline-empty {
  margin: 0.3rem 0 0;
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

.financial-health-card {
  --financial-health-state: var(--text-muted);
  padding: 1rem 1.15rem 1.05rem;
}

.financial-health-card[data-health-status="at-risk"] {
  --financial-health-state: var(--danger);
}

.financial-health-card[data-health-status="needs-attention"] {
  --financial-health-state: var(--warning-strong);
}

.financial-health-card[data-health-status="slightly-short"] {
  --financial-health-state: var(--warning-fill);
}

.financial-health-card[data-health-status="healthy"] {
  --financial-health-state: color-mix(in srgb, var(--success) 62%, var(--surface));
}

.financial-health-card[data-health-status="strong"] {
  --financial-health-state: var(--success);
}

/* Mixing toward --text deepens green in light and brightens it in dark. */
.financial-health-card[data-health-status="excellent"] {
  --financial-health-state: color-mix(in srgb, var(--success) 72%, var(--text));
}

.financial-health-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.financial-health-title {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}

/* E12-04: sized and weighted below .spendable-current-amount (Current
   Leftover) on purpose -- clearly the secondary number on the Dashboard,
   not a competing peer -- while staying above the Forecast's inline
   figure (.spendable-forecast-selected-amount, ~1.05-1.15rem) so it
   remains tertiary. */
.financial-health-primary-value {
  margin-top: 0.35rem;
  color: var(--text);
  font-size: clamp(1.3rem, 2.4vw, 1.55rem);
  font-weight: 620;
  letter-spacing: -0.02em;
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.financial-health-primary-value[data-tone="positive"] {
  color: var(--success);
}

.financial-health-primary-value[data-tone="negative"] {
  color: var(--danger);
}

.financial-health-primary-label {
  margin-top: 0.15rem;
  color: var(--text);
  font-size: 1rem;
  line-height: 1.2;
}

.financial-health-rating {
  display: grid;
  justify-items: end;
  gap: 0.3rem;
  text-align: right;
}

/* One treatment for every status: a lightly tinted chip with a state dot.
   The label stays in body text colour so contrast holds in both themes. */
.financial-health-status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.32rem 0.85rem 0.32rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--financial-health-state) 38%, var(--border));
  border-radius: 999px;
  background: color-mix(in srgb, var(--financial-health-state) 9%, var(--surface));
  color: var(--text);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25;
  white-space: nowrap;
}

.financial-health-status::before {
  content: "";
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  background: var(--financial-health-state);
}

.financial-health-coverage {
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 720;
}

/* Top padding reserves room for the coverage label above the pointer. */
.financial-health-scale {
  margin-top: 0.95rem;
  padding-top: 1.35rem;
}

.financial-health-scale__track {
  position: relative;
  display: grid;
  grid-template-columns: 70fr 20fr 10fr 20fr 30fr 50fr;
  height: 0.75rem;
  margin-inline: 0.55rem;
}

.financial-health-scale__segment {
  min-width: 0;
  border-right: 1px solid color-mix(in srgb, var(--surface) 78%, transparent);
}

.financial-health-scale__segment:first-child {
  border-radius: 999px 0 0 999px;
}

.financial-health-scale__segment--at-risk {
  background: color-mix(in srgb, var(--danger) 76%, var(--surface));
}

.financial-health-scale__segment--needs-attention {
  background: color-mix(in srgb, var(--warning-strong) 76%, var(--surface));
}

.financial-health-scale__segment--slightly-short {
  background: color-mix(in srgb, var(--warning-fill) 74%, var(--surface));
}

.financial-health-scale__segment--healthy {
  background: color-mix(in srgb, var(--success) 56%, var(--surface));
}

.financial-health-scale__segment--strong {
  background: color-mix(in srgb, var(--success) 88%, var(--surface));
}

/* Same deepened green as the Excellent status dot. */
.financial-health-scale__segment--excellent {
  border-right: 0;
  border-radius: 0 999px 999px 0;
  background: color-mix(in srgb, var(--success) 72%, var(--text));
}

.financial-health-scale--unrated .financial-health-scale__segment {
  border-color: color-mix(in srgb, var(--surface) 70%, transparent);
  background: color-mix(in srgb, var(--text-muted) 22%, var(--surface));
}

.financial-health-scale__tick {
  position: absolute;
  top: 100%;
  height: 0.3rem;
  border-left: 1px solid var(--border);
}

/* Positions on the proportional 0–200 scale. 100% is labelled only by the
   break-even line so the closely spaced 90/100/120 labels never collide. */
.financial-health-scale__tick--70,
.financial-health-scale__threshold--70 {
  left: 35%;
}

.financial-health-scale__tick--90,
.financial-health-scale__threshold--90 {
  left: 45%;
}

.financial-health-scale__tick--100,
.financial-health-scale__break-even {
  left: 50%;
}

.financial-health-scale__tick--120,
.financial-health-scale__threshold--120 {
  left: 60%;
}

.financial-health-scale__tick--150,
.financial-health-scale__threshold--150 {
  left: 75%;
}

/* Coverage label and pointer move as one unit centred on the precise
   position; the pointer tip meets the top of the bar without covering it. */
.financial-health-scale__marker {
  position: absolute;
  z-index: 2;
  bottom: calc(100% + 0.1rem);
  left: var(--financial-health-marker);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  transform: translateX(-50%);
  pointer-events: none;
}

/* The marker only ever moves when app.js applies a new server-computed
   position for the Savings Contributions scenario. app.js supplies the
   adaptive duration and, where there is room for it, the overshoot peak:
   both are positions it read from the server's own markup. A straight move
   (a very short one, or a target already at the end of the scale) uses the
   transition; otherwise one decelerating pass just past the target and one
   settle back onto it. No bounce, no second excursion. */
.financial-health-scale__marker--moving {
  transition: left var(--financial-health-marker-duration, 480ms)
    cubic-bezier(0.22, 0.61, 0.36, 1);
}

@keyframes financial-health-marker-settle {
  0% {
    left: var(--financial-health-marker-from);
    animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  72% {
    left: var(--financial-health-marker-peak);
    animation-timing-function: cubic-bezier(0.4, 0, 0.25, 1);
  }

  100% {
    left: var(--financial-health-marker);
  }
}

.financial-health-scale__marker--settling {
  animation: financial-health-marker-settle
    var(--financial-health-marker-duration, 480ms) both;
}

@media (prefers-reduced-motion: reduce) {
  .financial-health-scale__marker--moving {
    transition: none;
  }

  .financial-health-scale__marker--settling {
    animation: none;
  }
}

.financial-health-scale__marker-label {
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.financial-health-scale__pointer {
  width: 0.85rem;
  height: 0.6rem;
  background: var(--text);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

.financial-health-scale__overflow {
  position: absolute;
  top: 50%;
  left: calc(100% + 0.45rem);
  display: inline-flex;
  width: 0.9rem;
  height: 0.9rem;
  align-items: center;
  justify-content: center;
  color: var(--financial-health-state);
  transform: translateY(-50%);
}

.financial-health-scale__overflow-icon {
  width: 0.9rem;
  height: 0.9rem;
  stroke-width: 2.4;
}

.financial-health-scale__labels {
  position: relative;
  height: 2.55rem;
  margin: 0.35rem 0.55rem 0;
  color: var(--text-muted);
  font-size: 0.6875rem;
  line-height: 1.1;
}

.financial-health-scale__threshold,
.financial-health-scale__break-even {
  position: absolute;
  white-space: nowrap;
  transform: translateX(-50%);
}

.financial-health-scale__threshold {
  top: 0;
}

.financial-health-scale__threshold--200 {
  top: 0;
  right: 0;
  transform: none;
}

.financial-health-scale__break-even {
  top: 1rem;
  color: var(--text);
  font-weight: 600;
}

.financial-health-details {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: 0.15rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.financial-health-detail {
  min-width: 0;
  padding-right: 1.25rem;
}

.financial-health-detail + .financial-health-detail {
  padding-right: 0;
  padding-left: 1.25rem;
  border-left: 1px solid var(--border);
}

.financial-health-detail__label {
  color: var(--text-muted);
  font-size: 0.75rem;
}

.financial-health-detail__value {
  margin-top: 0.25rem;
  color: var(--text);
  font-size: clamp(1rem, 2.2vw, 1.2rem);
  font-weight: 720;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

/* Footer row of the frozen card: the normalized-amounts note keeps its
   place on the left, with the read-only Savings Contributions scenario on
   the right. It wraps beneath the note on narrow cards. */
.financial-health-details__footer {
  grid-column: 1 / -1;
  container-type: inline-size;
  container-name: financial-health-footer;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem 0.75rem;
  margin-top: 0.65rem;
}

.financial-health-details__note {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.6875rem;
  line-height: 1.35;
}

/* The shared compact toggle-switch, placed on the right of the footer row.
   Its label carries slightly more weight than the muted note beside it while
   staying well below the financial values above. */
.financial-health-scenario {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
}

.financial-health-scenario .boolean-field__row {
  min-height: 2rem;
}

.financial-health-scenario .toggle-switch__label {
  font-size: 0.75rem;
}

/* The Financial Health card is narrow in the dashboard's side column, and
   narrower still on a phone: below the width where the note and the switch
   fit side by side, the switch takes the whole line as an ordinary settings
   row -- label on the left, switch on the right -- instead of crowding. */
@container financial-health-footer (max-width: 24rem) {
  .financial-health-scenario,
  .financial-health-scenario .boolean-field,
  .financial-health-scenario .boolean-field__row,
  .financial-health-scenario .toggle-switch {
    width: 100%;
  }

  .financial-health-scenario .toggle-switch {
    justify-content: space-between;
  }

  .financial-health-scenario .toggle-switch__track {
    order: 2;
  }
}

@media (max-width: 480px) {
  .financial-health-card {
    padding: 0.9rem 0.95rem 0.95rem;
  }

  /* Comfortable touch target once the control wraps under the note. */
  .financial-health-scenario .boolean-field__row {
    min-height: 2.5rem;
  }

  .financial-health-header {
    gap: 0.65rem;
  }

  .financial-health-title {
    font-size: var(--fs-base);
  }

  /* Matches .financial-health-title's shrink at the same breakpoint. */
  .spendable-current-label {
    font-size: var(--fs-base);
  }

  .financial-health-primary-value {
    margin-top: 0.3rem;
    font-size: clamp(1.1rem, 5.5vw, 1.3rem);
  }

  .financial-health-primary-label {
    font-size: 0.875rem;
  }

  .financial-health-status {
    padding: 0.26rem 0.7rem 0.26rem 0.58rem;
    font-size: 0.8125rem;
  }

  .financial-health-scale {
    margin-top: 0.8rem;
  }

  .financial-health-scale__marker-label {
    font-size: 0.75rem;
  }

  .financial-health-scale__track,
  .financial-health-scale__labels {
    margin-inline: 0.45rem;
  }

  .financial-health-scale__labels {
    height: 2.3rem;
  }

  .financial-health-scale__threshold--70,
  .financial-health-scale__threshold--90,
  .financial-health-scale__threshold--120,
  .financial-health-scale__threshold--150 {
    display: none;
  }

  .financial-health-scale__break-even {
    top: 0.85rem;
    font-size: 0.625rem;
  }

  .financial-health-scale__threshold--200 {
    font-size: 0.625rem;
  }

  .financial-health-details {
    margin-top: 0.1rem;
    padding-top: 0.7rem;
  }

  .financial-health-detail {
    padding-right: 0.75rem;
  }

  .financial-health-detail + .financial-health-detail {
    padding-right: 0;
    padding-left: 0.75rem;
  }

  .financial-health-detail__label {
    font-size: 0.6875rem;
  }

  .financial-health-detail__value {
    font-size: 1rem;
  }
}

.dashboard-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.85rem;
}

.dashboard-panel-link {
  color: var(--action-primary);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

.monthcast-calendar-card {
  padding: 1.25rem;
  overflow: visible;
}

.monthcast-calendar-card .dashboard-panel-header {
  align-items: center;
}

.monthcast-calendar-title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.6rem;
}

.monthcast-calendar-month {
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 600;
}

.monthcast-calendar-grid {
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: visible;
}

.monthcast-calendar-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.monthcast-calendar-weekday {
  padding: 0.55rem 0.45rem;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
  color: var(--text-muted);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.045em;
  text-align: center;
  text-transform: uppercase;
}

.monthcast-calendar-day {
  position: relative;
  min-width: 0;
  min-height: 8.75rem;
  padding: 0.45rem;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.monthcast-calendar-day--outside {
  background: color-mix(in srgb, var(--surface-alt) 88%, var(--app-bg));
}

.monthcast-calendar-day[data-temporal-state="past"] {
  background: color-mix(in srgb, var(--text-muted) 6%, var(--surface));
  box-shadow: inset 0.18rem 0 0 color-mix(in srgb, var(--text-muted) 32%, var(--border));
}

.monthcast-calendar-day[data-temporal-state="past"] .monthcast-calendar-day__number {
  opacity: 0.7;
}

.monthcast-calendar-day[data-temporal-state="today"] {
  background: color-mix(in srgb, var(--brand-orange) 4%, var(--surface));
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--brand-orange) 58%, transparent);
  z-index: 1;
}

.monthcast-calendar-day__number {
  display: inline-flex;
  width: 1.5rem;
  height: 1.5rem;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
}

.monthcast-calendar-day__heading {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem;
}

.monthcast-calendar-today-label {
  color: var(--accent);
  font-size: 0.5625rem;
  font-weight: 800;
  letter-spacing: 0.035em;
  line-height: 1;
  text-transform: uppercase;
}

.monthcast-calendar-today-label--mobile {
  display: none;
}

.monthcast-calendar-day[data-temporal-state="today"] .monthcast-calendar-day__number {
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
}

.monthcast-calendar-day__button,
.monthcast-calendar-agenda {
  display: none;
}

.monthcast-calendar-day__occurrences {
  display: grid;
  gap: 0.35rem;
  margin-top: 0.25rem;
}

.monthcast-calendar-occurrence {
  min-width: 0;
  padding: 0.35rem 0.4rem;
  border-left: 2px solid var(--text-muted);
  border-radius: 0.2rem;
  background: var(--surface-alt);
  color: var(--text);
}

.monthcast-calendar-occurrence[data-direction="inflow"] {
  border-left-color: var(--flow-inflow);
}

.monthcast-calendar-occurrence[data-direction="outflow"] {
  border-left-color: var(--flow-outflow);
}

.monthcast-calendar-occurrence[data-direction="reserve"] {
  border-left-color: var(--warning-fill);
}

.monthcast-calendar-occurrence__main {
  display: flex;
  min-width: 0;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.35rem;
}

.monthcast-calendar-occurrence__name {
  min-width: 0;
  overflow: hidden;
  font-size: 0.6875rem;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.monthcast-calendar-occurrence__amount {
  flex: 0 0 auto;
  color: var(--text);
  font-size: 0.6875rem;
  font-weight: 700;
  white-space: nowrap;
}

.monthcast-calendar-occurrence__meta {
  display: flex;
  min-width: 0;
  flex-wrap: wrap;
  gap: 0.2rem 0.45rem;
  margin-top: 0.12rem;
  color: var(--text-muted);
  font-size: 0.625rem;
}

.monthcast-calendar-status {
  padding: 0.05rem 0.3rem;
  font-size: 0.5625rem;
  line-height: 1.25;
}

.monthcast-calendar-reminder {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}

/* The glyph carries the brand accent so it reads as active and
   discoverable, while the chip stays neutral -- that keeps it secondary to
   the occurrence name/status/amount. `--accent` is the theme-tuned orange
   (deep on light, bright on dark), so contrast follows both themes on its
   own; hover/focus deepens it to `--accent-hover`. */
.monthcast-calendar-reminder__trigger {
  display: inline-flex;
  width: 1.5rem;
  height: 1.5rem;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  color: var(--text-muted);
  cursor: pointer;
  transition: color 120ms ease, background-color 120ms ease, border-color 120ms ease;
}

.monthcast-calendar-reminder__trigger:hover,
.monthcast-calendar-reminder__trigger:focus-visible {
  border-color: color-mix(in srgb, var(--text-muted) 40%, var(--border));
  background: var(--surface-hover);
  color: var(--text);
}

.monthcast-calendar-reminder__trigger:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

.monthcast-calendar-reminder__icon {
  width: 1rem;
  height: 1rem;
}

.monthcast-calendar-reminder__tooltip {
  position: fixed;
  z-index: 40;
  display: grid;
  width: max-content;
  max-width: min(16rem, calc(100vw - 2rem));
  gap: 0.15rem;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  box-shadow: var(--shadow-menu);
  color: var(--text);
  font-size: 0.75rem;
  line-height: 1.35;
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.15rem);
  transition: opacity 120ms ease, transform 120ms ease;
}

.monthcast-calendar-reminder__tooltip > span {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* Desktop hover and keyboard focus both reveal it with no click. Touch
   taps focus the trigger, which satisfies :focus-within. */
.monthcast-calendar-reminder:hover .monthcast-calendar-reminder__tooltip,
.monthcast-calendar-reminder:focus-within .monthcast-calendar-reminder__tooltip {
  opacity: 1;
  transform: translateY(0);
}

.monthcast-calendar-more {
  margin-top: 0.35rem;
  padding: 0.15rem 0.25rem;
  border: 0;
  background: transparent;
  color: var(--action-primary);
  cursor: pointer;
  font: inherit;
  font-size: 0.6875rem;
  font-weight: 700;
}

.monthcast-calendar-more:hover,
.monthcast-calendar-more:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

.monthcast-calendar-popover {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 40;
  width: min(20rem, calc(100vw - 1.5rem));
  max-height: calc(100vh - 1.5rem);
  overflow-y: auto;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow-menu);
}

.monthcast-calendar-popover__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.65rem;
  font-size: 0.8rem;
}

.monthcast-calendar-popover__close {
  display: inline-flex;
  width: 1.75rem;
  height: 1.75rem;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 1.25rem;
  line-height: 1;
}

.monthcast-calendar-popover__close:hover,
.monthcast-calendar-popover__close:focus-visible {
  background: var(--surface-hover);
  color: var(--text);
}

.monthcast-calendar-popover__items,
.monthcast-calendar-agenda__items {
  display: grid;
  gap: 0.45rem;
}

.monthcast-calendar-occurrence--popover,
.monthcast-calendar-occurrence--agenda {
  padding: 0.5rem 0.55rem;
}

/* NEW-SMOKE-01: the full name wraps here; `overflow-wrap: anywhere` (the
   SMOKE-009 convention, with the base rule's `min-width: 0`) also breaks a
   long unbroken token, so it can never paint over the amount beside it. */
.monthcast-calendar-occurrence--popover .monthcast-calendar-occurrence__name,
.monthcast-calendar-occurrence--agenda .monthcast-calendar-occurrence__name {
  overflow: visible;
  font-size: 0.75rem;
  overflow-wrap: anywhere;
  text-overflow: clip;
  white-space: normal;
}

.monthcast-calendar-empty {
  margin: 0.85rem 0 0;
  color: var(--text-muted);
  font-size: 0.8rem;
}

@media (max-width: 760px) {
  .monthcast-calendar-card {
    padding: 1rem;
  }

  .monthcast-calendar-card .dashboard-panel-header {
    align-items: flex-start;
    margin-bottom: 0.7rem;
  }

  .monthcast-calendar-title-row {
    display: block;
  }

  .monthcast-calendar-month {
    display: block;
    margin-top: 0.2rem;
  }

  .monthcast-calendar-weekday {
    padding: 0.4rem 0.1rem;
    font-size: 0.6rem;
  }

  .monthcast-calendar-day {
    min-height: 3rem;
    padding: 0.18rem;
  }

  .monthcast-calendar-day__heading,
  .monthcast-calendar-day__occurrences,
  .monthcast-calendar-more,
  .monthcast-calendar-popover,
  .monthcast-calendar-empty {
    display: none;
  }

  .monthcast-calendar-day__button {
    position: relative;
    display: flex;
    width: 100%;
    min-height: 2.55rem;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.08rem;
    padding: 0.25rem 0.1rem;
    border: 0;
    border-radius: 0.3rem;
    background: transparent;
    color: var(--text);
    cursor: pointer;
    font: inherit;
    font-size: 0.75rem;
    font-weight: 650;
  }

  .monthcast-calendar-day__button[aria-pressed="true"] {
    background: color-mix(in srgb, var(--brand-orange) 13%, var(--surface));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand-orange) 55%, transparent);
  }

  .monthcast-calendar-day[data-temporal-state="past"] .monthcast-calendar-day__button {
    color: var(--text-muted);
  }

  .monthcast-calendar-day[data-temporal-state="today"] .monthcast-calendar-day__button {
    color: var(--accent);
  }

  .monthcast-calendar-today-label--mobile {
    display: inline;
    font-size: 0.5rem;
  }

  .monthcast-calendar-day__count {
    position: absolute;
    top: 0.18rem;
    right: 0.18rem;
    display: inline-flex;
    min-width: 0.9rem;
    height: 0.9rem;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--text-secondary);
    color: var(--surface);
    font-size: 0.55rem;
    font-weight: 800;
  }

  .monthcast-calendar-agenda {
    display: block;
    min-height: 4.5rem;
    margin-top: 0.85rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--border);
  }

  .monthcast-calendar-agenda__title {
    margin: 0 0 0.55rem;
    color: var(--text);
    font-size: 0.8rem;
    font-weight: 700;
  }

  .monthcast-calendar-agenda__day {
    scroll-margin-top: 5rem;
  }

  .monthcast-calendar-occurrence--agenda .monthcast-calendar-occurrence__amount {
    font-size: 0.75rem;
  }

  /* Comfortable touch target in the selected-day agenda. */
  .monthcast-calendar-occurrence--agenda .monthcast-calendar-reminder__trigger {
    width: 2rem;
    height: 2rem;
  }

  .monthcast-calendar-occurrence--agenda .monthcast-calendar-reminder__icon {
    width: 1.125rem;
    height: 1.125rem;
  }

  /* Touch reveals it as a bottom sheet rather than a hover bubble; the JS
     positioner leaves these coordinates alone below this breakpoint. */
  .monthcast-calendar-reminder__tooltip {
    right: 1rem;
    bottom: 1rem;
    left: 1rem;
    width: auto;
    max-width: none;
    font-size: 0.8125rem;
  }
}

/* Dashboard top section. Before the first MonthCast it stays a normal
   stacked flow; afterwards Leftover + Forecast sit beside Financial Health. */
.dashboard-top-grid {
  margin-bottom: 1.5rem;
}

/* Cards keep their natural heights so Financial Health is never stretched. */
.dashboard-top-grid--split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
}

/* Side by side only once both keep a comfortable width: the 16rem sidebar
   plus main padding leave ~60rem of content at 1280px. Financial Health
   never drops below 22rem. */
@media (min-width: 1280px) {
  .dashboard-top-grid--split {
    grid-template-columns: minmax(0, 1.6fr) minmax(22rem, 1fr);
  }
}

/* Financial Health and Quick Actions stack as separate cards, each at its
   natural height; on narrow screens they follow Leftover + Forecast. */
.dashboard-top-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

.dashboard-quick-actions {
  padding: 1rem 1.25rem 1.1rem;
}

.dashboard-quick-actions__list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

/* Desktop two-column layout: both columns share one bottom edge. The shorter
   side absorbs the difference — Quick Actions grows on the right, the
   Forecast plot grows on the left. Financial Health keeps its natural
   height. Stacked layouts below 1280px keep natural card heights. */
@media (min-width: 1280px) {
  .dashboard-top-grid--split {
    align-items: stretch;
  }

  .dashboard-top-grid--split .dashboard-quick-actions {
    flex: 1 1 auto;
  }

  .dashboard-top-grid--split .spendable-forecast-chart-wrap {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
  }

  .dashboard-top-grid--split .spendable-forecast-chart {
    flex: 1 1 auto;
  }
}

/* One surface for Current Leftover and its Forecast. */
.spendable-hero-stack {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 1.25rem 1.35rem 1rem;
}

.spendable-current-card {
  min-width: 0;
}

/* E12-04: matches the peer Dashboard card-title hierarchy (.dashboard-
   section-title / .financial-health-title) -- same size, weight, and
   color -- rather than reading as a small uppercase eyebrow above a
   different, unrelated title. The month context stays in the heading
   text itself ("Leftover — {{ month_label }}"). */
.spendable-current-label {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}

/* E12-04: the strongest primary number on the Dashboard -- still the
   largest/heaviest, but dialed back from an oversized KPI-marketing scale
   to a calmer, information-dense one -- and kept comfortably above
   .financial-health-primary-value (Financial Health) so the two never
   read as near-equal peers. */
.spendable-current-amount {
  margin-top: 0.45rem;
  color: var(--text);
  font-size: clamp(1.6rem, 3vw, 2rem);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-figure);
  line-height: var(--lh-tight);
  overflow-wrap: anywhere;
}

.spendable-current-card[data-sign="positive"] .spendable-current-amount {
  color: var(--success);
}

.spendable-current-card[data-sign="negative"] .spendable-current-amount {
  color: var(--danger);
}

.spendable-current-note {
  margin-top: 0.45rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

/* Forecast continues the Leftover story on the same surface: a hairline
   divider, not a nested card. */
.spendable-forecast-timeline {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.spendable-forecast-timeline-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
}

.spendable-forecast-timeline-title {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.spendable-forecast-timeline-helper {
  margin: 0.1rem 0 0;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.spendable-forecast-range {
  display: inline-flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.spendable-forecast-range-btn {
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0.4rem 0.75rem;
  border-radius: 0.55rem;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
}

.spendable-forecast-range-btn[aria-pressed="true"] {
  border-color: var(--selected-line);
  background: var(--selected-tint);
  color: var(--selected-ink);
  font-weight: var(--fw-semibold);
}

/* Readout for the inspected month: plain text on the card surface. Its line
   is reserved so showing/hiding a month never shifts the chart. */
.spendable-forecast-selected {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 0.75rem;
  min-height: 1.65rem;
  margin-top: 0.75rem;
}

.spendable-forecast-selected[data-state="idle"] > * {
  visibility: hidden;
}

.spendable-forecast-selected-meta,
.spendable-forecast-selected-value {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
}

.spendable-forecast-selected-month {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.spendable-forecast-sign-label {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.spendable-forecast-selected-caption {
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  color: var(--text-muted);
}

/* E12-04: tertiary in the Dashboard numeric hierarchy -- noticeably
   smaller/lighter than .financial-health-primary-value's floor (1.3rem/
   620) at every emphasis level, while staying immediately readable next
   to its caption/month. */
.spendable-forecast-selected-amount {
  font-size: 1.05rem;
  font-weight: 650;
  color: var(--text);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.spendable-forecast-selected[data-sign="positive"] .spendable-forecast-selected-amount,
.spendable-forecast-selected[data-sign="positive"] .spendable-forecast-sign-label {
  color: var(--success);
}

.spendable-forecast-selected[data-sign="negative"] .spendable-forecast-selected-amount,
.spendable-forecast-selected[data-sign="negative"] .spendable-forecast-sign-label {
  color: var(--danger);
}

.spendable-forecast-selected[data-state="default"] .spendable-forecast-selected-amount,
.spendable-forecast-selected[data-state="default"] .spendable-forecast-sign-label {
  color: var(--text-muted);
}

.spendable-forecast-selected-amount[data-emphasis="2"] {
  font-size: 1.1rem;
}

.spendable-forecast-selected-amount[data-emphasis="3"] {
  font-size: 1.15rem;
  font-weight: 700;
}

.spendable-forecast-chart-wrap {
  width: 100%;
  min-width: 0;
  margin-top: 0.5rem;
  border-radius: 0.5rem;
  overflow: hidden;
  touch-action: none;
  cursor: crosshair;
}

.spendable-forecast-chart-wrap:focus-visible {
  outline: 2px solid var(--action-primary);
  outline-offset: 2px;
}

.spendable-forecast-chart {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 640 / 240;
  user-select: none;
  -webkit-user-select: none;
}

.spendable-forecast-chart .forecast-grid-line {
  stroke: var(--border);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

/* $0 is break-even: solid and a step stronger than the grid. */
.spendable-forecast-chart .forecast-zero-line {
  stroke: var(--text-muted);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

.spendable-forecast-chart .forecast-axis-label {
  fill: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.spendable-forecast-chart .forecast-axis-label--zero {
  fill: var(--text);
  font-weight: var(--fw-semibold);
}

.spendable-forecast-chart .forecast-guide {
  stroke: var(--text-muted);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  opacity: 0.6;
  vector-effect: non-scaling-stroke;
}

.spendable-forecast-chart .forecast-area-positive,
.spendable-forecast-chart .forecast-area-negative,
.spendable-forecast-chart .forecast-area-neutral,
.spendable-forecast-chart .forecast-line-positive,
.spendable-forecast-chart .forecast-line-negative,
.spendable-forecast-chart .forecast-line-neutral,
.spendable-forecast-chart .forecast-zero-line,
.spendable-forecast-chart .forecast-grid-line,
.spendable-forecast-chart .forecast-axis-label,
.spendable-forecast-chart .forecast-guide {
  pointer-events: none;
}

.spendable-forecast-chart .forecast-area-positive {
  fill: var(--success);
  opacity: 0.14;
}

.spendable-forecast-chart .forecast-area-negative {
  fill: var(--danger);
  opacity: 0.16;
}

.spendable-forecast-chart .forecast-area-neutral {
  fill: none;
}

.spendable-forecast-chart .forecast-line-positive {
  fill: none;
  stroke: var(--success);
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.spendable-forecast-chart .forecast-line-negative {
  fill: none;
  stroke: var(--danger);
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.spendable-forecast-chart .forecast-line-neutral {
  fill: none;
  stroke: var(--text-muted);
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
  vector-effect: non-scaling-stroke;
}

.spendable-forecast-chart .forecast-marker {
  stroke: var(--surface);
  stroke-width: 2;
  pointer-events: none;
}

.spendable-forecast-chart .forecast-hit {
  fill: transparent;
  cursor: crosshair;
  touch-action: none;
}

/* Desktop: compact range buttons (shared with other segmented controls). */
@media (min-width: 901px) {
  .spendable-forecast-range-btn {
    min-height: 2.2rem;
    min-width: 2.4rem;
    padding: 0.25rem 0.6rem;
  }
}

/* Mobile/tablet: a taller plot than desktop so axis labels and the line
   stay legible (app.js draws to whatever box this sets). E12-05-030: on a
   phone the plot is shorter than on a tablet, so Financial Health below it
   comes into the first screen; the forecast itself -- series, range, the
   selected month -- is unchanged. */
@media (max-width: 900px) {
  .spendable-hero-stack {
    padding: 1rem 1rem 0.85rem;
  }

  .spendable-forecast-chart {
    aspect-ratio: 640 / 360;
  }
}

@media (max-width: 640px) {
  .spendable-hero-stack {
    padding: 0.85rem 0.9rem 0.7rem;
  }

  .spendable-forecast-timeline {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
  }

  .spendable-forecast-chart {
    aspect-ratio: 640 / 240;
  }

}

@media (prefers-reduced-motion: reduce) {
  .spendable-forecast-chart .forecast-marker {
    transition: none;
  }
}

@media (max-width: 1180px) {
  .investment-kpi-grid,
  .investment-table-grid-primary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .more-nav-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .more-nav-group:first-child {
    grid-column: 1 / -1;
  }
}

@media (max-width: 760px) {
  .dashboard-onboarding-desktop {
    display: none;
  }

  .dashboard-onboarding-mobile {
    display: block;
  }

  .investment-portfolio-header,
  .investment-empty-state {
    align-items: flex-start;
    flex-direction: column;
  }

  .investment-last-updated {
    text-align: right;
  }

  .investment-portfolio-actions {
    width: 100%;
    justify-content: space-between;
  }

  .investment-kpi-grid,
  .investment-table-grid-primary {
    grid-template-columns: minmax(0, 1fr);
  }

  .investment-owner-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .investment-owner-metrics {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .investment-table {
    font-size: var(--fs-2xs);
  }

  .more-nav-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .more-nav-group:first-child {
    grid-column: auto;
  }

  .page-header {
    align-items: stretch;
    flex-direction: column;
    margin-bottom: 1.25rem;
  }

  .page-header > .flex {
    justify-content: flex-start;
  }

  .table-controls {
    align-items: stretch;
    padding: 0.85rem;
  }

  .table-controls .field-input {
    max-width: none !important;
  }

  .summary-grid {
    gap: 0.75rem;
  }

  .summary-card {
    min-height: 5.75rem;
  }
}

/* Approved CountAhead artwork. Never stretch; never white-box. */
.brand-mark img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
}

.brand-mark img.brand-mark__dark {
  display: none;
}

[data-theme="dark"] .brand-mark img.brand-mark__light {
  display: none;
}

[data-theme="dark"] .brand-mark img.brand-mark__dark {
  display: block;
}

.brand-mark--shell {
  max-width: 100%;
  padding-block: 0.5rem;
}

.brand-mark--shell img {
  max-height: 2.6rem;
  width: auto;
  object-fit: contain;
}

.brand-mark--compact {
  display: flex;
  justify-content: center;
  max-width: 10rem;
  margin-inline: auto;
}

.brand-mark--compact img {
  max-height: 1.85rem;
}

.brand-mark--auth {
  display: flex;
  justify-content: center;
  max-width: 17.5rem;
  margin-inline: auto;
  padding-block: 0.5rem;
}

.brand-mark--auth img {
  max-height: 3.75rem;
}

/* E11-T011 Checkpoint 1: authenticated application shell. */
.app-shell,
.app-content {
  min-width: 0;
  background: var(--app-bg);
}

.app-desktop-header {
  position: sticky;
  top: 0;
  z-index: 35;
  min-height: 4rem;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  overflow: visible;
  padding: 0.55rem 2rem;
  border-bottom: 1px solid var(--sidebar-border);
  background: color-mix(in srgb, var(--sidebar-bg) 94%, transparent);
  backdrop-filter: blur(10px);
}

.app-desktop-header__cluster {
  display: flex;
  align-items: center;
  min-width: 0;
  flex: 1 1 0;
}

.app-desktop-header__cluster--start {
  justify-content: flex-start;
}

.app-desktop-header__cluster--center {
  justify-content: center;
}

.app-desktop-header__cluster--end {
  justify-content: flex-end;
}

.app-demo-status-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  padding: 0.35rem 1rem;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
}

@media (min-width: 768px) {
  .app-demo-status-bar {
    display: none;
  }
}

.app-demo-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 1.5rem;
  padding: 0.2rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--data-blue) 32%, var(--border));
  border-radius: 999px;
  background: color-mix(in srgb, var(--data-blue) 12%, var(--surface));
  color: var(--data-blue);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  line-height: 1;
  text-transform: uppercase;
}

.app-sidebar > * {
  position: relative;
  z-index: 1;
}

.app-sidebar::before {
  position: absolute;
  inset: 0 auto 0 0;
  z-index: 0;
  width: 4.75rem;
  border-right: 1px solid transparent;
  background: var(--sidebar-bg);
  box-shadow: none;
  opacity: 0;
  pointer-events: none;
  transition: width 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease,
    opacity 0.16s ease;
  content: "";
}

.app-sidebar__header,
.app-sidebar__scroll,
.app-sidebar__footer {
  width: 100%;
  transition: width 0.16s ease, padding 0.16s ease;
}

.app-sidebar__header {
  flex: 0 0 auto;
  min-height: 5.4rem;
  padding: 0.85rem 1rem 0.5rem;
}

.app-sidebar__brand {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  overflow: visible;
  border-radius: var(--radius-md);
}

.app-sidebar__brand-full {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow: visible;
}

.app-sidebar__brand-full .brand-mark--shell {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  width: auto;
  max-width: 100%;
  min-width: 0;
  padding-block: 0.1rem;
}

.app-sidebar__brand-full .brand-mark--shell img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 2.35rem;
  object-fit: contain;
  object-position: left center;
}

.app-sidebar__brand-full .brand-mark--shell img.brand-mark__light {
  display: block;
}

.app-sidebar__brand-full .brand-mark--shell img.brand-mark__dark {
  display: none;
}

[data-theme="dark"] .app-sidebar__brand-full .brand-mark--shell img.brand-mark__light {
  display: none;
}

[data-theme="dark"] .app-sidebar__brand-full .brand-mark--shell img.brand-mark__dark {
  display: block;
}

.app-sidebar__brand-icon {
  display: none;
  width: 2.25rem;
  height: 2.25rem;
}

.app-sidebar__brand-icon img {
  display: block;
  width: 100%;
  height: 100%;
}

.app-sidebar__brand-icon .app-sidebar__brand-icon-dark {
  display: none;
}

[data-theme="dark"] .app-sidebar__brand-icon-light {
  display: none;
}

[data-theme="dark"] .app-sidebar__brand-icon-dark {
  display: block;
}

[data-admin-shell] .app-sidebar__subtitle {
  display: block;
  margin-top: 0.2rem;
  padding-left: 0.1rem;
  color: var(--sidebar-text-muted, var(--text-muted));
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.app-sidebar__scroll {
  flex: 1 1 auto;
  min-height: 0;
  padding: 0.25rem 0.75rem 1rem;
  overflow-x: visible;
  overflow-y: auto;
  scrollbar-color: color-mix(in srgb, var(--sidebar-text) 46%, transparent) transparent;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

.app-sidebar__scroll::-webkit-scrollbar {
  width: 0.35rem;
}

.app-sidebar__scroll::-webkit-scrollbar-track {
  background: transparent;
}

.app-sidebar__scroll::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: color-mix(in srgb, var(--sidebar-text) 42%, transparent);
}

.sidebar-utilities {
  display: grid;
  gap: 0.7rem;
  margin-bottom: 1.15rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--sidebar-border);
}

.sidebar-utility__label {
  display: block;
  margin: 0 0 0.3rem 0.1rem;
  color: var(--sidebar-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
}

.sidebar-control-wrap {
  position: relative;
  display: block;
}

.sidebar-control-icon {
  position: absolute;
  top: 50%;
  left: 0.7rem;
  z-index: 1;
  color: var(--sidebar-text);
  pointer-events: none;
  transform: translateY(-50%);
}

.sidebar-control {
  width: 100%;
  min-height: 2.45rem;
  padding: 0.45rem 2rem 0.45rem 2.25rem;
  border: 1px solid var(--sidebar-border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
}

.sidebar-control::placeholder {
  color: var(--text-muted);
}

.sidebar-control:focus {
  border-color: var(--focus);
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 18%, transparent);
}

.sidebar-rail-action {
  position: relative;
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-inline: auto;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--sidebar-text);
}

.sidebar-rail-action:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-text-active);
}

.sidebar-rail-badge {
  position: absolute;
  right: 0.15rem;
  bottom: 0.1rem;
  display: grid;
  width: 1rem;
  height: 1rem;
  place-items: center;
  border: 2px solid var(--sidebar-bg);
  border-radius: 999px;
  background: var(--brand-orange);
  color: #111318;
  font-size: 0.5rem;
  font-weight: 800;
}

.sidebar-nav {
  display: grid;
  gap: 0.45rem;
}

.sidebar-nav__links {
  display: grid;
  gap: 0.125rem;
}

.sidebar-link--nested {
  padding-left: 1.15rem;
  position: relative;
}

/* E7-SMOKE-UX-02: a restrained tree-style parent/child guide -- a single
   neutral vertical trunk down the children block plus a short horizontal
   branch per child -- so the hierarchy reads at a glance beyond mere
   indentation. Reuses the existing neutral border token; deliberately not
   the brand/warning colors. Suppressed in true icon-only collapsed mode
   (below), where it would just be clutter over a stack of icon squares. */
.sidebar-nav-group__children::before {
  content: "";
  position: absolute;
  top: 0.1rem;
  bottom: 0.7rem;
  left: 0.65rem;
  width: 1px;
  background: var(--sidebar-border);
}

.sidebar-link--nested::before {
  content: "";
  position: absolute;
  left: -0.5rem;
  top: 50%;
  width: 0.5rem;
  height: 1px;
  background: var(--sidebar-border);
}

/* Per-group expand/collapse (nav_group macro) -- a DIFFERENT behavior from
   whole-sidebar collapse (data-sidebar-toggle). The <summary> reuses the
   exact .sidebar-link visual treatment (including collapsed-state/tooltip
   CSS below) so it composes with whole-sidebar collapse for free; only the
   chevron and children-visibility are group-specific. */
.sidebar-nav-group > summary {
  list-style: none;
  cursor: pointer;
}

.sidebar-nav-group > summary::-webkit-details-marker {
  display: none;
}

.sidebar-nav-group__chevron {
  margin-left: auto;
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
  opacity: 0.6;
  transition: transform 0.15s ease;
}

.sidebar-nav-group[open] > summary .sidebar-nav-group__chevron {
  transform: rotate(180deg);
}

.sidebar-nav-group__children {
  display: grid;
  gap: 0.125rem;
  margin: 0.125rem 0 0.35rem;
  position: relative;
  padding-left: 0.65rem;
}

.sidebar-link__tooltip {
  display: none;
}

.app-sidebar__footer {
  position: relative;
  flex: 0 0 auto;
  padding: 0.7rem 0.75rem 0.85rem;
  border-top: 1px solid var(--sidebar-border);
  background: var(--sidebar-bg);
}

.account-menu {
  position: relative;
}

.account-menu--desktop {
  width: min(15rem, 38vw);
}

.account-menu > summary::-webkit-details-marker {
  display: none;
}

.account-menu > summary::marker {
  content: "";
}

.account-menu__launcher {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  min-height: 3rem;
  padding: 0.35rem 0.45rem;
  border-radius: var(--radius-md);
  color: var(--sidebar-text-active);
  cursor: pointer;
  list-style: none;
}

.account-menu__launcher:hover,
.account-menu[open] > .account-menu__launcher {
  background: var(--sidebar-hover-bg);
}

.account-menu__launcher--desktop {
  min-height: 2.85rem;
  padding: 0.3rem 0.5rem;
}

.account-avatar {
  display: inline-grid;
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  place-items: center;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 800;
}

.account-avatar--button {
  border: 0;
  cursor: pointer;
}

.account-menu__identity {
  min-width: 0;
  flex: 1 1 auto;
}

.account-menu__name,
.account-menu__email,
.account-menu__role {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-menu__name {
  color: var(--sidebar-text-active);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.account-menu__email {
  margin-top: 0.1rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
}

.account-menu__role {
  margin-top: 0.1rem;
  color: var(--sidebar-text);
  font-size: var(--fs-2xs);
}

/* E12-06 F037: a Read-Only member sees their access level in the menu. */
.account-menu__access {
  display: inline-block;
  margin-top: 0.3rem;
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-secondary);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
}

.account-menu__chevron {
  width: 0.95rem;
  height: 0.95rem;
  color: var(--sidebar-text);
  transition: transform 0.15s ease;
}

.account-menu[open] .account-menu__chevron {
  transform: rotate(180deg);
}

.account-menu__panel {
  position: absolute;
  bottom: calc(100% + 0.55rem);
  left: 0;
  z-index: 50;
  width: 14.5rem;
  padding: 0.35rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow-menu);
}

.account-menu__panel--desktop {
  top: calc(100% + 0.5rem);
  right: 0;
  bottom: auto;
  left: auto;
}

.account-menu--mobile {
  position: relative;
  z-index: 40;
  flex: 0 0 auto;
}

.account-menu__launcher--mobile {
  width: 2.5rem;
  min-width: 2.5rem;
  height: 2.5rem;
  min-height: 2.5rem;
  padding: 0;
  justify-content: center;
}

.account-menu__panel--mobile {
  top: calc(100% + 0.5rem);
  right: 0;
  bottom: auto;
  left: auto;
  z-index: 60;
  width: min(16.5rem, calc(100vw - 1.5rem));
}

.account-menu__heading {
  margin: -0.35rem -0.35rem 0.3rem;
  padding: 0.7rem 0.75rem;
  border-bottom: 1px solid var(--border);
}

.account-menu__heading .account-menu__name {
  color: var(--text);
}

.account-menu__heading .account-menu__role {
  color: var(--text-muted);
}

.account-menu__group + .account-menu__group {
  margin-top: 0.3rem;
  padding-top: 0.3rem;
  border-top: 1px solid var(--border);
}

.account-menu__group-label {
  display: block;
  padding: 0.4rem 0.55rem 0.2rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
}

.account-menu__item {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  min-height: 2.5rem;
  padding: 0.45rem 0.55rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-size: var(--fs-sm);
  text-align: left;
  text-decoration: none;
}

.account-menu__item:hover,
.account-menu__item:focus-visible {
  background: var(--surface-hover);
}

.account-menu__item small {
  display: block;
  margin-top: 0.1rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
}

/* E12-05-031: the Appearance row and its quick theme choices (Light / Dark /
   System, the current one marked by a check -- never colour alone -- each at
   least 2.5rem tall). On a desktop pointer the choices are a compact side
   submenu opening LEFT of the account menu (toward the page); on touch or
   narrow layouts they open inline under the row, so nothing can overflow. */
.account-menu__appearance {
  position: relative;
}

.account-menu__appearance-toggle > span {
  flex: 1 1 auto;
}

.account-menu__appearance-chevron {
  width: 1rem;
  height: 1rem;
  color: var(--text-muted);
  transition: transform 0.15s ease;
}

/* Inline disclosure: the left chevron turns to point down when open. */
.account-menu__appearance-toggle[aria-expanded="true"] .account-menu__appearance-chevron {
  transform: rotate(-90deg);
}

.account-menu__appearance-panel {
  margin: 0.1rem 0 0.35rem;
  padding-left: 2.2rem;
}

.account-menu__theme-options {
  margin: 0;
  padding: 0;
  border: 0;
}

.account-menu__theme-option {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.5rem;
  padding: 0.35rem 0.55rem;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: var(--fs-sm);
  cursor: pointer;
}

.account-menu__theme-option:hover {
  background: var(--surface-hover);
}

.account-menu__theme-input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.account-menu__theme-check {
  visibility: hidden;
  color: var(--action-primary);
  font-weight: var(--fw-semibold);
}

.account-menu__theme-input:checked ~ .account-menu__theme-check {
  visibility: visible;
}

.account-menu__theme-input:checked ~ .account-menu__theme-label {
  font-weight: var(--fw-semibold);
}

.account-menu__theme-option:has(.account-menu__theme-input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.account-menu__appearance-panel .account-menu__appearance-status {
  min-height: 0;
  margin: 0.15rem 0.55rem 0;
  font-size: var(--fs-2xs);
}

/* The theme change itself is the confirmation: the quick switcher never
   says "Saving…" or "Saved". Only a failed save is shown. */
.account-menu__appearance-panel .account-menu__appearance-status:not([data-state="error"]) {
  display: none;
}

/* Desktop pointer: a floating side submenu in the menu's own language
   (surface, border, radius, menu shadow), level with the Appearance row
   and just left of the account menu. Its transparent right edge bridges
   the small gap back to the row, so moving the pointer across never
   leaves the interaction region. The chevron already points the way. */
@media (hover: hover) and (pointer: fine) {
  .account-menu--desktop .account-menu__appearance-panel {
    position: absolute;
    top: -0.35rem;
    right: calc(100% + 0.8rem);
    z-index: 55;
    min-width: 9.5rem;
    margin: 0;
    padding: 0.35rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-raised);
    box-shadow: var(--shadow-menu);
  }

  .account-menu--desktop .account-menu__appearance-panel::after {
    content: "";
    position: absolute;
    top: 0;
    right: -0.9rem;
    width: 0.9rem;
    height: 100%;
  }

  .account-menu--desktop .account-menu__appearance-toggle[aria-expanded="true"] {
    background: var(--surface-hover);
  }

  .account-menu--desktop .account-menu__appearance-toggle[aria-expanded="true"] .account-menu__appearance-chevron {
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .account-menu__appearance-chevron {
    transition: none;
  }
}

.account-menu__version {
  margin: 0.35rem 0 0;
  padding: 0.45rem 0.55rem 0.15rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  line-height: 1.35;
}

.account-menu__status {
  margin: 0 0 0.2rem;
  padding: 0 0.55rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  line-height: 1.35;
}

.account-menu__form {
  margin: 0;
}

.session-row-state {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.settings-start-fresh-lists {
  display: grid;
  gap: 1rem;
}

@media (min-width: 640px) {
  .settings-start-fresh-lists {
    grid-template-columns: 1fr 1fr;
  }
}

.account-menu__logout {
  margin-top: 0.3rem;
  padding-top: 0.3rem;
  border-top: 1px solid var(--border);
}

.account-menu__item--logout {
  color: var(--danger);
  cursor: pointer;
}

.sidebar-collapse-button {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  min-height: 2.5rem;
  margin-top: 0.4rem;
  padding: 0.45rem 0.55rem;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--sidebar-text);
  font-size: var(--fs-xs);
  cursor: pointer;
}

.sidebar-collapse-button:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-text-active);
}

.sidebar-collapse-icon--expand {
  display: none;
}

html[data-sidebar-collapsed="true"] .app-sidebar {
  width: 4.75rem;
}

html[data-sidebar-collapsed="true"] .app-sidebar__header {
  padding-inline: 0.7rem;
}

html[data-sidebar-collapsed="true"] .app-sidebar__brand {
  justify-content: center;
}

html[data-sidebar-collapsed="true"] .app-sidebar__brand-full,
html[data-sidebar-collapsed="true"] .app-sidebar__subtitle,
html[data-sidebar-collapsed="true"] .sidebar-control-wrap,
html[data-sidebar-collapsed="true"] .sidebar-utility__label,
html[data-sidebar-collapsed="true"] .sidebar-link__label,
html[data-sidebar-collapsed="true"] .nav-section-label,
html[data-sidebar-collapsed="true"] .sidebar-collapse-button__label,
html[data-sidebar-collapsed="true"] .sidebar-collapse-icon--collapse {
  display: none;
}

html[data-sidebar-collapsed="true"] .app-sidebar__brand-icon,
html[data-sidebar-collapsed="true"] .sidebar-collapse-icon--expand {
  display: block;
}

html[data-sidebar-collapsed="true"] .sidebar-rail-action {
  display: flex;
}

html[data-sidebar-collapsed="true"] .app-sidebar__scroll {
  padding-inline: 0.55rem;
}

html[data-sidebar-collapsed="true"] .sidebar-utilities {
  gap: 0.25rem;
  margin-bottom: 0.55rem;
  padding-bottom: 0.55rem;
}

html[data-sidebar-collapsed="true"] .sidebar-nav {
  gap: 0.2rem;
}

html[data-sidebar-collapsed="true"] .sidebar-nav__group + .sidebar-nav__group {
  margin-top: 0.35rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--sidebar-border);
}

html[data-sidebar-collapsed="true"] .sidebar-link {
  justify-content: center;
  width: 2.75rem;
  min-height: 2.75rem;
  margin-inline: auto;
  padding: 0;
}

html[data-sidebar-collapsed="true"] .sidebar-link.active::before {
  left: -0.55rem;
}

/* Icon-only collapsed mode: the open group's children still render (native
   <details>), but as a plain icon stack -- the tree guide from above would
   just be clutter over centered icon squares here. */
html[data-sidebar-collapsed="true"]:not([data-sidebar-temporary-expanded="true"]) .sidebar-nav-group__children::before,
html[data-sidebar-collapsed="true"]:not([data-sidebar-temporary-expanded="true"]) .sidebar-link--nested::before {
  display: none;
}

html[data-sidebar-collapsed="true"]:not([data-sidebar-temporary-expanded="true"]) .sidebar-nav-group__children {
  padding-left: 0;
}

html[data-sidebar-collapsed="true"] .sidebar-link:hover .sidebar-link__tooltip,
html[data-sidebar-collapsed="true"] .sidebar-link:focus-visible .sidebar-link__tooltip {
  position: absolute;
  top: 50%;
  left: calc(100% + 0.65rem);
  z-index: 80;
  display: block;
  width: max-content;
  max-width: 13rem;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--text);
  box-shadow: var(--shadow-menu);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  transform: translateY(-50%);
}

html[data-sidebar-collapsed="true"] .app-sidebar__footer {
  padding-inline: 0.55rem;
}

html[data-sidebar-collapsed="true"] .sidebar-collapse-button {
  justify-content: center;
  width: 2.75rem;
  margin-inline: auto;
  padding: 0;
}

/* Persistent collapse keeps the content column stable. Hover/focus expansion
   is an overlay and never changes the stored preference. */
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar::before {
  width: 16rem;
  border-right: 1px solid var(--sidebar-border);
  box-shadow: var(--shadow-menu);
  opacity: 1;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar {
  z-index: 40;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__header,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__scroll,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__footer {
  width: 16rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__header {
  padding: 0.85rem 1rem 0.5rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__brand {
  justify-content: flex-start;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__brand-full,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__subtitle,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-control-wrap,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-utility__label,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-link__label,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .nav-section-label,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-collapse-button__label {
  display: block;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__brand-icon,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-rail-action,
html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-link__tooltip {
  display: none;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__scroll {
  padding-inline: 0.75rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-utilities {
  gap: 0.7rem;
  margin-bottom: 1.15rem;
  padding-bottom: 1rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-nav {
  gap: 0.45rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-nav__group + .sidebar-nav__group {
  margin-top: 0;
  padding-top: 0.8rem;
  border-top: 0;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-link {
  justify-content: flex-start;
  width: auto;
  min-height: 2.5rem;
  margin-inline: 0;
  padding: 0.45rem 0.7rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-link.active::before {
  left: 0;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .app-sidebar__footer {
  padding-inline: 0.75rem;
}

html[data-sidebar-collapsed="true"][data-sidebar-temporary-expanded="true"] .sidebar-collapse-button {
  justify-content: flex-start;
  width: 100%;
  margin-inline: 0;
  padding: 0.45rem 0.55rem;
}

.app-mobile-header {
  position: sticky;
  top: 0;
  z-index: 35;
  min-height: var(--app-mobile-header-height);
  overflow: visible;
  border-bottom: 1px solid var(--sidebar-border);
  background: color-mix(in srgb, var(--sidebar-bg) 94%, transparent);
  backdrop-filter: blur(10px);
}

.app-mobile-header__brand {
  min-width: 0;
  overflow: visible;
}

.app-mobile-header__brand .brand-mark--compact {
  max-width: min(10rem, 100%);
}

.app-mobile-header__brand .brand-mark--compact img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 1.85rem;
  object-fit: contain;
}

.nav-icon-spacer {
  width: 2.5rem;
  height: 2.5rem;
}

.mobile-nav-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(5, 7, 10, 0.58);
}

.mobile-nav-panel {
  position: absolute;
  inset-block: 0;
  left: 0;
  display: flex;
  width: min(21rem, 88vw);
  flex-direction: column;
  border-right: 1px solid var(--sidebar-border);
  background: var(--sidebar-bg);
  box-shadow: var(--shadow-menu);
  overflow: hidden;
}

.mobile-nav-panel__header {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--sidebar-border);
}

.mobile-nav-panel__header .brand-mark--shell {
  max-width: 11rem;
  padding-block: 0;
}

.mobile-nav-utilities {
  display: grid;
  flex: 0 0 auto;
  gap: 0.65rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--sidebar-border);
}

.mobile-shell-control .sidebar-utility__label {
  margin-left: 0;
}

.mobile-nav-panel__scroll {
  flex: 1 1 auto;
  min-height: 0;
  padding: 0.8rem;
  overflow-y: auto;
}

.mobile-nav-panel .sidebar-nav {
  gap: 0.75rem;
}

.mobile-nav-panel .sidebar-link--nested {
  padding-left: 1.15rem;
}

.mobile-nav-panel .sidebar-link__tooltip {
  display: none;
}

.mobile-account-area {
  flex: 0 0 auto;
  padding: 0.75rem;
  border-top: 1px solid var(--sidebar-border);
  background: var(--sidebar-bg);
}

.mobile-account-area__identity {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.25rem 0.4rem 0.65rem;
}

.mobile-account-area__links {
  display: grid;
  grid-template-columns: 1fr;
}

.mobile-account-area .account-menu__item {
  color: var(--sidebar-text-active);
}

.mobile-account-area .account-menu__item--logout {
  color: var(--danger);
}

.app-mobile-bottom-nav {
  min-height: calc(3.5rem + env(safe-area-inset-bottom, 0px));
  padding: 0.2rem 0.35rem env(safe-area-inset-bottom, 0px);
  border-top: 1px solid var(--sidebar-border);
  background: color-mix(in srgb, var(--sidebar-bg) 96%, transparent);
  backdrop-filter: blur(10px);
}

/* Auth continuity: approved brand art on a calm product surface. */
.auth-page {
  min-height: 100vh;
  padding: 2rem 1rem;
  background: var(--app-bg);
}

.auth-shell {
  width: min(100%, 25rem);
}

.auth-shell--wide {
  width: min(100%, 32rem);
}

.auth-brand {
  margin-bottom: 1.35rem;
  text-align: center;
}

.auth-brand::after {
  display: block;
  width: 2.5rem;
  height: 3px;
  margin: 0.9rem auto 0;
  border-radius: 999px;
  background: var(--brand-orange);
  content: "";
}

.auth-card {
  padding: 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow);
}

.auth-card .page-title {
  font-size: var(--fs-lg) !important;
}

.secondary-navigation {
  margin-top: 1rem;
  text-align: center;
}

.secondary-navigation-link {
  color: var(--text-muted);
  font-size: var(--fs-base);
  text-decoration: none;
}

.secondary-navigation-link:hover {
  color: var(--text);
  text-decoration: underline;
}

.secondary-navigation-link:focus-visible {
  border-radius: 0.25rem;
  outline: 3px solid color-mix(in srgb, var(--focus) 35%, transparent);
  outline-offset: 0.2rem;
}

.auth-version {
  margin-top: 0.75rem;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  text-align: center;
}

.field-input:focus {
  border-color: var(--focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 18%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .app-sidebar,
  .app-sidebar::before,
  .app-sidebar__header,
  .app-sidebar__scroll,
  .app-sidebar__footer,
  .account-menu__chevron {
    transition: none;
  }
}

/* T011 Checkpoint 2 — shared product components */

.page-header {
  margin-bottom: 1.25rem;
}

/* E12-05: `.page-title` typography lives in its single role rule above. */

.page-header-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.5rem;
}

select.field-input {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'><path d='M4 6l4 4 4-4' stroke='%23646970' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 0.9rem;
  padding-right: 2.1rem;
}

[data-theme="dark"] select.field-input {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'><path d='M4 6l4 4 4-4' stroke='%239ca3ad' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

textarea.field-input {
  min-height: 4.5rem;
  height: auto;
  resize: vertical;
  line-height: 1.45;
}

.field-input:disabled,
.field-input[readonly],
.field-input--readonly {
  background-color: var(--surface-alt);
  color: var(--text-muted);
  cursor: default;
}

.field-readonly {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.75rem 0.9rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
}

.field-readonly-value {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.form-panel input[type="checkbox"],
.form-panel input[type="radio"],
.table-controls input[type="checkbox"] {
  accent-color: var(--action-primary);
  width: 1.05rem;
  height: 1.05rem;
  flex: 0 0 auto;
}

.form-panel .toggle-switch__input {
  width: 1px;
  height: 1px;
  flex: none;
}

.form-check {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 2.5rem;
}

.platform-category-card {
  --platform-category-accent: var(--border);
  border-color: color-mix(in srgb, var(--platform-category-accent) 24%, var(--border));
  background: color-mix(in srgb, var(--platform-category-accent) 5%, var(--surface));
}

.platform-category--invitations {
  --platform-category-accent: var(--data-blue);
}

.platform-category--access-requests {
  --platform-category-accent: var(--warning);
}

.platform-category--families {
  --platform-category-accent: var(--success);
}

.platform-category-card .platform-section-head {
  background: color-mix(in srgb, var(--platform-category-accent) 7%, var(--surface));
}

.platform-category__heading {
  margin: 1.5rem 0 0.75rem;
  padding-left: 0.75rem;
  border-left: 3px solid var(--platform-category-accent);
}

.platform-category__heading h2 {
  margin: 0;
  color: var(--text);
  font-size: 1rem;
  font-weight: 700;
}

.platform-category__heading p {
  margin: 0.2rem 0 0;
  color: var(--text-muted);
  font-size: 0.75rem;
}

.form-panel {
  width: 100%;
  max-width: 100%;
  padding: 1.25rem 1.15rem 1.4rem;
}

@media (min-width: 768px) {
  .form-panel {
    max-width: min(64rem, 100%);
    padding: 1.5rem 1.6rem 1.65rem;
  }
}

@media (min-width: 1280px) {
  .form-panel {
    max-width: min(72rem, 100%);
  }
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.55rem;
  padding-top: 0.9rem;
  margin-top: 0.35rem;
  border-top: 1px solid var(--border);
}

/* E12-04 Design System Foundation: generic Entity Management primitives,
   extracted from the approved Accounts & Cards List/Add/Edit/View
   implementation (docs/DESIGN_SYSTEM.md). Values are unchanged from the
   Account-specific rules they replace -- this is a rename/extraction,
   not a redesign. Account-domain rules (type/currency choices, credit
   card math, generated names, currency/owner semantics) stay under
   `.account-*` below and are intentionally NOT part of this section. */

.entity-detail-header {
  margin-bottom: 0.4rem;
}

.entity-detail-header__row {
  display: flex;
  align-items: flex-start;
  gap: 0.35rem;
}

.page-back-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  margin-top: -0.25rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
  box-shadow: var(--shadow);
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease, transform 0.1s ease;
}

.page-back-button:hover {
  background: var(--surface-alt);
  border-color: color-mix(in srgb, var(--action-primary) 35%, var(--border));
  color: var(--text);
}

.page-back-button:active {
  background: var(--surface-selected);
  transform: translateY(1px);
}

.page-back-button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.page-back-button__icon {
  width: 1.15rem;
  height: 1.15rem;
}

.entity-form-panel,
.entity-detail-view {
  padding: 0.5rem 0.75rem 0.6rem;
}

.entity-form-panel .field-label {
  margin-bottom: 0.125rem;
}

.entity-form-panel .field-input {
  min-height: 2.25rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
}

.entity-form-panel textarea.field-input {
  min-height: 2.5rem;
}

.entity-form-section + .entity-form-section,
.entity-detail-section + .entity-detail-section {
  padding-top: 0.35rem;
  margin-top: 0.35rem;
  border-top: 1px solid var(--border);
}

.entity-form-section__title,
.entity-detail-section__title {
  margin: 0 0 0.3rem;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-title);
}

.field-optional {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
}

.account-type-choices {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.4rem;
  padding: 0;
  margin: 0;
  border: 0;
}

.account-type-choice,
.account-currency-choice {
  position: relative;
  min-width: 0;
  cursor: pointer;
}

.account-choice-input {
  position: absolute;
  width: 1px !important;
  height: 1px !important;
  opacity: 0;
  pointer-events: none;
}

.account-type-choice__surface {
  display: flex;
  align-items: center;
  min-height: 2.8rem;
  gap: 0.45rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text-muted);
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.account-type-choice:hover .account-type-choice__surface,
.account-currency-choice:hover .account-currency-choice__surface {
  border-color: color-mix(in srgb, var(--action-primary) 45%, var(--border));
}

.account-choice-input:focus:not(:focus-visible) + .account-type-choice__surface,
.account-choice-input:focus:not(:focus-visible) + .account-currency-choice__surface {
  outline: none;
}

.account-choice-input:focus-visible + .account-type-choice__surface,
.account-choice-input:focus-visible + .account-currency-choice__surface {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

/* E12-05-020: every choice tile gets the selected treatment One-Time's type
   cards established -- the action-primary border and tint PLUS non-color
   cues: a 1px inset ring (a 2px outline in effect) and a small check mark.
   Room for the check is reserved on every card, so selecting one never
   shifts its layout. Focus-visible keeps its own separate outline. */
.account-type-choice .account-choice-input + .account-type-choice__surface,
.account-currency-choice .account-choice-input + .account-currency-choice__surface {
  padding-right: 1.1rem;
}

.account-choice-input:checked + .account-type-choice__surface,
.account-choice-input:checked + .account-currency-choice__surface {
  position: relative;
  border-color: var(--action-primary);
  background: color-mix(in srgb, var(--action-primary) 8%, var(--surface));
  box-shadow: inset 0 0 0 1px var(--action-primary);
  color: var(--action-primary);
}

.account-choice-input:checked + .account-type-choice__surface::after,
.account-choice-input:checked + .account-currency-choice__surface::after {
  /* SMOKE-012: the check mark is decorative -- the native radio already
     exposes its checked state -- so it must not join the radio's
     accessible name. Browsers without generated-content alt text keep the
     first declaration (unchanged look); the rest paint the same glyph with
     an empty alternative. */
  content: "\2713";
  content: "\2713" / "";
  position: absolute;
  top: 0.2rem;
  right: 0.4rem;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  color: var(--action-primary);
}

/* E12-04 One-Time Add type cards: a restrained inflow/outflow cue in the
   same direction language as the One-Time List Type headings. The card
   label always names the type, so color is never the only cue.
   E12-06 UI-09 (final PO mapping; supersedes F016's color choice while
   keeping its point): the direction reads from the SAME semantic tokens
   the List headings use -- Receivable/Money Lent green, Money
   Borrowed/Reserved Funds red -- so the two surfaces cannot drift apart.
   It stays an edge on a plain surface: no wash, no status border, no
   status text color, so an unselected outflow card still never reads
   like a validation error. Theme-aware via the tokens themselves. */
.one-time-type-choice--inflow .account-type-choice__surface {
  background: var(--surface);
  box-shadow: inset 3px 0 0 var(--flow-inflow);
}

.one-time-type-choice--outflow .account-type-choice__surface {
  background: var(--surface);
  box-shadow: inset 3px 0 0 var(--flow-outflow);
}

/* Selected: the shared action-primary border/tint PLUS non-color cues --
   a 2px ring (border + inset ring) and a check mark -- while the
   direction edge stays visible. Hover/focus-visible keep the shared
   treatment above (focus outline is separate from the selection ring). */
.one-time-type-choice .account-choice-input:checked + .account-type-choice__surface {
  position: relative;
  border-color: var(--action-primary);
  background: color-mix(in srgb, var(--action-primary) 8%, var(--surface));
}

.one-time-type-choice--inflow .account-choice-input:checked + .account-type-choice__surface {
  box-shadow:
    inset 3px 0 0 var(--flow-inflow),
    inset 0 0 0 1px var(--action-primary);
}

.one-time-type-choice--outflow .account-choice-input:checked + .account-type-choice__surface {
  box-shadow:
    inset 3px 0 0 var(--flow-outflow),
    inset 0 0 0 1px var(--action-primary);
}

.account-type-choice__icon {
  width: 1.3rem;
  height: 1.3rem;
  flex: 0 0 auto;
}

.account-type-choice__label {
  min-width: 0;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
}

.account-information-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  gap: 0.3rem 0.7rem;
}

.account-compact-select {
  min-width: 0;
}

.entity-detail-grid--compact {
  gap: 0.3rem 0.8rem;
}

.entity-metadata-item {
  min-width: 0;
  padding: 0.05rem 0;
}

.entity-metadata-label,
.entity-metadata-item dt {
  display: block;
  margin: 0 0 0.15rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
}

.entity-metadata-value,
.entity-metadata-item dd {
  display: block;
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  line-height: 1.3;
}

.account-currency-field fieldset {
  padding: 0;
  margin: 0;
  border: 0;
}

.account-currency-choices {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.4rem;
  max-width: 18rem;
}

.account-currency-choice__surface {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.3rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.account-short-input {
  max-width: 12rem;
}

.account-balance-single {
  max-width: 22rem;
}

.account-credit-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: 0.6rem;
}

.account-nickname-field {
  max-width: 34rem;
}

.entity-form-switches {
  display: grid;
  gap: 0.15rem;
  max-width: 48rem;
}

/* E12-04 pre-freeze polish: no grey filled/bordered container -- the row
   is spacing only. The switch, label, and state text (On/Off,
   Active/Inactive) are unchanged, as is the touch-target sizing below. */
.entity-setting-row {
  padding: 0.15rem 0.55rem;
}

.entity-setting-row .boolean-field__row {
  justify-content: space-between;
  min-height: 2.15rem;
}

.entity-setting-row .toggle-switch {
  min-height: 2.15rem;
}

.entity-form-section--secondary,
.entity-detail-section--secondary {
  color: var(--text-muted);
}

.entity-notes-field {
  max-width: 40rem;
}

.entity-form-section [hidden],
.entity-detail-view [hidden] {
  display: none;
}

.account-currency-warning {
  color: var(--warning);
  max-width: 24rem;
  margin-top: 0.15rem;
  font-size: var(--fs-2xs);
  line-height: 1.3;
}

.account-calculated-value {
  align-self: end;
  min-height: 2.25rem;
  padding: 0.15rem 0 0.25rem;
}

.entity-detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.3rem;
  margin: 0;
}

.entity-detail-grid--financial {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.entity-detail-item {
  min-width: 0;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
}

.entity-detail-item--wide {
  grid-column: 1 / -1;
}

.entity-detail-item--emphasis {
  border-color: color-mix(in srgb, var(--text-muted) 30%, var(--border));
  background: var(--surface-alt);
}

.entity-detail-item dt {
  margin-bottom: 0.15rem;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
}

.entity-detail-item dd {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
}

.entity-detail-notes {
  min-height: 1.25rem;
  white-space: pre-wrap;
}

.entity-form-actions {
  padding-top: 0.3rem;
  margin-top: 0;
}

@media (min-width: 768px) {
  .entity-form-panel,
  .entity-detail-view {
    padding: 0.65rem 0.9rem 0.7rem;
  }
}

@media (max-width: 767px) {
  .entity-form-panel,
  .entity-detail-view {
    margin-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  }
}

@media (max-width: 639px) {
  .account-type-choices,
  .account-information-grid,
  .account-credit-grid,
  .entity-detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .account-type-choices {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .account-information-grid,
  .entity-detail-grid--compact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .account-information-grid > *,
  .entity-detail-grid--compact > * {
    grid-column: 1 / -1;
  }

  .account-information-grid > .account-metadata-item--type,
  .entity-detail-grid--compact > .account-metadata-item--type {
    grid-column: 1;
    grid-row: 1;
  }

  .account-information-grid > .account-currency-field--immutable,
  .entity-detail-grid--compact > .account-metadata-item--currency {
    grid-column: 2;
    grid-row: 1;
  }

  .account-type-choice__surface {
    min-height: 2.8rem;
    padding: 0.35rem 0.55rem;
  }

  .account-currency-choices {
    max-width: none;
  }

  .entity-detail-item--wide {
    grid-column: auto;
  }

  .form-actions .btn {
    flex: 1 1 calc(50% - 0.3rem);
    min-height: 2.75rem;
  }

  .entity-form-actions--add .btn-primary {
    flex-basis: 100%;
  }
}

/* ==========================================================================
   E12-04 Investment Accounts List / Add / Edit / View
   Built from the Savings Contributions primitives (owner -> type grouped
   `.bills-data-table`, `.contribution-*` identity grids, type cards,
   `.bill-owner-grid`, entity-detail View) and the Accounts & Cards summary
   card. Only the few rules below are Investment Accounts specific.
   ========================================================================== */

/* List: a Current Value WealthCast has not recorded yet reads as quiet,
   not as a zero amount. */
.investment-value-unknown {
  color: var(--text-muted);
  font-weight: var(--fw-medium);
}

/* Performance history: compact percentage fields (Add/Edit) and values
   (View) instead of full-width inputs. */
.investment-performance-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 8.5rem));
  gap: 0.4rem 0.75rem;
}

.investment-performance-field {
  min-width: 0;
}

/* Phones: the compact detail grid spans each item full-width; the yearly
   returns stay compact side-by-side values instead. */
@media (max-width: 639px) {
  .entity-detail-grid.investment-performance-grid {
    grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  }

  .entity-detail-grid.investment-performance-grid > * {
    grid-column: auto;
  }
}

.investment-currency-warning {
  color: var(--warning);
}

/* The WealthCast navigation link inside a muted hint stays recognisable
   as a link in both themes. */
.investment-wealthcast-link {
  color: var(--action-primary);
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ==========================================================================
   E12-04 Contribution Room List / Add / Edit / View
   Built from the Accounts & Cards primitives (summary card, owner-grouped
   `.accounts-list-table`, `.account-type-choices`,
   `.account-information-grid`, read-only `.entity-metadata-item`). Only
   the few rules below are Contribution Room specific.
   ========================================================================== */

/* List: the As-of line under the account type stands in for the As of
   column wherever the column is hidden (the mobile card, below 1024px). */
@media (min-width: 1024px) {
  .contribution-room-row-summary {
    display: none;
  }
}

/* View: the persisted type is the Add/Edit choice card shown alone and
   made non-interactive (no pointer, no hover border change). */
.contribution-room-type-choice--readonly {
  cursor: default;
}

.contribution-room-type-choice--readonly:hover .account-type-choice__surface {
  border-color: var(--border);
}

/* View: Notes read as the Edit notes field's text (literal, wrapped). */
.contribution-room-view-notes {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-base);
}

/* ==========================================================================
   E12-04 One-Time Money Edit/View
   One entity architecture for every type: Edit is the populated Add form,
   View its read-only counterpart; Money Lent / Borrowed add Interest terms,
   Balance today and Repayments as further shared entity sections. Only the
   few rules below are One-Time specific.
   ========================================================================== */
.one-time-detail-subtitle {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.6rem;
}

/* Edit and View: the read-only Item type is the Add selector card made
   non-interactive -- identical dimensions/direction treatment (the shared
   .one-time-type-choice rules above), without the pointer or the shared
   hover border change. */
.one-time-type-choice--readonly {
  cursor: default;
}

.one-time-type-choice--readonly:hover .account-type-choice__surface {
  border-color: var(--border);
}

/* View: Notes read as the Edit notes field's text (literal, wrapped). */
.one-time-view-notes {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-base);
}

/* Money Lent / Borrowed Edit and View: ONE card. The Edit <form> (View:
   its read-only field wrapper) is `display: contents`, so its sections/
   actions and the repayment companion are
   sibling grid items of the card -- ordered by grid areas without
   duplicating any content (the form still owns its fields for submission).
   Below 1280px: one vertical flow with the companion between Status and
   Notes. From 1280px: Edit details (~63%) | companion (~37%), separated by
   an internal divider; Notes + actions stay with the Edit side. The card
   is an inline-size container so the read-only Item type card keeps its
   approved single-column width. */
.one-time-loan-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "item"
    "amount"
    "interest"
    "status"
    "companion"
    "notes"
    "actions";
  align-items: start;
  container-type: inline-size;
}

.one-time-loan-card > form,
.one-time-loan-card > .one-time-view-fields {
  display: contents;
}

.one-time-loan-card [aria-labelledby="one-time-edit-item"],
.one-time-loan-card [aria-labelledby="one-time-view-item"] { grid-area: item; }
.one-time-loan-card [aria-labelledby="one-time-edit-amount"],
.one-time-loan-card [aria-labelledby="one-time-view-amount"] { grid-area: amount; }
.one-time-loan-card [aria-labelledby="one-time-edit-interest"],
.one-time-loan-card [aria-labelledby="one-time-view-interest"] { grid-area: interest; }
.one-time-loan-card [aria-labelledby="one-time-edit-status"],
.one-time-loan-card [aria-labelledby="one-time-view-status"] { grid-area: status; }
.one-time-loan-card [aria-labelledby="one-time-edit-notes"],
.one-time-loan-card [aria-labelledby="one-time-view-notes"] { grid-area: notes; }
.one-time-loan-card > form > .entity-form-actions,
.one-time-loan-card > .one-time-view-fields > .entity-form-actions { grid-area: actions; }
.one-time-loan-card > .one-time-repayment-companion { grid-area: companion; }

/* Stacked: the companion reads as a section of the same card. */
.one-time-repayment-companion {
  padding-top: 0.35rem;
  margin-top: 0.35rem;
  border-top: 1px solid var(--border);
}

@media (min-width: 1280px) {
  .one-time-loan-card {
    max-width: min(96rem, 100%);
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    grid-template-rows: repeat(6, auto) 1fr;
    grid-template-areas:
      "item companion"
      "amount companion"
      "interest companion"
      "status companion"
      "notes companion"
      "actions companion"
      ". companion";
    column-gap: 1.5rem;
  }

  /* Side by side: an internal vertical divider, not a second card. */
  .one-time-loan-card > .one-time-repayment-companion {
    align-self: stretch;
    margin-top: 0;
    padding: 0.1rem 0 0 1.5rem;
    border-top: 0;
    border-left: 1px solid var(--border);
  }

  /* Compact Amount & dates: Original principal | Currency | Due on ONE row,
     sized to their content (money, a 3-letter code, a date) rather than
     three equal columns. The section's two field grids are flattened
     (display: contents) so the same three cells share one grid; stacked
     below this breakpoint exactly as before. */
  .one-time-loan-card [aria-labelledby="one-time-edit-amount"],
  .one-time-loan-card [aria-labelledby="one-time-view-amount"] {
    display: grid;
    grid-template-columns: minmax(12rem, 16rem) minmax(6rem, 8rem) minmax(11rem, 14rem);
    justify-content: start;
    align-items: start;
    column-gap: 1rem;
    row-gap: 0;
  }

  .one-time-loan-card [aria-labelledby="one-time-edit-amount"] > .entity-form-section__title,
  .one-time-loan-card [aria-labelledby="one-time-view-amount"] > .entity-form-section__title {
    grid-column: 1 / -1;
  }

  .one-time-loan-card [aria-labelledby="one-time-edit-amount"] > .grid,
  .one-time-loan-card [aria-labelledby="one-time-view-amount"] > .grid {
    display: contents;
  }

  /* Approved Item type card width: a quarter of the single-column form
     panel's content box (panel = min(72rem, available width); minus
     2 x 0.9rem padding, the 1px borders and 3 x 0.4rem gaps) -- 100cqw is
     this card's content box, so the available width is 100cqw + 1.8rem +
     2px -- capped to the column. */
  .one-time-loan-card .one-time-type-choices {
    grid-template-columns: minmax(0, min(calc((min(72rem, 100cqw + 1.8rem + 2px) - 3rem - 2px) / 4), 100%));
  }
}

.one-time-repayment-companion__action {
  width: 100%;
  min-height: 2.5rem;
  margin-top: 0.6rem;
}

.one-time-repayment-companion__subtitle {
  margin: 0.9rem 0 0.35rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.one-time-recent-repayments {
  margin: 0;
  padding: 0;
  list-style: none;
}

.one-time-recent-repayments__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "date amount"
    "type type"
    "note note";
  gap: 0.15rem 0.75rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm);
}

.one-time-recent-repayments__item:last-child {
  border-bottom: 0;
}

.one-time-recent-repayments__date {
  grid-area: date;
  color: var(--text);
}

.one-time-recent-repayments__amount {
  grid-area: amount;
  font-weight: var(--fw-semibold);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.one-time-recent-repayments__type {
  grid-area: type;
}

.one-time-recent-repayments__type .badge {
  white-space: nowrap;
}

.one-time-recent-repayments__note {
  grid-area: note;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* Record repayment sheet: the shared native <dialog> primitive (Family
   member drawers, confirm modal), placed as a right-side sheet. The UA
   provides focus containment, Esc and the backdrop. Phones: a near-full-
   height bottom sheet. */
.one-time-repayment-sheet {
  position: fixed;
  inset: 0 0 0 auto;
  margin: 0;
  width: min(30rem, 100%);
  max-width: 100%;
  height: 100dvh;
  max-height: 100dvh;
  padding: 0;
  border: 0;
  border-left: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  box-shadow: -12px 0 40px rgba(17, 19, 23, 0.25);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.one-time-repayment-sheet:not([open]) {
  display: none;
}

.one-time-repayment-sheet::backdrop {
  background: rgba(15, 17, 21, 0.5);
}

/* Restrained motion: the sheet slides in from the right while the backdrop
   fades; closing plays the reverse (the script adds .is-closing and calls
   close() only when it ends). Phones: the same language, bottom-up. */
@keyframes one-time-sheet-in-right {
  from { transform: translateX(100%); }
  to { transform: translateX(0); }
}

@keyframes one-time-sheet-out-right {
  from { transform: translateX(0); }
  to { transform: translateX(100%); }
}

@keyframes one-time-sheet-in-up {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

@keyframes one-time-sheet-out-down {
  from { transform: translateY(0); }
  to { transform: translateY(100%); }
}

@keyframes one-time-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes one-time-backdrop-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* The entrance runs from a class the script adds right after showModal()
   -- NOT from [open] -- so a server-rendered open sheet (non-JS fallback)
   never animates by itself and the JS upgrade animates exactly once. */
.one-time-repayment-sheet.is-opening {
  animation: one-time-sheet-in-right 240ms cubic-bezier(0.2, 0, 0, 1);
}

.one-time-repayment-sheet.is-opening::backdrop {
  animation: one-time-backdrop-in 240ms ease-out;
}

.one-time-repayment-sheet.is-closing {
  animation: one-time-sheet-out-right 200ms cubic-bezier(0.4, 0, 1, 1) forwards;
}

.one-time-repayment-sheet.is-closing::backdrop {
  animation: one-time-backdrop-out 200ms ease-in forwards;
}

.one-time-repayment-sheet__header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.one-time-repayment-sheet__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  letter-spacing: var(--tracking-title);
}

/* Comfortable (not compressed) spacing: single-column fields at a relaxed
   rhythm, so the form reads as the sheet's content rather than a strip at
   the top of an empty panel. */
.one-time-repayment-sheet__body {
  display: grid;
  gap: 1.1rem;
  padding: 1.5rem 1.5rem 2rem;
}

.one-time-repayment-sheet [data-repayment-form] {
  display: grid;
  gap: 1.1rem;
}

.one-time-repayment-sheet [data-repayment-form] .grid {
  grid-template-columns: minmax(0, 1fr);
  gap: 1.1rem;
}

.one-time-repayment-sheet .one-time-repayment-actions {
  margin-top: 0.4rem;
  padding-top: 1rem;
}

/* Sheet actions: right-aligned, the primary last (standard treatment). */
.one-time-repayment-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.5rem;
}

.one-time-repayment-actions form {
  display: contents;
}

@media (max-width: 639px) {
  .one-time-repayment-sheet {
    inset: auto 0 0 0;
    width: 100%;
    height: 92dvh;
    max-height: 92dvh;
    border-left: 0;
    border-top: 1px solid var(--border);
    border-radius: 1rem 1rem 0 0;
    box-shadow: 0 -12px 40px rgba(17, 19, 23, 0.25);
  }

  .one-time-repayment-sheet.is-opening {
    animation-name: one-time-sheet-in-up;
  }

  .one-time-repayment-sheet.is-closing {
    animation-name: one-time-sheet-out-down;
  }

  .one-time-repayment-sheet__header {
    padding: 0.9rem 1.1rem;
  }

  .one-time-repayment-sheet__body {
    padding: 1.1rem 1.1rem 1.5rem;
  }

  .one-time-repayment-actions .btn {
    flex: 1 1 100%;
    min-height: 2.75rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .one-time-repayment-sheet.is-opening,
  .one-time-repayment-sheet.is-opening::backdrop,
  .one-time-repayment-sheet.is-closing,
  .one-time-repayment-sheet.is-closing::backdrop {
    animation: none;
  }
}

/* Repayment review (server-authoritative; nothing recorded until Confirm). */
.one-time-review {
  padding: 0.85rem;
  border: 1px solid color-mix(in srgb, var(--action-primary) 40%, var(--border));
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--action-primary) 4%, var(--surface));
}

.one-time-review__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  letter-spacing: var(--tracking-title);
}

.one-time-review__lede {
  margin: 0.15rem 0 0.6rem;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.one-time-review__table-wrap {
  overflow-x: auto;
}

.one-time-review__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-base);
}

.one-time-review__table th,
.one-time-review__table td {
  padding: 0.45rem 0.5rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
  color: var(--text);
}

.one-time-review__table thead th {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.one-time-review__table td,
.one-time-review__table thead th:not(:first-child) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.one-time-review__table tbody th {
  font-weight: var(--fw-medium);
}

.one-time-review__total th,
.one-time-review__total td {
  font-weight: var(--fw-semibold);
}

@media (min-width: 640px) and (max-width: 899px) {
  .account-information-grid,
  .account-credit-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.field-with-mark {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.field-with-mark .field-input {
  flex: 1 1 auto;
}

.field-with-mark [data-brand-preview-img][hidden] {
  display: none;
}

.data-table thead th {
  background: var(--surface-alt);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

/* E12-05 column-header role: every User App table header shares it
   (uppercase is reserved for column headers, badges and weekday names). */
.item-ledger-table thead th,
.cp-timeline-table thead th,
.month-list-table thead th,
.quick-update-table thead th,
.preview-occurrence-table thead th,
.one-time-review__table thead th,
.investment-table thead th {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* E12-05 text tiers: table data reads as secondary text, not muted. */
.entity-list-meta,
.month-list-meta,
.item-ledger-meta,
.cp-timeline-col-date,
.cp-timeline-col-account,
.quick-update-col-type {
  color: var(--text-secondary);
}

.data-table tbody tr.entity-list-row {
  border-bottom: 1px solid var(--border);
}

.data-table tbody tr.entity-list-row:hover {
  background: var(--surface-hover);
}

.data-table .entity-list-value,
.financial-value {
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-semibold);
}

.financial-value--positive {
  color: var(--success);
}

.financial-value--negative {
  color: var(--danger);
}

.financial-value--muted,
.financial-note {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}

.brand-mark--institution {
  display: inline-block;
  width: 1.75rem;
  height: 1.75rem;
  flex: 0 0 auto;
  object-fit: contain;
  border-radius: 0.35rem;
  background: var(--surface);
}

.brand-mark--generic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--surface-alt);
  color: var(--text-muted);
}

.brand-mark__generic-icon {
  width: 1.05rem;
  height: 1.05rem;
}

.brand-mark--network {
  display: inline-block;
  width: 2.15rem;
  height: 1.4rem;
  flex: 0 0 auto;
  object-fit: contain;
  border-radius: 0.28rem;
  border: 1px solid var(--border);
  background: var(--surface);
}

[data-theme="dark"] .brand-mark--network {
  background: var(--surface-selected);
}

.identity-with-marks {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  min-width: 0;
}

.identity-marks {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
  padding-top: 0.1rem;
}

.identity-copy {
  min-width: 0;
}

/* E12-05-024: Accounts reserve the same mark column on every row (room for
   an institution mark plus a card-network mark), so a name starts in the
   same place whether a row has two marks, one, or none -- absence is left
   to the layout, never filled with placeholder text. */
.accounts-list-table .identity-marks {
  width: 4.25rem;
  justify-content: flex-start;
}

.member-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  flex: 0 0 auto;
}

.member-avatar--header {
  width: 2rem;
  height: 2rem;
  font-size: 0.72rem;
}

.member-avatar--sm {
  width: 1.8rem;
  height: 1.8rem;
  font-size: 0.65rem;
}

.member-avatar--xs {
  width: 1.35rem;
  height: 1.35rem;
  margin-right: 0.35rem;
  font-size: 0.55rem;
  vertical-align: middle;
}

.badge-owner {
  text-transform: none;
  letter-spacing: 0.01em;
}

.list-action {
  min-height: 2.25rem;
}

.entity-list-actions .table-edit-button {
  min-height: 2.25rem;
}

@media (max-width: 1023px) {
  .entity-list-table .entity-list-row {
    gap: 0.05rem;
  }

  .identity-with-marks {
    align-items: center;
  }

  .list-action {
    min-height: 2.75rem;
  }
}

/* E12-04: Accounts & Cards list redesign. Everything below is scoped to
   .accounts-* classes or nested under .accounts-list-table, so Income /
   Bills / Savings Contributions / Loans -- which share the same
   .entity-list/.entity-list-table primitives -- are completely
   unaffected. */

/* Design System Foundation: generic Entity List controls (search +
   compact exception switch on one row), extracted from the approved
   Accounts & Cards list controls below (spec ACC-LIST-002). Values are
   unchanged -- Accounts is the only current consumer; Income/Bills/
   Savings Contributions/Loans still use their own Tailwind-based
   `.table-controls` layout until they are migrated in a later batch. */
/* E12-06 UI-10 (supersedes the "never wrap" contract these controls
   carried for ACC-LIST-002): the row reflows when it genuinely cannot
   hold both controls, rather than squeezing Search. The switch never
   shrinks and its label is never shortened, so Search keeps a usable
   basis and the switch drops to a second line exactly when the page's
   own label needs it -- "Show inactive bills" rejoins one row sooner
   than "Show inactive income sources", with no per-page rule and no
   magic viewport width. */
.entity-list-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

/* The switch's own label stays on one line and never shrinks; with room
   to spare the search field takes the rest of the row. E12-06 UI-10: at
   narrow widths the row reflows instead of squeezing Search -- see the
   max-width: 480px block below. */
.entity-list-controls .toggle-switch {
  flex: 0 0 auto;
  white-space: nowrap;
}

.entity-search-field {
  position: relative;
  flex: 1 1 14rem;
  min-width: 10rem;
  max-width: 20rem;
}

.entity-search-field .field-input {
  width: 100%;
  padding-right: 2rem;
}

/* The browser's own native type="search" clear icon is suppressed --
   it's inconsistent across engines (absent in Firefox) and doesn't
   guarantee an immediate resubmit, so the explicit control above is the
   one source of truth; without this, Chrome/Safari render both side by
   side. */
.entity-search-field input[type="search"]::-webkit-search-cancel-button,
.entity-search-field input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}

/* Native type="search" already clears reliably in most engines, but not
   consistently (notably Firefox) and not with a guaranteed immediate
   resubmit -- this explicit control (app.js) covers every browser and
   restores the full list the instant it's pressed, per spec. */
.entity-search-clear {
  position: absolute;
  top: 50%;
  right: 0.5rem;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.entity-search-clear:hover,
.entity-search-clear:focus-visible {
  background: var(--surface-hover);
  color: var(--text);
}

.entity-search-clear[hidden] {
  display: none;
}

@media (max-width: 480px) {
  .table-controls.entity-list-controls {
    padding: 0.625rem;
  }

  /* E12-06 UI-10: on a phone the search field simply takes the whole
     first line (the reflow itself is in the shared rule above). */
  .entity-list-controls {
    gap: 0.5rem 0.3rem;
  }

  .entity-search-field {
    max-width: none;
    flex-basis: 100%;
  }

  .entity-list-controls .toggle-switch {
    gap: 0.4rem;
  }
}

/* Owner grouping (spec ACC-LIST-004): a lightweight section break, not a
   second heavy heading style -- title case (the label text itself, e.g.
   "Joint" or a Family Member's name, is already correctly cased) rather
   than the shared .owner-group-heading's uppercase treatment, and a
   hairline rule instead of a tinted background. */
.accounts-owner-heading {
  padding: 1.1rem 1rem 0.35rem;
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  background-color: transparent;
  border-top: 1px solid var(--border);
}

.entity-list-group:first-child .accounts-owner-heading {
  padding-top: 0.25rem;
  border-top: none;
}

/* MonthCast Included/Excluded (spec ACC-LIST-005): Included is the
   expected default state and stays quiet plain text; Excluded is the
   more noticeable badge -- an intentional reversal of the old
   Included=badge-success/Excluded=plain treatment. */
.accounts-monthcast-quiet {
  color: var(--text-muted);
}

/* Compact mobile-only summary line ("Chequing · CAD · MonthCast
   Included") replacing the separate Type/Currency/MonthCast/Status rows
   the shared entity-list mobile transform would otherwise reveal. */
.accounts-row-summary {
  margin-top: 0.3rem;
  font-size: var(--fs-sm);
}

/* Compact pencil/eye row action (spec ACC-LIST-006), replacing the full-
   width text button. Sized/colored like .btn-secondary at rest (a plain
   bordered control, no color call-out) so it reads as the same weight of
   action the old text button was. */
.icon-action-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  text-decoration: none;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.icon-action-btn:hover,
.icon-action-btn:focus-visible {
  background: var(--surface-hover);
  color: var(--text);
}

.icon-action-btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

.icon-action-btn__icon {
  width: 1.05rem;
  height: 1.05rem;
}

/* E12-MCS: the one action a row is actually for carries the app's primary
   treatment, so it reads as the way in rather than as one more neutral
   control beside the destructive one. */
.icon-action-btn--primary {
  border-color: var(--action-primary);
  background: var(--action-primary);
  color: var(--action-primary-contrast);
}

.icon-action-btn--primary:hover,
.icon-action-btn--primary:focus-visible {
  border-color: var(--action-primary-hover);
  background: var(--action-primary-hover);
  color: var(--action-primary-contrast);
}

/* DATA-01: a record-lifecycle row action says what it does at rest, from
   the existing semantic tokens -- Delete destructive (the treatment the
   Latest MonthCast's Delete already has), Deactivate warning, Activate
   success. Edit / View keep the neutral control above. One shared
   treatment for every list that renders these actions; never a per-list
   colour. */
.icon-action-btn--tone-danger {
  border-color: color-mix(in srgb, var(--danger) 46%, var(--border));
  color: var(--danger);
}

.icon-action-btn--tone-danger:hover,
.icon-action-btn--tone-danger:focus-visible {
  border-color: color-mix(in srgb, var(--danger) 46%, var(--border));
  background: var(--danger-bg);
  color: var(--danger);
}

.icon-action-btn--tone-warning {
  border-color: color-mix(in srgb, var(--warning-fill) 55%, var(--border));
  color: var(--warning-fill);
}

.icon-action-btn--tone-warning:hover,
.icon-action-btn--tone-warning:focus-visible {
  border-color: color-mix(in srgb, var(--warning-fill) 55%, var(--border));
  background: var(--warning-bg);
  color: var(--warning);
}

.icon-action-btn--tone-success {
  border-color: color-mix(in srgb, var(--success) 46%, var(--border));
  color: var(--success);
}

.icon-action-btn--tone-success:hover,
.icon-action-btn--tone-success:focus-visible {
  border-color: color-mix(in srgb, var(--success) 46%, var(--border));
  background: var(--success-bg);
  color: var(--success);
}

/* Immediate hover/focus disclosure (no native browser tooltip delay),
   consistent with the MonthCast Calendar Email Reminder icon's tooltip
   (.monthcast-calendar-reminder__tooltip). Anchored above-right so it
   never clips against the viewport's right edge from this rightmost
   column. */
.icon-action-btn__tooltip {
  position: absolute;
  z-index: 20;
  bottom: calc(100% + 0.4rem);
  right: 0;
  width: max-content;
  max-width: 14rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  box-shadow: var(--shadow-menu);
  color: var(--text);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.3;
  white-space: normal;
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.15rem);
  transition: opacity 120ms ease, transform 120ms ease;
}

.icon-action-btn:hover .icon-action-btn__tooltip,
.icon-action-btn:focus-visible .icon-action-btn__tooltip {
  opacity: 1;
  transform: translateY(0);
}

/* SMOKE-009: long unbroken user-controlled names (a token with no break
   opportunity) must not widen their component past its container.
   Component-scoped only -- the established CountAhead convention
   (`overflow-wrap: anywhere`, plus `min-width: 0` where flex/grid intrinsic
   sizing needs it): the complete name stays visible, nothing is truncated,
   and ordinary names (which already fit) keep their presentation. Amounts,
   dates, badges and actions are untouched. */
.entity-list-identity,
.owner-group-heading,
.icon-action-btn__tooltip {
  min-width: 0;
  overflow-wrap: anywhere;
}

.entity-detail-header__row > div {
  min-width: 0;
}

/* A fitted entity-name title measures itself against its own width, so its
   header row and title column take the remaining width instead of
   shrink-wrapping the title; otherwise a title that already fits would
   measure a subpixel too wide and shrink. */
.entity-detail-header:has([data-fit-title]) > .entity-detail-header__row,
.entity-detail-header__row > div:has(> [data-fit-title]) {
  flex: 1 1 auto;
}

.entity-detail-header .page-subtitle,
.entity-detail-header .page-title--with-icon > span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.cp-timeline-col-name,
.cp-timeline-col-account {
  overflow-wrap: anywhere;
}

/* Quick Update's table can already be tight, where `anywhere` on every
   name would let the column shrink below the longest ordinary word and
   split ordinary names mid-word. Only a name the template marks as holding
   an unbroken token opts in; the column keeps the width its ordinary names
   give it, and that one name wraps inside it. */
.quick-update-col-name--unbroken {
  overflow-wrap: anywhere;
}

[data-wealthcast-chart] .analytics-chart-legend-toggle {
  max-width: 100%;
  min-width: 0;
  overflow-wrap: anywhere;
  text-align: left;
}

/* The data table is deliberately `nowrap` (it scrolls), so wrapping the
   whole header cell would split ordinary multi-word names per word. The
   label box is exactly its max-content width -- ordinary names keep their
   single line and width -- capped so only an unbroken token wraps. */
[data-wealthcast-value-history-table] .wealthcast-row-label {
  display: inline-block;
  width: max-content;
  max-width: 20rem;
  white-space: normal;
  overflow-wrap: anywhere;
  vertical-align: top;
}

.value-history-filter-panel {
  max-width: min(24rem, calc(100vw - 1rem));
}

@media (max-width: 767px) {
  /* In normal flow the panel starts after the page gutter and form-card
     padding (about 2.06rem), so it is capped to end the same distance from
     the right edge. */
  .value-history-filter-panel {
    max-width: calc(100vw - 4.125rem);
  }
}

.value-history-filter-panel label > span {
  min-width: 0;
  overflow-wrap: anywhere;
}

@media (max-width: 1023px) {
  /* Accounts & Cards mobile card (spec ACC-LIST-007): a materially
     different hierarchy from the shared generic entity-list stacked-rows
     pattern -- identity on top with the action in its corner, one
     compact metadata line, no separate Type/Currency/MonthCast/Status
     rows, no full-width bottom action bar. Scoped to .accounts-list-table
     so every other entity list keeps today's shared behavior. */
  .accounts-list-table .entity-list-row {
    position: relative;
    padding-right: 3.25rem;
  }

  .accounts-list-table .entity-list-identity {
    padding-bottom: 0;
  }

  /* Consistent identity alignment: a fixed-width marks column sized for
     the widest case (institution + card-network side by side), so the
     account name/secondary line/metadata all begin at the same x
     position whether a row has one mark or two, instead of shifting
     right when a network mark is also present. */
  .accounts-list-table .identity-marks {
    width: 4.25rem;
    justify-content: flex-start;
  }

  .accounts-list-table td.entity-list-meta.hidden {
    display: none !important;
  }

  .accounts-list-table .entity-list-value {
    margin-top: 0.45rem;
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
  }

  /* Balance hierarchy (spec ACC-LIST-003 mobile refinement): the label
     sits on its own line, more subdued than before, so the amount below
     it reads as clearly dominant rather than an inline "label value"
     pairing that echoes the removed table-style rows. */
  .accounts-list-table .entity-list-value .entity-list-field-label {
    display: block;
    margin-bottom: 0.2rem;
    font-weight: var(--fw-medium);
    min-width: 0;
  }

  /* A quieter, more clearly annotation-like "Calculated" note than a
     third stacked field. */
  .accounts-list-table .entity-list-value .financial-note {
    margin-top: 0.3rem;
    font-size: var(--fs-2xs);
  }

  .accounts-list-table .entity-list-actions {
    position: absolute;
    top: 0.85rem;
    right: 1rem;
    width: auto !important;
    padding: 0 !important;
    margin: 0;
    border-top: none;
  }

  .icon-action-btn {
    width: 2.5rem;
    height: 2.5rem;
  }

  /* The corner action's own tooltip would otherwise be clipped by the
     card's overflow; it is short text in practice ("Edit <name>") and
     reads fine left-aligned under the button on a narrow card. */
  .accounts-list-table .icon-action-btn__tooltip {
    right: 0;
    left: auto;
    max-width: min(14rem, calc(100vw - 4rem));
  }
}

@media (max-width: 1023px) {
  /* E12-04: Income mobile card mirrors the same approved Accounts & Cards
     corner-action mobile card (spec ACC-LIST-007) -- identity + amount on
     top, the pencil/eye action in the card's own corner, no full-width
     bottom action bar. Scoped to .income-list-table so every other entity
     list keeps today's shared behavior. Income has no identity marks
     column, so this is a smaller subset of the Accounts block above. */
  .income-list-table .entity-list-row {
    position: relative;
    padding-right: 3.25rem;
  }

  .income-list-table .entity-list-identity {
    padding-bottom: 0;
  }

  .income-list-table .entity-list-value {
    margin-top: 0.45rem;
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
  }

  .income-list-table .entity-list-value .entity-list-field-label {
    display: block;
    margin-bottom: 0.2rem;
    font-weight: var(--fw-medium);
    min-width: 0;
  }

  .income-list-table .entity-list-actions {
    position: absolute;
    top: 0.85rem;
    right: 1rem;
    width: auto !important;
    padding: 0 !important;
    margin: 0;
    border-top: none;
  }

.income-list-table .icon-action-btn__tooltip {
    right: 0;
    left: auto;
    max-width: min(14rem, calc(100vw - 4rem));
  }
}

@media (max-width: 1023px) {
  /* E12-04 Batch 1: Bills mobile card mirrors the same approved Accounts &
     Cards / Income corner-action mobile card (spec ACC-LIST-007) -- the
     action type itself (pencil/eye) was already correct; only its
     placement was wrong (full-width bottom action bar instead of the
     card's own corner). Scoped to .bills-data-table so every other entity
     list keeps today's shared bottom-action-row behavior. */
  .bills-data-table .entity-list-row {
    position: relative;
    padding-right: 3.25rem;
  }

  .bills-data-table .entity-list-identity {
    padding-bottom: 0;
  }

  .bills-data-table .entity-list-value {
    margin-top: 0.45rem;
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
  }

  .bills-data-table .entity-list-value .entity-list-field-label {
    display: block;
    margin-bottom: 0.2rem;
    font-weight: var(--fw-medium);
    min-width: 0;
  }

  .bills-data-table .entity-list-actions {
    position: absolute;
    top: 0.85rem;
    right: 1rem;
    width: auto !important;
    padding: 0 !important;
    margin: 0;
    border-top: none;
  }

  .bills-data-table .icon-action-btn__tooltip {
    right: 0;
    left: auto;
    max-width: min(14rem, calc(100vw - 4rem));
  }
}

/* E12-04 Income refinement: a compact, domain-scoped application of the
   Entity Management form primitives.  Income's type tiles and field
   composition remain domain presentation, not new Foundation APIs. */
.income-type-choices {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: 46rem;
  gap: 0.3rem;
}

.income-type-choices .account-type-choice__surface {
  height: 2.35rem;
  gap: 0.3rem;
  padding: 0.25rem 0.45rem;
  overflow: hidden;
}

.income-type-choices .account-type-choice__icon {
  width: 1.05rem;
  height: 1.05rem;
}

.income-type-choices .account-type-choice__label {
  font-size: 0.78rem;
  line-height: 1.1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.income-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.4rem 0.75rem;
  max-width: 54rem;
}

.income-form-grid > * { min-width: 0; }
.income-form-grid--owner { grid-template-columns: minmax(12rem, 0.75fr) minmax(15rem, 1fr); max-width: 42rem; }
.income-schedule-grid {
  display: grid;
  grid-template-columns: minmax(14rem, 1.15fr) minmax(14rem, 1fr) minmax(12rem, 0.85fr);
  align-items: start;
  gap: 0.4rem 0.75rem;
  max-width: 56rem;
}
.income-schedule-grid > * { min-width: 0; }
.income-amount-field { max-width: 21rem; }
.income-frequency-stack { display: grid; gap: 0.4rem; max-width: 18rem; }
.income-frequency-field { max-width: 18rem; }
.income-semi-monthly-field { max-width: 18rem; }
.income-date-field { max-width: 15rem; }
.income-employer-field { max-width: 32rem; margin-top: 0.4rem; }
.income-deposit-field { max-width: 34rem; }
.income-active-switch { margin-top: 0.4rem; }

.income-view-source-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.income-readonly-type__card {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 2rem;
  padding: 0.2rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  color: var(--text);
  font-weight: var(--fw-semibold);
}
.income-view-amount {
  border-color: var(--border);
  background: var(--surface-alt);
}
.income-view-amount dd { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }
.income-view-notes { background: transparent; }
.income-view-notes__empty { color: var(--text-muted) !important; font-weight: var(--fw-medium) !important; font-style: italic; }

/* Preserve the approved WealthCast performance legend ordering. */
.wealthcast-line-key { order: 2; }

@media (min-width: 1024px) {
  /* Source owns the remaining flexible table space. The other columns have
     stable, content-appropriate widths so Frequency does not create a dead
     gap before the financial value. Mobile cards do not use these widths. */
  .income-list-table { table-layout: fixed; }
  .income-list-table__frequency-column { width: 8rem; }
  .income-list-table__amount-column { width: 12rem; }
  .income-list-table__date-column { width: 10rem; }
  .income-list-table__action-column { width: var(--entity-row-actions-column); }
}

@media (max-width: 639px) {
  .income-type-choices {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    max-width: none;
  }
  .income-type-choices .account-type-choice__surface {
    height: 3.05rem;
    align-items: flex-start;
    padding: 0.32rem 0.35rem;
  }
  .income-type-choices .account-type-choice__icon { width: 0.9rem; height: 0.9rem; }
  .income-type-choices .account-type-choice__label {
    font-size: 0.7rem;
    line-height: 1.1;
    white-space: normal;
    text-overflow: clip;
  }
  .income-form-grid { grid-template-columns: minmax(0, 1fr); max-width: none; }
  .income-schedule-grid { grid-template-columns: minmax(0, 1fr); max-width: none; }
  .income-amount-field, .income-frequency-stack, .income-frequency-field, .income-semi-monthly-field,
  .income-date-field, .income-employer-field, .income-deposit-field { max-width: none; }
  .income-view-source-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 374px) {
  .income-type-choices { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .income-type-choices .account-type-choice__surface { height: 2.5rem; align-items: center; }
  .income-type-choices .account-type-choice__label { white-space: nowrap; font-size: 0.72rem; }
}

/* E12-04 Bills & Expenses refinement: the same compact Entity Management
   form primitives Income established, applied to Bills' own fields.
   Category is an intentional exception to the shared choice-tile pattern
   (Bills' 15-preset catalog is too large for tiles) -- a standard select,
   matching the same catalog-preset-select convention already used by
   Contributions/Investments (icon + label option text). */
.bill-category-field { max-width: 26rem; }

.bill-name-field { margin-top: 0.4rem; max-width: 34rem; }
.bill-name-field__row { display: flex; gap: 0.4rem; align-items: center; }
.bill-name-field__row .field-input { flex: 1; min-width: 0; }
.bill-name-suggest-button { flex: 0 0 auto; white-space: nowrap; }

.bill-owner-grid {
  display: grid;
  grid-template-columns: minmax(12rem, 0.75fr) minmax(15rem, 1fr);
  gap: 0.4rem 0.75rem;
  max-width: 42rem;
  margin-top: 0.4rem;
}
.bill-owner-grid > * { min-width: 0; }

.bill-schedule-grid {
  display: grid;
  grid-template-columns: minmax(14rem, 1.15fr) minmax(14rem, 1fr) minmax(12rem, 0.85fr);
  align-items: start;
  gap: 0.4rem 0.75rem;
  max-width: 56rem;
}
.bill-schedule-grid > * { min-width: 0; }
.bill-amount-field { max-width: 21rem; }
.bill-frequency-stack { display: grid; gap: 0.4rem; max-width: 18rem; }
.bill-frequency-field { max-width: 18rem; }
.bill-semi-monthly-field { max-width: 18rem; }
.bill-date-field { max-width: 15rem; }
.bill-payment-field { max-width: 34rem; }
.bill-active-switch { margin-top: 0.4rem; }

@media (max-width: 639px) {
  .bill-owner-grid { grid-template-columns: minmax(0, 1fr); max-width: none; }
  .bill-schedule-grid { grid-template-columns: minmax(0, 1fr); max-width: none; }
  .bill-amount-field, .bill-frequency-stack, .bill-frequency-field, .bill-semi-monthly-field,
  .bill-date-field, .bill-payment-field, .bill-name-field, .bill-category-field { max-width: none; }
}

/* E12-04 Contributions refinement: Investment Type keeps the shared
   choice-tile pattern (Income's precedent -- 7 presets, unlike Bills' 15,
   so tiles stay appropriate here); Institution stays the existing select
   (contract: "Institution remains editable", unchanged selector style).
   `.contribution-institution-grid` reuses `.bill-owner-grid`'s exact
   two-column shape for every Institution/Nickname/date field pair below. */
.contribution-type-other-field { max-width: 26rem; margin-top: 0.4rem; }

.contribution-institution-grid {
  display: grid;
  grid-template-columns: minmax(12rem, 0.75fr) minmax(15rem, 1fr);
  gap: 0.4rem 0.75rem;
  max-width: 42rem;
  margin-top: 0.4rem;
}
.contribution-institution-grid > * { min-width: 0; }

@media (max-width: 639px) {
  .contribution-type-other-field { max-width: none; }
  .contribution-institution-grid { grid-template-columns: minmax(0, 1fr); max-width: none; }
}

/* SMOKE-003: the shared entity-form grids above have hard column minimums,
   but their single-column fallback is a viewport breakpoint. At tablet
   widths (sidebar present) or under browser zoom the form card can be
   narrower than those minimums while the viewport is still "desktop", so
   fields spilled out of the card. Each grid now also collapses when the
   card itself is narrower than that grid's own minimum:
     three-column schedule grids: 14rem + 14rem + 12rem + 2 x 0.75rem gap = 41.5rem
     two-column owner/institution grids: 12rem + 15rem + 0.75rem gap = 27.75rem
   Fields keep their desktop max-widths here (only the phone rules above
   remove them). */
.entity-form-panel {
  container-type: inline-size;
  container-name: entity-form;
}

/* The standalone Quick Update panel is both an entity-form panel and the
   monthly-accounts container its card layout queries; keep both names so
   neither contract overrides the other. */
.entity-form-panel.monthly-accounts-layout {
  container-name: monthly-accounts entity-form;
}

@container entity-form (max-width: 41.5rem) {
  .income-schedule-grid,
  .bill-schedule-grid { grid-template-columns: minmax(0, 1fr); }
}

@container entity-form (max-width: 27.75rem) {
  .income-form-grid--owner,
  .bill-owner-grid,
  .contribution-institution-grid { grid-template-columns: minmax(0, 1fr); }
}

.is-updating {
  opacity: 0.72;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .btn.htmx-request,
  .is-updating,
  .global-loading-spinner {
    animation: none;
  }
}

/* T011 Checkpoint 3 — dashboard remaining surfaces and standalone auth */

.session-row {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 1rem;
}

.session-row[data-current-session] {
  border-color: var(--selected-line);
  background: var(--selected-tint);
}

.session-row-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.65rem;
}

.session-row-title {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

.session-meta {
  display: grid;
  gap: 0.35rem;
  font-size: var(--fs-base);
}

.session-meta div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}

.session-meta dt {
  color: var(--text-muted);
}

.session-meta dd {
  color: var(--text);
  text-align: right;
}

.session-ip-address {
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.btn-compact {
  min-height: 2.25rem;
  padding: 0.28rem 0.7rem;
  font-size: var(--fs-sm);
}

/* E7 shared "light confirm" -- a native <details> disclosure standing in
   for a raw browser confirm() on contained row/account actions. */
.light-confirm {
  position: relative;
  display: inline-block;
}

.light-confirm > summary {
  list-style: none;
  cursor: pointer;
}

.light-confirm > summary::-webkit-details-marker {
  display: none;
}

.light-confirm__panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 0.5rem);
  right: 0;
  width: 15.5rem;
  padding: 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: 0 0.75rem 1.75rem -1rem rgba(0, 0, 0, 0.3);
}

.light-confirm__panel p {
  margin: 0 0 0.6rem;
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--text-muted);
}

.light-confirm__actions {
  display: flex;
  gap: 0.4rem;
  justify-content: flex-end;
}

.mfa-qr-frame {
  display: inline-flex;
  padding: 0.65rem;
  margin-bottom: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: white;
}

.mfa-secret {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  overflow-wrap: anywhere;
}

.activity-table th,
.platform-table th {
  color: var(--text-muted);
  font-weight: var(--fw-semibold);
}

.platform-family-table {
  table-layout: fixed;
  width: 100%;
}

.platform-family-usage {
  padding: 0.6rem 1rem 0.75rem;
  border-bottom: 1px solid var(--border);
}

.platform-family-usage-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.45rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.platform-family-usage-list li {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  padding: 0.18rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: color-mix(in srgb, var(--text) 5%, var(--surface));
  color: var(--text-muted);
  font-size: 0.75rem;
  line-height: 1.3;
}

.platform-family-usage-count {
  font-weight: 650;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.platform-family-usage-empty {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.8125rem;
}

.platform-family-col-member {
  width: 20%;
}

.platform-family-col-email {
  width: 24%;
}

.platform-family-col-login {
  width: 13%;
}

.platform-family-col-access {
  width: 15%;
}

.platform-family-col-last-login {
  width: 16%;
}

.platform-family-col-actions {
  width: 12%;
}

.platform-family-table .platform-family-col-email {
  overflow-wrap: anywhere;
  word-break: break-word;
}

.platform-family-member-cell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
}

.platform-family-actions {
  min-height: 2.25rem;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

@media (max-width: 1023px) {
  .platform-family-card:has(.platform-family-table) {
    overflow: visible;
  }

  .platform-family-table {
    table-layout: auto;
  }

  .platform-family-table,
  .platform-family-table thead,
  .platform-family-table tbody,
  .platform-family-table tr,
  .platform-family-table th,
  .platform-family-table td,
  .platform-family-table colgroup,
  .platform-family-table col {
    display: block;
    width: 100%;
    max-width: 100%;
  }

  .platform-family-table thead,
  .platform-family-table colgroup {
    display: none;
  }

  .platform-family-table tbody tr {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    width: auto;
    margin: 0.75rem 1rem;
    padding: 0.85rem 1rem 1rem;
  }

  .platform-family-table tbody tr:first-child {
    margin-top: 0.75rem;
  }

  .platform-family-table tbody tr:last-child {
    margin-bottom: 0.75rem;
  }

  .platform-family-table td {
    border: 0;
    padding: 0.35rem 0;
    white-space: normal;
    text-align: left;
  }

  .platform-family-col-member,
  .platform-family-col-email,
  .platform-family-col-login,
  .platform-family-col-access,
  .platform-family-col-last-login,
  .platform-family-col-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.75rem;
    width: 100%;
  }

  .platform-family-col-member::before,
  .platform-family-col-email::before,
  .platform-family-col-login::before,
  .platform-family-col-access::before,
  .platform-family-col-last-login::before,
  .platform-family-col-actions::before {
    content: attr(data-label);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    min-width: 5.5rem;
  }

  .platform-family-col-actions {
    padding-top: 0.75rem;
    margin-top: 0.5rem;
    border-top: 1px solid var(--border);
    text-align: left;
  }

  .platform-family-actions {
    justify-content: flex-start;
    width: 100%;
  }
}

.platform-section-head {
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--border);
}

.platform-section-head h2 {
  margin: 0;
  color: var(--text);
  font-size: 1rem;
  font-weight: 650;
}

.platform-section-head p {
  margin: 0.25rem 0 0;
  color: var(--text-muted);
  font-size: 0.8125rem;
}

.destructive-panel {
  border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
}

.settings-page {
  max-width: 52rem;
}

.settings-page-header {
  margin-bottom: 1rem;
}

.settings-back {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-bottom: 0.65rem;
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  min-height: 2.5rem;
}

.settings-back:hover {
  color: var(--text);
}

.settings-back__icon {
  width: 1rem;
  height: 1rem;
}

.settings-title-category,
.settings-subtitle-category {
  display: none;
}

.settings-nav {
  display: none;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin: 0 0 1.25rem;
  padding: 0.2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
}

.settings-nav__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  padding: 0.4rem 0.85rem;
  border-radius: 0.375rem;
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
}

.settings-nav__link:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.settings-nav__link.is-current {
  color: var(--selected-ink);
  background: var(--selected-tint);
  box-shadow: inset 0 -2px 0 var(--selected-mark);
  font-weight: var(--fw-semibold);
}

.settings-landing {
  display: grid;
  gap: 0.5rem;
}

.settings-landing__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 3.25rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}

.settings-landing__item:hover {
  border-color: color-mix(in srgb, var(--text-muted) 28%, var(--border));
  background: var(--surface-hover);
}

.settings-landing__copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.15rem;
}

.settings-landing__title {
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-title);
}

.settings-landing__meta {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.settings-landing__chevron {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  color: var(--text-muted);
}

.settings-home-desktop {
  display: none;
}

.settings-group + .settings-group {
  margin-top: 1.75rem;
}

.settings-group__intro {
  margin-bottom: 0.75rem;
}

.settings-group__title {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-title);
}

.settings-group__copy,
.settings-help {
  margin: 0.25rem 0 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* E12-04-REVFIX-001: honour the `hidden` attribute that auto-save sets on
   the fallback submit button once it has taken over the form. `.btn` sets
   `display: inline-flex`, and an author-level `display` always beats the
   UA stylesheet's `[hidden] { display: none }` -- so without this rule the
   button stayed visible even though `element.hidden` was correctly true.
   Deliberately scoped to the attribute JS sets (not an unconditional
   hide), so with JS off or auto-save unavailable the button never gets
   `hidden` and stays visible/usable. Same pattern already used for
   `[data-brand-preview-img][hidden]` and the timezone option list. */
[data-settings-autosave-fallback-submit][hidden] {
  display: none;
}

/* E12-04: one subtle, consistent auto-save status line for Appearance/
   Family/Notifications. Reserves its own line height even when empty so
   filling it in (or clearing it) never shifts the layout around it. */
.settings-autosave-status {
  min-height: 1.2rem;
  margin: 0.75rem 0 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.settings-autosave-status[data-state="saved"] {
  color: var(--success);
}

.settings-autosave-status[data-state="error"] {
  color: var(--danger);
}

/* E12-MCS-011: the same status line inside MonthCast, where it sits beside
   the fallback Save button rather than under a settings card. */
.monthcast-autosave {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.monthcast-autosave__status {
  margin: 0;
}

.settings-card-title {
  margin: 0 0 0.25rem;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-title);
}

.settings-stack {
  display: grid;
  gap: 0.75rem;
}

.settings-field-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

.settings-readonly-list {
  display: grid;
  gap: 0.75rem;
}

.settings-email-value {
  overflow-wrap: anywhere;
}

.settings-appearance-panel {
  max-width: 34rem;
}

/* E11-NEXTFIX-001: visual, whole-card-clickable Theme selector. Native
   radio inputs (visually hidden, not display:none so they stay
   focusable) drive the checked state -- Tab/Arrow-key/Space work for
   free, and `:checked` on the input is exposed to assistive tech
   without any custom ARIA. */
.theme-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.theme-picker__option {
  display: block;
  cursor: pointer;
}

.theme-picker__input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.theme-picker__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem;
  border: 2px solid var(--border);
  border-radius: 0.75rem;
  background: var(--surface);
  position: relative;
}

.theme-picker__input:focus-visible + .theme-picker__card {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.theme-picker__input:checked + .theme-picker__card {
  border-color: var(--action-primary);
  box-shadow: 0 0 0 1px var(--action-primary);
}

.theme-picker__preview {
  width: 100%;
  height: 3.5rem;
  border-radius: 0.5rem;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  border: 1px solid var(--border);
}

.theme-picker__preview-bar {
  height: 0.4rem;
  width: 60%;
  border-radius: 999px;
}

.theme-picker__preview-line {
  height: 0.28rem;
  width: 90%;
  border-radius: 999px;
}

.theme-picker__preview-line--short {
  width: 55%;
}

.theme-picker__preview-accent {
  margin-top: auto;
  height: 0.3rem;
  width: 35%;
  border-radius: 999px;
  background: var(--brand-orange);
}

.theme-picker__card--light .theme-picker__preview {
  background: #ffffff;
}

.theme-picker__card--light .theme-picker__preview-bar,
.theme-picker__card--light .theme-picker__preview-line {
  background: #cfd3da;
}

.theme-picker__card--dark .theme-picker__preview {
  background: #17191d;
  border-color: #2a2d33;
}

.theme-picker__card--dark .theme-picker__preview-bar,
.theme-picker__card--dark .theme-picker__preview-line {
  background: #494f59;
}

.theme-picker__card--system .theme-picker__preview {
  background: linear-gradient(to right, #ffffff 50%, #17191d 50%);
  border-color: var(--border);
}

.theme-picker__card--system .theme-picker__preview-bar,
.theme-picker__card--system .theme-picker__preview-line {
  background: linear-gradient(to right, #cfd3da 50%, #494f59 50%);
}

.theme-picker__check {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 999px;
  border: 2px solid var(--border);
  background: var(--surface);
}

.theme-picker__input:checked + .theme-picker__card .theme-picker__check {
  border-color: var(--action-primary);
  background: var(--action-primary);
  box-shadow: inset 0 0 0 2px var(--surface);
}

.theme-picker__label {
  font-size: 0.8125rem;
  font-weight: 650;
  color: var(--text);
}

/* E11-NEXTFIX-008: Date format / Number & currency format visual card
   pickers -- same whole-card-clickable native-radio pattern as the
   Theme picker above. Equal card heights, neutral unselected state,
   a subtle blue selected background/border (design tokens, so Dark
   Mode is automatic), and an orange selected indicator dot. */
.format-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.format-picker__option {
  display: block;
  cursor: pointer;
  height: 100%;
}

.format-picker__input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.format-picker__card {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.25rem;
  height: 100%;
  min-height: 3.5rem;
  padding: 0.75rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  background: var(--surface);
  position: relative;
  text-align: center;
}

.format-picker__input:focus-visible + .format-picker__card {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.format-picker__input:checked + .format-picker__card {
  border-color: var(--action-primary);
  background: color-mix(in srgb, var(--action-primary) 8%, var(--surface));
}

.format-picker__check {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 999px;
  border: 2px solid var(--border);
  background: var(--surface);
}

.format-picker__input:checked + .format-picker__card .format-picker__check {
  border-color: var(--action-primary);
  background: var(--action-primary);
  box-shadow: inset 0 0 0 2px var(--surface);
}

.format-picker__example {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.format-picker__pattern {
  font-size: 0.6875rem;
  color: var(--text-muted);
}

/* E11-NEXTFIX-007: shared confirmation modal (User App + Admin Panel).
   Native <dialog> -- ::backdrop is the browser's own overlay, sized/
   positioned by the UA; only the panel itself needs styling. Balanced
   width on Desktop, near-full-width with margins on Mobile. */
.confirm-modal {
  border: none;
  border-radius: 0.9rem;
  padding: 0;
  width: calc(100% - 2.5rem);
  max-width: 26rem;
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 20px 50px rgba(17, 19, 23, 0.25);
}

.confirm-modal::backdrop {
  background: rgba(15, 17, 21, 0.5);
}

.confirm-modal__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.25rem 1.25rem 1.1rem;
}

.confirm-modal__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  letter-spacing: var(--tracking-title);
}

.confirm-modal__message {
  margin: 0;
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--text-muted);
}

/* E12-MCS: the same shared dialog, able to carry one read-only figure the
   decision turns on (Projected Leftover, Current Amount) and one editable
   value when the action needs a number (Override). Everything else -- the
   title, the message, Cancel, the tone-coloured primary action -- is
   unchanged, and a confirmation that asks for neither shows neither.

   `[hidden]` is spelled out on both, because the `display` below would
   otherwise override the attribute's own `display: none` and show an empty
   block -- and, for the field, an empty required-looking box -- on every
   ordinary confirmation. */
.confirm-modal__detail[hidden],
.confirm-modal__field[hidden],
.confirm-modal__warning[hidden],
.confirm-modal__phrase[hidden] {
  display: none;
}

/* DATA-01: two more extras for a materially more destructive confirmation
   (a One-Time Money item whose repayment history is deleted with it), each
   hidden unless the form asks for it: one stronger statement set apart
   from the message -- the danger semantic pair, as an error flash uses --
   and a word the user must type before the action is offered. The typed
   field is the ordinary form field and label; the action stays the
   tone-coloured button, unavailable until the word matches. */
.confirm-modal__warning {
  margin: 0.35rem 0 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--danger) 35%, var(--border));
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.45;
}

.confirm-modal__phrase {
  display: grid;
  gap: 0.3rem;
  margin-top: 0.5rem;
}

.confirm-modal__phrase code {
  color: var(--text);
  font-weight: var(--fw-semibold);
}

/* An unavailable action shows the shared disabled treatment and nothing
   else: no hover darkening that would make it look live. */
.confirm-modal__confirm:disabled {
  pointer-events: none;
}

.confirm-modal__detail {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.85rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.confirm-modal__detail-value {
  color: var(--text);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

.confirm-modal__field {
  display: grid;
  gap: 0.3rem;
  margin-top: 0.85rem;
}

/* E12-06 UI-01: the dialog's money row is the shared Quick Update money
   field (marker + right-aligned tabular input + inline error), sized for
   the dialog rather than a table cell. */
.confirm-modal__money {
  max-width: none;
}

.confirm-modal__field-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.confirm-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 0.75rem;
}

/* Cancel and Confirm share the base .btn box model exactly (height,
   padding, radius, typography, alignment) -- only color/tone differs,
   per NEXTFIX-007's explicit requirement. */
.confirm-modal__cancel,
.confirm-modal__confirm {
  min-height: 2.75rem;
  padding: 0.55rem 1.15rem;
}

.confirm-modal__confirm--danger {
  background-color: var(--danger);
  color: white;
  border-color: var(--danger);
}

.confirm-modal__confirm--danger:hover {
  background-color: color-mix(in srgb, var(--danger) 85%, black);
}

.confirm-modal__confirm--warning {
  background-color: var(--warning-strong);
  color: white;
  border-color: var(--warning-strong);
}

.confirm-modal__confirm--warning:hover {
  background-color: color-mix(in srgb, var(--warning-strong) 85%, black);
}

.confirm-modal__confirm--success {
  background-color: var(--success);
  color: white;
  border-color: var(--success);
}

.confirm-modal__confirm--success:hover {
  background-color: color-mix(in srgb, var(--success) 85%, black);
}

@media (max-width: 480px) {
  .confirm-modal {
    width: calc(100% - 1.5rem);
  }

  .confirm-modal__actions {
    flex-direction: column-reverse;
  }

  .confirm-modal__cancel,
  .confirm-modal__confirm {
    width: 100%;
  }
}

@media (min-width: 768px) {
  .settings-back {
    display: none;
  }

  .settings-title-category,
  .settings-subtitle-category {
    display: none;
  }

  /* E12-04: .settings-title-root now always carries the Page Title icon
     modifier (display: flex) -- kept separate from .settings-subtitle-root
     so this rule cannot re-assert display: block and silently drop the
     icon's flex alignment at this breakpoint. */
  .settings-title-root {
    display: flex;
  }

  .settings-subtitle-root {
    display: block;
  }

  .settings-nav {
    display: flex;
  }

  .settings-landing {
    display: none;
  }

  .settings-home-desktop {
    display: block;
  }

  .settings-field-grid {
    grid-template-columns: 1fr 1fr;
  }

  .settings-stack {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 767px) {
  .settings-page:not([data-settings-category="home"]) .settings-title-root,
  .settings-page:not([data-settings-category="home"]) .settings-subtitle-root {
    display: none;
  }

  .settings-page:not([data-settings-category="home"]) .settings-title-category,
  .settings-page:not([data-settings-category="home"]) .settings-subtitle-category {
    display: block;
  }
}

@media (max-width: 480px) {
  .spendable-forecast-range-btn {
    min-height: 2.75rem;
  }

  /* Phones: month, amount, and Surplus/Shortfall share one reserved line so
     the neutral state leaves no tall blank band. The chart's slider value
     text still announces the full inspected month. */
  .spendable-forecast-selected {
    flex-wrap: nowrap;
  }

  .spendable-forecast-selected-caption {
    display: none;
  }

  /* Phones: keep the range buttons beside the title (the helper wraps
     instead) and tighten the gaps above the chart. Tap targets and the
     reserved readout line are unchanged. */
  .spendable-forecast-timeline-header {
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: 0.5rem;
  }

  .spendable-forecast-timeline-header > :first-child {
    min-width: 0;
  }

  .spendable-forecast-timeline-helper {
    text-wrap: balance;
  }

  .spendable-forecast-range {
    flex-shrink: 0;
    flex-wrap: nowrap;
    gap: 0.25rem;
  }

  .spendable-forecast-selected {
    margin-top: 0.4rem;
  }

  .spendable-forecast-chart-wrap {
    margin-top: 0.2rem;
  }
}

/* Admin App authenticated header navigation (E4). Scoped to [data-admin-shell]
   (admin/_base.html's <body>) only; reuses existing tokens (--radius-sm,
   --surface-hover) rather than introducing a second nav-item component. */
[data-admin-shell] .admin-nav-link {
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 600;
}

[data-admin-shell] .admin-nav-link:hover,
[data-admin-shell] .admin-nav-link:focus-visible {
  background: var(--surface-hover);
}

/* E6 subscriptions: Admin read-first information architecture. */
.admin-subscriptions-shell { display: grid; grid-template-columns: minmax(11rem, 13rem) minmax(0, 1fr); gap: 1.5rem; }
.admin-subscriptions-nav { align-self: start; display: grid; gap: 0.25rem; padding: 0.35rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-alt); }
.admin-subscriptions-nav__link, .admin-subscriptions-mobile-nav__link { display: block; min-height: 2.5rem; padding: 0.6rem 0.75rem; border-radius: 0.375rem; color: var(--text-muted); font-size: 0.875rem; font-weight: 650; }
.admin-subscriptions-nav__link:hover, .admin-subscriptions-mobile-nav__link:hover { color: var(--text); background: var(--surface-hover); }
.admin-subscriptions-nav__link.is-current, .admin-subscriptions-mobile-nav__link.is-current { color: var(--action-primary); background: var(--surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--action-primary) 28%, var(--border)); }
.admin-subscriptions-mobile-nav { display: none; }
.admin-subscription-search { max-width: 38rem; margin: 1rem 0; }
.admin-subscription-search__controls { display: flex; gap: 0.5rem; }
.admin-subscription-search__controls .field-input { min-width: 0; flex: 1; }
.admin-subscription-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.admin-subscription-table { width: 100%; min-width: 51rem; border-collapse: collapse; }
.admin-subscription-table th, .admin-subscription-table td { padding: 0.8rem 0.9rem; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; }
.admin-subscription-table th { color: var(--text-muted); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; }
.admin-subscription-table tr:last-child td { border-bottom: 0; }
/* E12-05-022: a row's action stays one control on one line; the table's
   own wrapper scrolls sideways at narrow widths instead. */
.admin-subscription-table .btn { white-space: nowrap; }
.admin-subscription-card-list { display: none; gap: 0.75rem; }
.admin-subscription-card, .admin-subscription-manage__section { padding: 1rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.admin-subscription-card__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.admin-subscription-card h3, .admin-subscription-manage__section h3 { margin: 0; color: var(--text); font-size: 1rem; font-weight: 650; }
.admin-subscription-card__meta { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; margin: 1rem 0; }
.admin-subscription-card__meta dt { color: var(--text-muted); font-size: 0.75rem; font-weight: 650; }
.admin-subscription-card__meta dd { margin: 0.15rem 0 0; overflow-wrap: anywhere; }
.admin-subscription-manage { display: grid; gap: 1rem; }
.admin-subscription-targets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; margin-top: 0.75rem; }
.admin-subscription-target { display: flex; align-items: flex-start; gap: 0.6rem; min-height: 4.5rem; padding: 0.8rem; border: 1px solid var(--border); border-radius: 0.5rem; cursor: pointer; }
.admin-subscription-target span, .admin-subscription-target small { display: block; }
.admin-subscription-target small, .admin-subscription-selector__row small { margin-top: 0.2rem; color: var(--text-muted); font-size: 0.8125rem; }
.admin-subscription-selector { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; max-height: 19rem; margin-top: 0.85rem; overflow: auto; }
.admin-subscription-selector__row { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 0.55rem; padding: 0.7rem; border: 1px solid var(--border); border-radius: 0.5rem; }
.admin-subscription-selector__row small { grid-column: 2; overflow-wrap: anywhere; }
.admin-subscription-form-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; margin-top: 0.75rem; }
.admin-subscription-form-grid__wide { grid-column: 1 / -1; }
.admin-subscription-manage__actions { display: flex; justify-content: flex-end; }
.admin-subscription-detail-history-cards { display: none; }
.admin-subscription-confirm-cards { display: none; gap: 0.75rem; margin-top: 1rem; }
.admin-subscription-family-picker { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(16rem, 0.8fr); gap: 1rem; margin-top: 1rem; }
.admin-subscription-search-results, .admin-subscription-selected-families { min-height: 8rem; margin-top: 0.5rem; padding: 0.5rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.admin-subscription-search-results { max-height: 19rem; overflow-y: auto; }
.admin-subscription-search-result, .admin-subscription-selected-family { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.55rem; align-items: center; padding: 0.65rem; border-radius: 0.45rem; }
.admin-subscription-search-result:hover { background: var(--surface-hover); }
.admin-subscription-search-result small, .admin-subscription-selected-family small { display: block; color: var(--text-muted); overflow-wrap: anywhere; }
.admin-subscription-selected-families { display: grid; align-content: start; gap: 0.35rem; }
.admin-subscription-selected-families__heading { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; padding: 0.1rem 0.1rem 0.35rem; border-bottom: 1px solid var(--border); }
.admin-subscription-selected-families__heading h3 { margin: 0; font-size: 0.9rem; }
.admin-subscription-selected-family { grid-template-columns: minmax(0, 1fr) auto; border: 1px solid color-mix(in srgb, var(--action-primary) 18%, var(--border)); background: color-mix(in srgb, var(--action-primary) 5%, var(--surface)); }
.admin-subscription-selected-family button { color: var(--text-muted); }
.admin-subscription-family-picker.is-disabled { opacity: 0.55; }
.admin-subscription-family-picker.is-disabled .admin-subscription-search-results, .admin-subscription-family-picker.is-disabled .admin-subscription-selected-families { background: var(--surface-alt); }
.admin-subscription-change-choice { grid-column: 1 / -1; min-width: 0; border: 0; padding: 0; }
.admin-subscription-change-choice__options { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.admin-subscription-change-option { display: grid; grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: 0.75rem; min-height: 4.5rem; padding: 0.8rem; border: 1px solid var(--border); border-radius: var(--radius-md); cursor: pointer; }
.admin-subscription-change-option strong, .admin-subscription-change-option small { display: block; }
.admin-subscription-change-option small { margin-top: 0.15rem; color: var(--text-muted); font-size: 0.8125rem; }
.admin-subscription-change-option__icon { display: grid; width: 2.25rem; height: 2.25rem; place-items: center; border-radius: 999px; color: white; font-size: 1.35rem; font-weight: 750; }
.admin-subscription-change-option--increase .admin-subscription-change-option__icon { background: #168a5b; }
.admin-subscription-change-option--decrease .admin-subscription-change-option__icon { background: var(--danger); }
.admin-subscription-change-option--increase:has(input:checked) { border-color: #168a5b; background: color-mix(in srgb, #168a5b 8%, var(--surface)); }
.admin-subscription-change-option--decrease:has(input:checked) { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 6%, var(--surface)); }
.admin-subscription-notification-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 0.85rem; }
.admin-subscription-notification-fields.is-disabled { opacity: 0.55; }
.admin-subscription-directory-filters { margin: 1rem 0; padding: 1rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.admin-subscription-directory-filters .admin-subscription-search__controls { display: grid; grid-template-columns: minmax(14rem, 1.5fr) repeat(2, minmax(9rem, 1fr)) auto; align-items: end; }
.admin-subscription-directory-summary, .admin-subscription-pagination { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin: 1rem 0; }
.admin-subscription-directory-summary h2 { margin: 0; font-size: 1.05rem; }
.admin-subscription-directory-summary p { margin: 0; color: var(--text-muted); font-size: 0.875rem; }
.admin-subscription-pagination { justify-content: flex-end; }
.admin-subscription-family-picker__search, .admin-subscription-selected-families { min-height: 14rem; margin-top: 0; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.admin-subscription-family-picker__search .admin-subscription-search-results { min-height: 0; margin-top: 0.5rem; padding: 0; border: 0; border-radius: 0; }

.admin-subscription-sort-link { display: inline-flex; align-items: center; gap: 0.25rem; color: inherit; text-decoration: none; }
.admin-subscription-sort-link:hover { text-decoration: underline; }
.admin-subscription-sort-link.is-active { color: var(--text); }
.admin-subscription-mobile-sort { display: none; }
.admin-invite-form { max-width: 40rem; }

/* E7-SMOKE-UX-31/32: Communications entity pickers (Selected Users /
   Selected Families) -- a searchable checkbox multi-select with a
   removable "chip" list, replacing raw line-by-line email/name typing as
   the primary interaction. */
/* E7-SMOKE-UX-31A: search+results (left) and selected entities (right) as
   a balanced two-column row on desktop -- the same layout ratio already
   proven for the Manage Subscriptions family picker
   (.admin-subscription-family-picker) -- instead of consuming the page
   vertically. Both sides get a bounded, scrollable height so a long
   result/selection list stays usable rather than growing the page. */
.admin-entity-picker { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(16rem, 0.8fr); gap: 1rem; max-width: 50rem; }
.admin-entity-picker__results, .admin-entity-picker__selected { min-height: 6rem; margin-top: 0.5rem; padding: 0.5rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.admin-entity-picker__results, .admin-entity-picker__selected [data-entity-selected-list] { max-height: 20rem; overflow-y: auto; }
.admin-entity-picker__result, .admin-entity-picker__chip { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.55rem; align-items: center; padding: 0.65rem; border-radius: 0.45rem; }
.admin-entity-picker__result { grid-template-columns: auto minmax(0, 1fr); cursor: pointer; }
.admin-entity-picker__result:hover { background: var(--surface-hover); }
.admin-entity-picker__result small, .admin-entity-picker__chip small { display: block; color: var(--text-muted); overflow-wrap: anywhere; }
.admin-entity-picker__chip { grid-template-columns: minmax(0, 1fr) auto; border: 1px solid color-mix(in srgb, var(--action-primary) 18%, var(--border)); background: color-mix(in srgb, var(--action-primary) 5%, var(--surface)); margin-bottom: 0.35rem; }
.admin-entity-picker__chip button { color: var(--text-muted); }
.admin-entity-picker__selected { display: grid; align-content: start; gap: 0.35rem; }
.admin-entity-picker__selected-heading { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.admin-entity-picker__selected-heading h3 { font-size: 0.8125rem; font-weight: 650; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.02em; }

@media (max-width: 767px) {
  .admin-entity-picker { max-width: 100%; grid-template-columns: 1fr; }
}

/* E7-SMOKE-UX-35 (composer follow-up): the Send Announcement compose
   editor is a live contenteditable -- unsanitized until submit -- so the
   sanitizer's own trusted-signature-URL size bound never applies to what
   the Admin sees while composing. Scoped to the one class the Signature
   toolbar button itself applies to its own inserted <img>, inside the
   compose editor only: this never affects any other image (an Admin
   pasting one manually gets none of this styling), and the class does
   not survive sanitize_announcement_html (img allows only src/alt), so
   it has no bearing on the sent/reviewed HTML -- that is bounded
   separately, server-side, by exact URL match. */
#announce-body-editable .announce-signature-logo {
  max-width: 150px;
  height: auto;
}

@media (max-width: 767px) {
  .admin-subscriptions-shell { display: block; }
  .admin-subscriptions-nav { display: none; }
  .admin-subscriptions-mobile-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 0.25rem; margin: 0 0 1rem; padding: 0.25rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-alt); }
  .admin-subscriptions-mobile-nav__link { text-align: center; font-size: 0.8125rem; }
  .admin-subscription-table-wrap, .admin-subscription-detail-history-table, .admin-subscription-confirm-table { display: none; }
  .admin-subscription-card-list, .admin-subscription-detail-history-cards, .admin-subscription-confirm-cards { display: grid; }
  .admin-subscription-search__controls { flex-wrap: wrap; }
  .admin-subscription-directory-filters .admin-subscription-search__controls { display: grid; grid-template-columns: 1fr; }
  .admin-subscription-directory-summary, .admin-subscription-pagination { align-items: flex-start; flex-direction: column; }
  .admin-subscription-search__controls .field-input { width: 100%; flex-basis: 100%; }
  .admin-subscription-targets, .admin-subscription-selector, .admin-subscription-form-grid, .admin-subscription-family-picker, .admin-subscription-notification-fields, .admin-subscription-change-choice__options { grid-template-columns: 1fr; }
  .admin-subscription-selector { max-height: none; }
  .admin-subscription-manage__actions { justify-content: stretch; }
  .admin-subscription-manage__actions .btn { width: 100%; }
  .admin-subscription-mobile-sort { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-top: 0.5rem; }
  .admin-subscription-mobile-sort .field-label { grid-column: 1 / -1; }
  .admin-invite-form { flex-direction: column; align-items: stretch; }
  .admin-invite-form__submit { width: 100%; }

  /* Bound Available Families to roughly 3-4 visible rows before
     scrolling, instead of consuming most of the viewport. */
  .admin-subscription-family-picker__search .admin-subscription-search-results {
    max-height: 11rem;
    overflow-y: auto;
  }

  /* An empty Selected Families panel stays compact; a populated one
     scrolls internally past a sensible height rather than growing
     unbounded down the page. */
  .admin-subscription-selected-families {
    min-height: 0;
  }
  .admin-subscription-selected-families:not(.is-empty) [data-selected-family-list] {
    max-height: 11rem;
    overflow-y: auto;
  }
}

/* ---------------------------------------------------------------------- */
/* E8 Analytics Refinement: chart primitives (hand-rolled inline SVG line  */
/* charts, CSS composition/grouped bars -- no charting library, same      */
/* architecture as the Dashboard Spendable Forecast Timeline).            */
/* ---------------------------------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.analytics-chart-wrap {
  width: 100%;
}

.analytics-line-chart {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 640 / 280;
  max-height: 340px;
}

.analytics-comparison {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  font-size: 0.75rem;
  margin-top: 0.25rem;
  flex-wrap: wrap;
}

.analytics-comparison-arrow {
  font-weight: 700;
}

.analytics-comparison-pct {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.analytics-comparison-caption {
  color: var(--text-muted);
}

.analytics-comparison--positive .analytics-comparison-arrow,
.analytics-comparison--positive .analytics-comparison-pct {
  color: var(--success);
}

.analytics-comparison--negative .analytics-comparison-arrow,
.analytics-comparison--negative .analytics-comparison-pct {
  color: var(--danger);
}

.analytics-comparison--neutral .analytics-comparison-arrow,
.analytics-comparison--neutral .analytics-comparison-pct {
  color: var(--text-muted);
}

.analytics-comparison-badge {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
  font-weight: 700;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.analytics-chart-gridline {
  stroke: var(--border);
  stroke-width: 1;
}

/* E11-SMOKE-007: a clear zero baseline when a chart's data spans
   negative and positive values (e.g. YTD Performance). */
.analytics-chart-gridline--zero {
  stroke: var(--text-muted);
  stroke-width: 1.5;
}

.analytics-chart-axis-label {
  font-size: 9px;
  fill: var(--text-muted);
}

.analytics-chart-axis-label--x {
  text-anchor: middle;
}

/* E12-06 F030: the chart scales down with the phone, and its labels with
   it (9 user units is ~5px on screen at 390px). The Performance History
   labels grow in user units as the chart narrows so years and % stay
   legible (~10-11px rendered). */
@media (max-width: 640px) {
  .wealthcast-performance-chart .analytics-chart-axis-label {
    font-size: 15px;
  }
}

@media (max-width: 480px) {
  .wealthcast-performance-chart .analytics-chart-axis-label {
    font-size: 19px;
  }
}

.analytics-chart-line {
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}

.analytics-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.analytics-chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.analytics-chart-legend-swatch,
.analytics-composition-legend-swatch {
  display: inline-block;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 2px;
  flex-shrink: 0;
}

.analytics-chart-data-details {
  margin-top: 0.5rem;
}

.analytics-chart-data-details summary {
  cursor: pointer;
  font-size: 0.75rem;
  color: var(--action-primary);
  font-weight: 600;
}

.analytics-chart-data-table-wrap {
  overflow-x: auto;
  margin-top: 0.5rem;
}

.analytics-chart-data-table {
  border-collapse: collapse;
  font-size: 0.75rem;
  white-space: nowrap;
}

.analytics-chart-data-table th,
.analytics-chart-data-table td {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.analytics-chart-data-table th[scope="row"] {
  text-align: left;
  color: var(--text);
  font-weight: 600;
}

.analytics-chart-empty {
  font-size: 0.8125rem;
  color: var(--text-muted);
  padding: 1.5rem 0;
  text-align: center;
}

.analytics-composition-bar {
  display: flex;
  width: 100%;
  height: 1.5rem;
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface-alt);
}

.analytics-composition-bar__segment {
  height: 100%;
  transition: width 0.2s ease;
}

.analytics-composition-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 0.75rem;
}

.analytics-composition-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  color: var(--text);
}

.analytics-composition-legend-pct {
  color: var(--text-muted);
}

.analytics-grouped-bar-chart {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}

.analytics-grouped-bar-chart__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 0.25rem;
}

.analytics-grouped-bar-row {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.analytics-grouped-bar-row__label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
}

.analytics-grouped-bar-row__bars {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.analytics-grouped-bar-track {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.analytics-grouped-bar-track-rail {
  position: relative;
  flex: 1 1 auto;
  height: 1.125rem;
  background: var(--surface-alt);
  border-radius: 4px;
  min-width: 3rem;
}

.analytics-grouped-bar-fill {
  height: 100%;
  border-radius: 4px;
  min-width: 2px;
}

.analytics-grouped-bar-value {
  flex: 0 0 auto;
  min-width: 2.25rem;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------- */
/* Visual Remediation: interactive chart legend toggles, redesigned Date  */
/* Range control, compact Family lifecycle explainer.                    */
/* ---------------------------------------------------------------------- */

.analytics-chart-legend--interactive {
  margin-bottom: 0.5rem;
}

.analytics-chart-legend-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.25rem 0.625rem;
  cursor: pointer;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}

.analytics-chart-legend-toggle:hover {
  background: var(--surface-hover);
}

.analytics-chart-legend-toggle:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.analytics-chart-legend-toggle[aria-pressed="false"] {
  opacity: 0.55;
}

.analytics-chart-legend-toggle[aria-pressed="false"] .analytics-chart-legend-swatch {
  background: transparent !important;
  border: 1.5px solid var(--text-muted);
}

.analytics-chart-legend-toggle[aria-pressed="false"]::after {
  content: " (hidden)";
  color: var(--text-muted);
}

/* E11-NEXTFIX-015: WealthCast Dashboard's three-view tab bar -- plain
   links (real navigation, so Back/Forward and deep links just work),
   styled as a touch-friendly segmented control consistent with the
   Period/Group By segmented buttons below. */
.dashboard-view-tabs {
  position: sticky;
  top: var(--app-sticky-offset);
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1rem;
  background: var(--app-bg);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.6rem;
  box-shadow: 0 1px 0 color-mix(in srgb, var(--border) 72%, transparent);
}

/* Shared compact Dashboard rhythm: title, view navigation, then content. */
.dashboard-page-header {
  margin-bottom: 0.75rem;
}

.dashboard-view-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.75rem;
  padding: 0.5rem 0.9rem;
  border-radius: 0.6rem;
  border: 1px solid transparent;
  color: var(--text-muted);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  text-decoration: none;
  position: relative;
}

.dashboard-view-tab:hover {
  background: var(--surface-hover);
  color: var(--text);
}

.dashboard-view-tab__icon {
  width: 1.1rem;
  height: 1.1rem;
}

.dashboard-view-tab[aria-current="page"] {
  border-color: transparent;
  background: var(--selected-tint);
  color: var(--selected-ink);
  font-weight: var(--fw-semibold);
}

/* E12-05 selected-view recipe: the Orange position mark is a short bar on
   the tab's bottom edge plus the tab icon -- never Orange text. */
.dashboard-view-tab[aria-current="page"]::after {
  position: absolute;
  right: 0.8rem;
  bottom: 0.2rem;
  left: 0.8rem;
  height: 2px;
  border-radius: 2px;
  background: var(--selected-mark);
  content: "";
}

.dashboard-view-tab[aria-current="page"] .dashboard-view-tab__icon {
  color: var(--selected-mark);
}

@media (max-width: 640px) {
  /* E12-05-030: a little less space between the title, the view tabs and
     the content on a phone (the tabs keep their 2.75rem touch height). */
  .dashboard-page-header {
    margin-bottom: 0.5rem;
  }

  .dashboard-view-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.2rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.4rem;
  }

  .dashboard-view-tabs--two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .dashboard-view-tab {
    justify-content: center;
    padding: 0.45rem 0.2rem;
    font-size: var(--fs-xs);
    text-align: center;
    line-height: 1.25;
    gap: 0.2rem;
  }
  .dashboard-view-tab__icon { width: 0.9rem; height: 0.9rem; flex-shrink: 0; }
  .theme-picker, .format-picker { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.35rem; }
  .theme-picker__card { padding: 0.55rem 0.3rem; }
  .theme-picker__preview { height: 2.75rem; }
  .format-picker__card { padding: 1.15rem 0.2rem 0.5rem; }
  .format-picker__example { font-size: var(--fs-xs); overflow-wrap: anywhere; }
  .format-picker__pattern { font-size: 0.6rem; }
}
@media (max-width: 340px) { .format-picker { grid-template-columns: 1fr; } }

.timezone-picker { position: relative; }
.timezone-picker__options { position: absolute; top: 100%; width: 100%; max-height: 15rem; overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); z-index: 30; box-shadow: var(--shadow-menu); }
.timezone-picker__options button { display: block; width: 100%; min-height: 2.75rem; padding: 0.6rem; text-align: left; background: var(--surface); color: var(--text); border: 0; }
.timezone-picker__options button[hidden] { display: none; }
.timezone-picker__options button:hover, .timezone-picker__options button[aria-selected="true"] { background: var(--surface-hover); }

/* E11-NEXTFIX-005: graphical Group By selector -- same segmented-button
   visual language as .spendable-forecast-range-btn (Period, right next
   to it) so the two controls read as one consistent family, just with
   an icon added before the label. */
.value-history-groupby {
  display: inline-flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.value-history-groupby-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2.75rem;
  padding: 0.4rem 0.75rem;
  border-radius: 0.55rem;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}

.value-history-groupby-btn__icon {
  width: 1rem;
  height: 1rem;
}

.value-history-groupby-btn[aria-pressed="true"] {
  border-color: var(--selected-line);
  background: var(--selected-tint);
  color: var(--selected-ink);
  font-weight: var(--fw-semibold);
}

.value-history-groupby-btn[aria-pressed="true"] .value-history-groupby-btn__icon {
  color: var(--selected-mark);
}

/* E11-SMOKE-004: many-series (above the precompute-safe toggle cap)
   selection picker -- same legend/swatch visual language as the
   interactive toggle buttons above, wrapped in a compact scrollable
   panel so a large ACCOUNT-grouped portfolio stays usable rather than
   pushing the chart far down the page. */
.value-history-series-picker {
  max-height: 8.5rem;
  overflow-y: auto;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-alt);
}

.value-history-series-option {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: var(--fs-xs);
  color: var(--text);
  cursor: pointer;
}

/* Date Range control (Visual Remediation): a proper bordered period
   control, visually distinct from the metric cards it governs. */
.analytics-date-range-control {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.875rem 1rem;
  margin-bottom: 1.5rem;
}

.analytics-date-range-control__label {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  margin-bottom: 0.375rem;
}

.analytics-date-range-control__display {
  font-size: 0.8125rem;
  color: var(--text);
  font-weight: 600;
  margin-left: 0.5rem;
}

/* Family lifecycle explainer (Final Product-Owner Refinement): reuses the
   Period control's own "boxed, alt-surface" visual language so it reads
   as a supporting reference panel, clearly secondary to the actual KPI
   cards/composition bar analytics above it in the same card -- not a
   dominant new component, just a restrained background/border/spacing
   difference already established elsewhere on this page. */
.analytics-explainer-panel {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.875rem 1rem;
  margin-top: 1.25rem;
}

.analytics-explainer-panel__label {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  margin-bottom: 0.375rem;
}

/* Family Definitions uses low-chroma, theme-aware tints to separate its
   three independent terminology groups without making them read as alerts. */
.family-definitions-card--setup {
  background: color-mix(in srgb, var(--data-blue) 6%, var(--surface));
}

.family-definitions-card--activation {
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}

.family-definitions-card--engagement {
  background: color-mix(in srgb, var(--success) 6%, var(--surface));
}

/* Family lifecycle explainer (Visual Remediation): a compact, non-
   analytics explanatory flow -- no counts/percentages. */
.family-lifecycle {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.family-lifecycle__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 6rem;
  padding: 0.5rem 0.625rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-alt);
}

.family-lifecycle__step-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.family-lifecycle__step-caption {
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  margin-top: 0.125rem;
}

.family-lifecycle__step--active {
  border-color: var(--success);
  background: var(--success-bg);
}

.family-lifecycle__step--at-risk {
  border-color: var(--warning);
  background: var(--warning-bg);
}

.family-lifecycle__step--dormant {
  border-color: var(--danger);
  background: var(--danger-bg);
}

.family-lifecycle__arrow {
  color: var(--text-muted);
  font-size: 1rem;
  flex-shrink: 0;
}

.family-lifecycle__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.family-lifecycle__note {
  flex-basis: 100%;
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  margin-top: 0.375rem;
}

@media (max-width: 640px) {
  .family-lifecycle {
    flex-direction: column;
    align-items: stretch;
  }
  .family-lifecycle__arrow {
    transform: rotate(90deg);
    align-self: center;
  }
  .family-lifecycle__group {
    flex-direction: column;
    align-items: stretch;
  }
}

/* Overview temporal hierarchy (Visual Remediation): a small label
   distinguishes the current/all-time zone from the selected-period zone
   so the Period control's ownership is visually unambiguous. */
.analytics-temporal-zone__label {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.analytics-info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  background: var(--badge-neutral-bg);
  color: var(--badge-neutral-text);
  font-size: 0.625rem;
  font-weight: 700;
  cursor: pointer;
}

.analytics-info-icon:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* E12-04 User App Activity: a scan-friendly log table. Fixed layout, no
   min-width, so it never scrolls horizontally: Desktop When | Activity |
   Area | By | chevron; narrow desktop / tablet folds Area and By into the
   Activity metadata line; phones keep a two-column When | Activity table.
   The whole row opens the detail drawer (.activity-sheet). */
.activity-controls {
  margin-bottom: 1rem;
}

.activity-area-filter {
  flex: 0 1 12rem;
  min-width: 0;
}

.activity-area-filter .field-input {
  width: 100%;
  min-width: 0;
}

.activity-table {
  table-layout: fixed;
  width: 100%;
  border-collapse: collapse;
}

.activity-table th,
.activity-table td {
  padding: 0.7rem 1rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}

.activity-table th.activity-table__when { width: 11.5rem; }
.activity-table th.activity-table__area { width: 10.5rem; }
.activity-table th.activity-table__by { width: 12rem; }
.activity-table th.activity-table__open { width: 2.75rem; }

.activity-table td.activity-table__when,
.activity-table td.activity-table__area,
.activity-table td.activity-table__by {
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.activity-table td.activity-table__open {
  color: var(--text-muted);
  vertical-align: middle;
}

.activity-row {
  cursor: pointer;
}

.activity-row:hover,
.activity-row:focus-within {
  background: var(--surface-hover);
}

.activity-row:hover .activity-table__open {
  color: var(--text);
}

.activity-row__link {
  display: block;
  color: var(--text);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.activity-row__link:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 0.25rem;
}

.activity-row__summary,
.activity-row__meta {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.activity-row__meta {
  display: none;
}

@media (max-width: 1023px) {
  .activity-table .activity-table__area,
  .activity-table .activity-table__by {
    display: none;
  }

  .activity-row__meta {
    display: block;
  }
}

@media (max-width: 639px) {
  .activity-table th,
  .activity-table td {
    padding: 0.65rem 0.75rem;
  }

  .activity-table th.activity-table__when {
    width: 6.25rem;
  }

  .activity-table td.activity-table__when {
    font-size: var(--fs-xs);
  }

  .activity-table .activity-table__open {
    display: none;
  }
}

/* Activity detail drawer: the One-Time Money sheet primitive (native
   <dialog>, right side on desktop, bottom sheet on phones, same motion and
   reduced-motion handling). */
.activity-sheet {
  position: fixed;
  inset: 0 0 0 auto;
  margin: 0;
  width: min(30rem, 100%);
  max-width: 100%;
  height: 100dvh;
  max-height: 100dvh;
  padding: 0;
  border: 0;
  border-left: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  box-shadow: -12px 0 40px rgba(17, 19, 23, 0.25);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.activity-sheet:not([open]) {
  display: none;
}

.activity-sheet::backdrop {
  background: rgba(15, 17, 21, 0.5);
}

.activity-sheet.is-opening {
  animation: one-time-sheet-in-right 240ms cubic-bezier(0.2, 0, 0, 1);
}

.activity-sheet.is-opening::backdrop {
  animation: one-time-backdrop-in 240ms ease-out;
}

.activity-sheet.is-closing {
  animation: one-time-sheet-out-right 200ms cubic-bezier(0.4, 0, 1, 1) forwards;
}

.activity-sheet.is-closing::backdrop {
  animation: one-time-backdrop-out 200ms ease-in forwards;
}

.activity-sheet__header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.activity-sheet__heading {
  min-width: 0;
}

.activity-sheet__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  overflow-wrap: anywhere;
  letter-spacing: var(--tracking-title);
}

.activity-sheet__title:focus {
  outline: none;
}

.activity-sheet__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.2rem 0 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.activity-sheet__close {
  flex: 0 0 auto;
}

.activity-sheet__content {
  display: grid;
  gap: 1.25rem;
  padding: 1.25rem 1.5rem 2rem;
}

.activity-sheet__summary,
.activity-sheet__limited {
  margin: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

.activity-sheet__limited {
  color: var(--text-muted);
}

.activity-sheet__section-title {
  margin: 0 0 0.5rem;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}

.activity-sheet__list {
  display: grid;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--border);
}

.activity-sheet__row {
  display: grid;
  grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
  gap: 0.75rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-base);
}

.activity-sheet__row dt {
  color: var(--text-muted);
}

.activity-sheet__row dd {
  margin: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

.activity-sheet__before {
  color: var(--text-muted);
}

.activity-sheet__arrow {
  margin: 0 0.25rem;
  color: var(--text-muted);
}

.activity-sheet__not-recorded {
  color: var(--text-muted);
  font-style: italic;
}

@media (max-width: 639px) {
  .activity-sheet {
    inset: auto 0 0 0;
    width: 100%;
    height: 92dvh;
    max-height: 92dvh;
    border-left: 0;
    border-top: 1px solid var(--border);
    border-radius: 1rem 1rem 0 0;
    box-shadow: 0 -12px 40px rgba(17, 19, 23, 0.25);
  }

  .activity-sheet.is-opening {
    animation-name: one-time-sheet-in-up;
  }

  .activity-sheet.is-closing {
    animation-name: one-time-sheet-out-down;
  }

  .activity-sheet__header {
    padding: 0.9rem 1.1rem;
  }

  .activity-sheet__content {
    padding: 1.1rem 1.1rem 1.5rem;
  }

  .activity-sheet__row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.15rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .activity-sheet.is-opening,
  .activity-sheet.is-opening::backdrop,
  .activity-sheet.is-closing,
  .activity-sheet.is-closing::backdrop {
    animation: none;
  }
}

/* E12 Admin Audit Log: the Activity log table + sheet primitives above,
   with Admin-specific Target / Result columns. Admin shell content is about
   60rem wide at 1280px and 44rem at 1024px (16rem sidebar), so secondary
   columns fold into the Activity cell earlier than on User Activity; no
   width ever needs horizontal scrolling. */
.admin-audit-result-filter {
  flex: 0 1 9.5rem;
}

.admin-audit-table th.activity-table__when { width: 9rem; }
.admin-audit-table th.admin-audit-table__target { width: 13rem; }
.admin-audit-table th.admin-audit-table__result { width: 6.5rem; }
.admin-audit-table th.activity-table__by { width: 11.5rem; }

.admin-audit-table td.admin-audit-table__target,
.admin-audit-table td.activity-table__by {
  color: var(--text);
  overflow-wrap: anywhere;
}

/* E12-05-022: the actor wraps at the break its markup offers (after an
   email's "@"); only a single unbreakable token falls back to breaking. */
.admin-audit-table td.activity-table__by {
  overflow-wrap: break-word;
}

.admin-audit-target__kind,
.admin-audit-target__secondary,
.admin-audit-actor__note {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.admin-audit-target__label--missing,
.admin-audit-target__none {
  color: var(--text-muted);
}

.admin-audit-actor__role {
  margin-left: 0.25rem;
}

/* The inline result badge is used only once the Result column folds. Its
   wrapper holds a real trailing space, so text / assistive technology read
   "Success ada@…" rather than "Successada@…". */
.admin-audit-row__result {
  display: none;
}

.admin-audit-row__result .badge {
  vertical-align: 0.1em;
}

.admin-audit-meta {
  column-gap: 0.35rem;
  row-gap: 0.2rem;
}

.admin-audit-meta__item {
  display: inline-block;
  white-space: nowrap;
}

.admin-audit-meta__separator {
  color: var(--text-muted);
}

.admin-audit-target__plain {
  margin: 0;
  padding: 0.55rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
  color: var(--text);
}

.admin-audit-operation__ref {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.admin-audit-related__title {
  margin: 0.75rem 0 0.35rem;
  font-size: 0.8125rem;
  font-weight: 650;
  color: var(--text-muted);
}

.admin-audit-related {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
}

.admin-audit-related__item {
  display: grid;
  gap: 0.1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
}

.admin-audit-related__label {
  color: var(--text);
  font-weight: 600;
}

.admin-audit-related__target,
.admin-audit-related__meta,
.admin-audit-related__more {
  color: var(--text-muted);
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}

.admin-audit-related__more {
  margin: 0.5rem 0 0;
}

@media (max-width: 1279px) {
  .admin-audit-table .admin-audit-table__target,
  .admin-audit-table .activity-table__by {
    display: none;
  }

  .admin-audit-table .activity-row__meta {
    display: block;
  }
}

@media (max-width: 1023px) {
  .admin-audit-table .admin-audit-table__result {
    display: none;
  }

  .admin-audit-row__result {
    display: inline;
  }
}

@media (max-width: 639px) {
  /* Wide enough for "Sep 19, 2026," / "5:05 PM EDT" on two lines. */
  .admin-audit-table th.activity-table__when {
    width: 7.5rem;
  }

  /* Admin Audit has Search + Action + Result: search on its own row, the
     two filters side by side below it (no overlap, no horizontal scroll). */
  .admin-audit-controls {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.5rem;
  }

  .admin-audit-controls .entity-search-field {
    grid-column: 1 / -1;
    max-width: none;
  }

  .admin-audit-controls .activity-area-filter {
    min-width: 0;
  }

  .admin-audit-controls .field-input {
    width: 100%;
    min-width: 0;
  }
}

/* P5: the shared Month Note component closes both MonthCast surfaces. */
.month-note__title {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  letter-spacing: normal;
}

.month-note__body {
  margin-top: 0.4rem;
  color: var(--text);
  font-size: var(--fs-base);
  line-height: 1.5;
  white-space: pre-wrap;
}

.month-note__empty {
  margin-top: 0.4rem;
  color: var(--text-muted);
  font-size: var(--fs-base);
}

.month-note__input {
  margin-top: 0.5rem;
  resize: vertical;
}

.month-note__actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.6rem;
}

.month-note--frozen .month-note__body {
  color: var(--text-muted);
}

/* ------------------------------------------------------------------ */
/* B7: the MonthCast financial summary -- one component, both surfaces */
/* ------------------------------------------------------------------ */

/* An ordinary neutral CountAhead surface in both themes. The only colour
   here is the sign of Leftover itself and the direction tint on a driver
   bar, which says whether that driver adds or takes -- never whether it is
   good or bad. */
.monthcast-summary {
  padding: 0.9rem 1rem 0.95rem;
  margin-bottom: 0.75rem;
  min-width: 0;
}

.monthcast-summary__headline {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.monthcast-summary__label {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}

.monthcast-summary__state {
  font-size: var(--fs-2xs);
}

.monthcast-summary__amount {
  margin-top: 0.15rem;
  color: var(--text);
  font-size: clamp(1.75rem, 3.4vw, 2.25rem);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.03em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.monthcast-summary[data-sign="positive"] .monthcast-summary__amount {
  color: var(--success);
}

.monthcast-summary[data-sign="negative"] .monthcast-summary__amount {
  color: var(--danger);
}

.monthcast-summary__note {
  margin: 0.5rem 0 0;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  line-height: 1.45;
}

/* E12-MCS-UX-004: the Contribution Stack as one formula line, not five
   cards. Each driver is an operator, a name and a value read straight
   across; the proportion band underneath carries the same four drivers as
   one strip. Leftover above is the only display-sized number, so the
   hierarchy is Leftover first and the drivers plainly secondary. */
.monthcast-stack {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0.65rem 0 0;
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.5rem;
}

.monthcast-stack__term {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
}

.monthcast-stack__term-body {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
  flex-wrap: wrap;
}

.monthcast-stack__operator {
  color: var(--text-muted);
  font-size: 0.9375rem;
  font-weight: 650;
  line-height: 1;
}

.monthcast-stack__label {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: 1.3;
}

.monthcast-stack__note {
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-regular);
}

.monthcast-stack__value {
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* One band, four segments -- the same drivers in the same order, each
   sized against the largest of them. */
.monthcast-stack__band {
  display: flex;
  gap: 0.2rem;
  margin-top: 0.55rem;
}

.monthcast-stack__segment {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  height: 0.3rem;
  border-radius: 999px;
  background: var(--surface-selected);
  overflow: hidden;
}

.monthcast-stack__fill {
  display: block;
  height: 100%;
  width: var(--monthcast-share, 0%);
  border-radius: 999px;
  background: var(--data-blue);
}

/* Direction, not judgement: what a driver adds is drawn in the data accent,
   what it takes away in a muted neutral of the same weight. */
.monthcast-stack__segment[data-direction="out"] .monthcast-stack__fill {
  background: color-mix(in srgb, var(--text-muted) 62%, var(--border));
}

/* The band follows the counters on the same clock when a MonthCast action
   changes the month. */
.monthcast-stack__fill--moving {
  transition: width var(--monthcast-value-duration, 420ms) cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .monthcast-stack__fill--moving {
    transition: none;
  }
}

@media (max-width: 600px) {
  .monthcast-summary {
    padding: 0.85rem 0.85rem 0.9rem;
  }

  /* Still one component: the formula wraps by term, so a term never
     breaks between its own name and its own value. */
  .monthcast-stack {
    gap: 0.15rem 0.45rem;
  }

  .monthcast-stack__value {
    font-size: var(--fs-sm);
  }
}

/* E12-MCS-UX-003/005: one sticky layer for a MonthCast surface. The full
   Summary above it never sticks. The rail does, and it carries the view
   selector and the compact Leftover on the same row, so revealing the
   Leftover changes nothing about the rail's height and nothing underneath
   it moves. */
.monthcast-rail {
  position: sticky;
  top: var(--app-sticky-offset);
  z-index: 31;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
  padding: 0.35rem 0 0.5rem;
  background: var(--app-bg);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--border) 72%, transparent);
}

.monthcast-rail__tabs {
  flex: 1 1 auto;
  min-width: 0;
}

/* Inside the rail the view selector is an ordinary segmented control
   again -- the rail is what sticks, so the tabs must not stick too. */
.monthcast-rail .dashboard-view-tabs {
  position: static;
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: 0;
  box-shadow: none;
  background: transparent;
}

.monthcast-compact {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex: 0 1 auto;
  min-width: 0;
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}

.monthcast-compact__label {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  white-space: nowrap;
}

.monthcast-compact__value {
  color: var(--text);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.monthcast-compact__value[data-sign="positive"] {
  color: var(--success);
}

.monthcast-compact__value[data-sign="negative"] {
  color: var(--danger);
}

@media (max-width: 520px) {
  /* The rail stays one row on a phone; the word "Leftover" is what gives
     way, never the number. */
  .monthcast-compact__label {
    display: none;
  }

  .monthcast-compact {
    padding: 0.2rem 0.45rem;
  }

  .monthcast-compact__value {
    font-size: var(--fs-base);
  }
}

/* Section context (E12-MCS-UX-005): the header of the section being read
   pins directly under the rail and leaves with its own section. One at a
   time, nothing permanent, and the same on Desktop and Mobile. */
[data-monthcast-surface] {
  --monthcast-rail-offset: var(--app-sticky-offset);
}

[data-monthcast-surface] .monthly-shell-section > summary,
[data-monthcast-surface] .monthcast-section-heading {
  position: sticky;
  top: var(--monthcast-rail-offset);
  z-index: 20;
  background: var(--surface);
}

/* A sticky heading is opaque and square, so a rounded card has to clip its
   own content or the heading paints over the corners and the border reads
   as broken (E12-MCS-UX-018 -- the Historical sections, which are
   `.item-ledger-wrap` cards rather than `.monthly-shell-section` ones).
   `overflow: hidden` would make the card a scrollport, and a sticky child
   cannot escape one; `clip` rounds the content off without creating one,
   so the heading pins and the corners stay whole. */
[data-monthcast-surface] .monthly-shell-section,
[data-monthcast-surface] .item-ledger-wrap.card {
  overflow: clip;
}

/* ------------------------------------------------------------- */
/* B8a: MonthCast Create Preview -- the list of occurrences to    */
/* review before the month is created.                            */
/* ------------------------------------------------------------- */

.preview-occurrences {
  container-type: inline-size;
  container-name: preview-occurrences;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  overflow: hidden;
}

.preview-occurrence-table {
  table-layout: fixed;
  width: 100%;
}

.preview-occurrence-head th {
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}

/* E12-MCS-013: wide enough for the whole native YYYY-MM-DD plus the
   browser's own picker control, so neither is clipped on Desktop. */
.preview-col-date { width: 12rem; }
.preview-col-category { width: 15rem; }
.preview-col-amount { width: 12.5rem; text-align: right; }

.preview-occurrence-row {
  border-bottom: 1px solid var(--border);
}

.preview-occurrence-row td {
  vertical-align: top;
  overflow-wrap: anywhere;
}

.preview-occurrence-empty td {
  color: var(--text-muted);
}

/* The column headings already name these cells on a wide screen, and the
   values name themselves on a narrow one, so the per-cell labels exist for
   assistive technology only. */
.preview-field-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.preview-occurrence-date {
  display: block;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.preview-occurrence-name {
  display: block;
  color: var(--text);
  font-weight: var(--fw-medium);
}

.preview-occurrence-owner {
  display: block;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
}

/* "Income · Inflow": Category is the label the reader scans, and the
   direction trails it quietly to say which way the money moves. It is never
   a green/red verdict -- a Savings Contribution is an Outflow, not a loss. */
.preview-occurrence-category {
  color: var(--text);
}

.preview-occurrence-direction {
  color: var(--text-muted);
  white-space: nowrap;
}

.preview-occurrence-amount {
  display: inline-block;
  color: var(--text);
}

.preview-amount-field {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.35rem;
  max-width: 100%;
}

.preview-amount-currency {
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.preview-amount-input {
  width: 7.25rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.preview-amount-field .field-error {
  flex: 1 0 100%;
  text-align: right;
}

/* Narrow: every row becomes its own card, with Date, Name and Category all
   still on screen -- they are what tell two occurrences of the same source
   apart, so none of them may be dropped. */
@container preview-occurrences (max-width: 44rem) {
  .preview-occurrence-table,
  .preview-occurrence-table tbody,
  .preview-occurrence-row,
  .preview-occurrence-empty,
  .preview-occurrence-row td,
  .preview-occurrence-empty td {
    display: block;
    width: auto;
  }

  .preview-occurrence-head {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
  }

  .preview-occurrence-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "name     name"
      "category amount"
      "date     amount";
    align-items: center;
    gap: 0.1rem 0.75rem;
    padding: 0.7rem 0.9rem;
  }

  .preview-occurrence-row td {
    padding: 0;
  }

  .preview-col-name { grid-area: name; }
  .preview-col-date { grid-area: date; }
  .preview-col-category { grid-area: category; }
  .preview-col-amount { grid-area: amount; justify-self: end; }

  .preview-col-category {
    font-size: var(--fs-xs);
  }

  /* The whole date has to be readable: it is half of what tells two
     occurrences of the same source apart. */
  .preview-date-input {
    /* The Desktop minimum would overflow a narrow card. */
    min-width: 0;
    max-width: 100%;
    font-size: var(--fs-xs);
    padding: 0.3rem 0.35rem;
  }

  .preview-amount-input {
    width: 6.25rem;
  }
}

/* B8b: a Date Override lives in the Preview's own Date cell. Native
   type="date" with min/max expresses the month rule in the browser; the
   server enforces the same rule and answers beside this field. */
.preview-date-input {
  width: 100%;
  min-width: 9.75rem;
  max-width: 10.5rem;
  padding: 0.3rem 0.45rem;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

.preview-date-input:invalid,
.field-input--invalid {
  border-color: var(--danger);
}

.preview-col-date .field-error {
  margin-top: 0.25rem;
  white-space: normal;
}
/* E12-MCS: the server-computed confirmation is the shared dialog now, so
   it needs no surface of its own. This form only carries the receipt and
   the no-JavaScript way through. */
.monthcast-create-confirm {
  display: flex;
  justify-content: flex-end;
  margin-top: 1rem;
}

/* B8b: an opt-in native money field. It is a real numeric control so the
   browser enforces the same minimum, maximum and two-decimal step the
   server does, but it keeps the shared field's appearance -- the spinner
   would only invite clicking through an amount one cent at a time. */
.money-input-native {
  -moz-appearance: textfield;
  appearance: textfield;
}

.money-input-native::-webkit-outer-spin-button,
.money-input-native::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
