/* Vagabonds Royalty Intelligence — vintage parchment + ink theme.
   Inspired by the Vagabonds logo: cream/parchment paper, deep ink-brown,
   typewriter-era typography. Still a finance/analytics interface underneath. */

/* ========== PALETTE — warm parchment + newsprint ink (2026-05-27) ==========
   Two-ink newspaper model. The PAPER is warm parchment (sampled from
   the logo's cream background, #ece1d0 / R235 G225 B208). The INK is
   newsprint slate-blue (#2a3340) — used for primary actions, V-era
   markers, focus rings, and the lead chart series. Warm-black is
   still around for body type. Warm tan persists for "faded /
   historical / supporting" surfaces.

   Mental model: open a 1920s broadsheet. Most of the type is set in
   black ink on the cream stock — that's the body. The headlines and
   accent rules are printed in a deeper blue-black ink that catches
   the light differently from pure black on warm paper. That's the
   newsprint contribution.

   Cohesion guidelines (soft — feel free to break for good cause):
     - Surfaces stay warm parchment (R >= G > B) so cards and page
       always feel like the same paper.
     - Cool tones are anchored on the ink-blue accent family so the
       app reads as a single primary contrast against the warm paper.
     - The previous hard "no greens" rule has been lifted now that the
       overall palette settled cohesively — green/teal tones can be
       used sparingly when they earn their place semantically (e.g.
       a specific status or chart series), as long as they don't
       reintroduce the green-on-brown clash from earlier iterations. */

:root {
  /* Surfaces — warm parchment family. R >= G > B everywhere. */
  --bg:           #f1ede4;          /* page — aged paper */
  --bg-grad-top:  #f5f1e8;
  --bg-grad-bot:  #ede9e0;
  --surface:      #faf6ec;          /* cards — fresh stock, one shade lifted */
  --surface-solid:#fffaf0;
  --surface-2:    #e6e2d8;          /* hover / quiet highlight */
  --surface-3:    #d4cfc4;
  --border:       #9b958a;          /* warm tan edge */
  --border-soft:  #cfc9bc;          /* thin paper-rule divider */

  /* Ink — warm-black for body type */
  --fg:           #1f1c16;          /* body text */
  --fg-strong:    #0e0c08;          /* headings, emphasis */
  --muted:        #756f60;          /* secondary copy */
  --muted-strong: #46412f;          /* labels, captions */

  /* Accent — newsprint ink-blue. Used for buttons (Save / Submit /
     Generate PDF), focus rings, the V-era marker, and the lead chart
     series. The single cool primary against the warm paper. */
  --accent:       #2a3340;          /* ink-blue */
  --accent-2:     #3a4554;
  --accent-soft:  rgba(42, 51, 64, 0.10);
  --accent-hover: #1a2330;
  --accent-fg:    #faf6ec;          /* cream against ink-blue */

  /* Status — five-color story shared with chart palette + financial
     direction. Every status surface uses ONE of the brand inks at
     known luminance, with a light tint companion for backgrounds.
     This means a 'warn' banner, a mustard chart bar, and the warn-icon
     badge all carry the same hue — no two competing "yellow"s. */
  --good:         #2d6066;          /* deep teal — growth / healthy */
  --good-bg:      #d8e6e6;
  --good-border:  #2d6066;
  --warn:         #8a5a14;          /* deep mustard — text-readable */
  --warn-bg:      #f4e2b4;
  --warn-border:  #c4942a;
  --bad:          #913232;          /* oxblood — same as --negative */
  --bad-bg:       #f0d8d8;
  --bad-border:   #913232;

  /* Code / chips */
  --code-bg:      #e6e2d8;
  --code-fg:      #1f1c16;
  --row-hover:    #e6e2d8;
  --row-flagged:  #f4e2b4;

  /* V/H differentiation — V-era picks up the ink-blue accent (it's
     the "current/our money" highlight, so it gets the cool counterpoint
     hue). Historical stays faded warm tan ("previous owner, aged"). */
  --vagabonds:        #2a3340;      /* ink-blue */
  --vagabonds-soft:   rgba(42, 51, 64, 0.10);
  --vagabonds-tint:   #d4d8de;
  --vagabonds-border: #3a4554;
  --historical:       #a89a82;      /* faded parchment-tan */
  --historical-soft:  rgba(168, 154, 130, 0.14);
  --historical-tint:  #e6e2d8;
  --historical-border:#bcb09c;

  /* Acquisition / annotation markers — warm tan dashed strokes on
     chart annotations. Sits between the data ink (blue/black) and the
     paper without competing with either. */
  --ribbon:        #a78a6b;
  --ribbon-soft:   rgba(167, 138, 107, 0.10);

  /* Financial direction — green/red convention re-cast onto the brand
     inks. Positive = teal (same as --good); negative = oxblood (same as
     --bad). Used for YoY %, P&L deltas, recovered-of-cost, etc. */
  --positive:      #2d6066;          /* teal */
  --negative:      #913232;          /* oxblood */

  /* Oxblood accent for the clickable toggle LINKS (chips) — filters, view
     toggles, forecast lenses, etc. Makes the links stand out from the
     muted-grey descriptive labels next to them. */
  --oxblood:       #913232;          /* oxblood */

  /* Chart palette — five brand inks + three supporting tones, ordered
     to maximize differentiation when adjacent slots stack. Each hue is
     bright enough to read against warm parchment paper.

     The first five hues (ink-blue / oxblood / mustard / teal / plum)
     are the SHARED brand inks reused for status + financial direction:
       chart-1 = --vagabonds = --accent  (ink-blue)
       chart-2 = --bad / --negative      (oxblood)
       chart-3 ≈ --warn-border           (mustard)
       chart-4 = --good / --positive     (teal)
     So the chart series and the status/financial colors live on the
     same color story. */
  /* Chart palette — saturated vintage broadsheet inks, tuned to POP
     against warm parchment. All hues sit at high saturation so they
     read as clear distinct printed inks rather than muted page tints.
     Adjacent slots alternate between cool/warm and dark/bright so no
     two consecutive bars look like the same color when stacked. */
  --chart-1: #243f64;   /* ink-blue      — V-era / accent / lead (brighter mid-blue) */
  --chart-2: #b8302e;   /* cinnabar red  — vivid oxblood / negative */
  --chart-3: #d09010;   /* vivid mustard — saturated aged-print yellow */
  --chart-4: #2c8079;   /* jade teal     — vivid positive / good */
  --chart-5: #88347a;   /* magenta-plum  — saturated purple counter */
  --chart-6: #c95e1c;   /* burnt orange  — bright warm differentiator */
  --chart-7: #3e5380;   /* periwinkle    — brighter cool mid */
  --chart-8: #7a705a;   /* warm tan      — neutral "Other" */
}

/* ========== HERITAGE PUBLISHER theme ==========
   Cream paper, deep burgundy primary, antique gold secondary. Feels
   like a 1900s music publisher imprint or vintage law-library volume.
   Established, distinguished, old-money. */
:root[data-theme="heritage"] {
  --bg:           #f4ead7;          /* aged cream paper */
  --bg-grad-top:  #f8eedb;
  --bg-grad-bot:  #f0e6d3;
  --surface:      #fbf2dc;          /* ivory cards */
  --surface-solid:#fff7e2;
  --surface-2:    #ebdfc4;
  --surface-3:    #d8cbac;
  --border:       #9b8e6e;
  --border-soft:  #cabea0;

  --fg:           #2a1f10;          /* deep coffee brown */
  --fg-strong:    #170f04;
  --muted:        #756a52;
  --muted-strong: #4a3e26;

  --accent:       #6b1a2a;          /* deep burgundy */
  --accent-2:     #7a2436;
  --accent-soft:  rgba(107, 26, 42, 0.10);
  --accent-hover: #4d0e1c;
  --accent-fg:    #fbf2dc;

  --good:         #3a5a3a;          /* forest */
  --good-bg:      #dde2ce;
  --good-border:  #3a5a3a;
  --warn:         #6e4a14;
  --warn-bg:      #ecd6a4;
  --warn-border:  #8a6e1a;
  --bad:          #6b1a2a;
  --bad-bg:       #ecd0d4;
  --bad-border:   #6b1a2a;

  --code-bg:      #ebdfc4;
  --code-fg:      #2a1f10;
  --row-hover:    #ebdfc4;
  --row-flagged:  #ecd6a4;

  --vagabonds:        #6b1a2a;      /* burgundy = "our money" */
  --vagabonds-soft:   rgba(107, 26, 42, 0.10);
  --vagabonds-tint:   #e8c4cc;
  --vagabonds-border: #7a2436;
  --historical:       #a89868;
  --historical-soft:  rgba(168, 152, 104, 0.14);
  --historical-tint:  #ebdfc4;
  --historical-border:#c4b486;

  --ribbon:        #8a6e1a;         /* antique gold for chart annotations */
  --ribbon-soft:   rgba(138, 110, 26, 0.10);

  --positive:      #3a5a3a;         /* forest */
  --negative:      #6b1a2a;         /* burgundy */
  --oxblood:       #6b1a2a;         /* burgundy oxblood — clickable toggle links (chips) */

  /* Heritage chart palette — saturated vintage law-library inks. Same
     "pop against warm cream" tuning as refined, but in the heritage
     burgundy/gold/navy family. */
  --chart-1: #8e1a2e;   /* deep burgundy — V-era / accent (saturated) */
  --chart-2: #b88018;   /* rich gold     — vivid antique gold */
  --chart-3: #46743e;   /* forest        — saturated leafy green */
  --chart-4: #1d4674;   /* navy          — deeper indigo */
  --chart-5: #8a5828;   /* tobacco       — richer warm brown */
  --chart-6: #6e3962;   /* plum          — richer royal purple */
  --chart-7: #4a5366;   /* slate         — cool mid */
  --chart-8: #a89868;   /* mushroom      — neutral "Other" */
}

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  /* 2026-05-27 reskin — clean commercial layout. Courier Prime stays
     the signature typeface but the visual treatment is now editorial:
     near-white warm paper, no grain, soft shadows. */
  font-family: var(--font-display);
  color: var(--fg);
  background: var(--bg);
  background-attachment: fixed;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* All visible text rendered lowercase for consistent stylized look.
     Underlying data is preserved (form submissions, alt text, URLs,
     stored values) — this is purely a display layer. Numbers and
     punctuation are unaffected; only letters are transformed. */
  text-transform: lowercase;
}

/* User-typed input must show in the case the user is typing (so the
   visible value matches what they actually entered). Selects, however,
   carry developer-defined option text — same content as everything
   else on the page — so they DO get lowercased.
   Note: `select` browser support for text-transform on <option> is
   inconsistent (Safari closed-state honors it, Firefox option-list
   may not), so we also explicitly apply it on the select element
   AND on inline option content via the styles below. */
input, textarea {
  text-transform: none;
}
select, select option {
  text-transform: lowercase;
}

/* Buttons don't inherit text-transform from body in most browsers
   (form-control quirk in the UA stylesheet), so apply lowercase
   explicitly. Their labels are presentation text we control, not user
   data, so the global typewriter / lowercase look should reach them. */
button, .btn, .btn-primary, .btn-small, .btn-secondary, .chip {
  text-transform: lowercase;
  font-family: inherit;
}

/* Soften default bold weight across the app. The typewriter face has
   heavy strokes already, so browser-default <strong>/<b>/<th> = 700
   reads as aggressive. 500 keeps emphasis without shouting. Specific
   elements that want heavier bold can override locally. */
strong, b, th {
  font-weight: 500;
}

/* Multi-line code blocks (<pre>) keep their original case — preserving
   line-by-line readability for error traces, schema dumps, etc.
   Inline <code> / <kbd> / <samp> / .verbatim are now ALSO lowercased
   along with the rest of the page so payor codes, sub-account IDs,
   and short tokens read consistently in the typewriter style. Numbers
   and punctuation are unaffected by text-transform either way. */
pre {
  text-transform: none;
}

a { color: var(--accent); text-decoration: underline; text-decoration-color: rgba(26, 26, 26, 0.3); text-underline-offset: 2px; }
a:hover { color: var(--accent-hover); text-decoration-color: var(--accent); }

::selection { background: var(--fg); color: var(--bg); }

/* ----- Typography — typewriter accent for brand + headings ----- */

.serif, header h1, main h2 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.005em;
}

/* ----- Layout ----- */

.container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 1.75rem;
}

header {
  border-bottom: 1px solid var(--border-soft);
  padding: 0.2rem 0;
  background: rgba(253, 253, 253, 0.94);
  backdrop-filter: saturate(120%) blur(6px);
  -webkit-backdrop-filter: saturate(120%) blur(6px);
  position: sticky;
  top: 0;
  z-index: 50;
}

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

header h1 {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  letter-spacing: 0.01em;
}

header h1 a {
  color: var(--fg-strong);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

header h1 a:hover { color: var(--accent-hover); }

/* Header thumbnail logo — clean, no frame. Just the mark sitting on
   the page. (2026-05-27 reskin — removed ornate double-border + brass
   mat that was competing with the data below.) */
header h1 img.brand-logo {
  height: 88px;
  width: auto;
  display: block;
  mix-blend-mode: multiply;
  /* Negative vertical margin crops the PNG's built-in transparent
     whitespace top + bottom so the silhouette doesn't push the
     header taller than it needs to be. Mild negative right margin
     leaves visible breathing room before the wordmark. */
  margin: -0.8rem -1.25rem -0.8rem 0;
}

/* Wordmark image sits between the silhouette and the "Royalty
   Intelligence" tagline. The "vagabonds" word PNG has substantial
   transparent whitespace top + bottom AND left + right, so we crop
   visually with negative margins on all four sides. */
header h1 img.brand-wordmark-img {
  height: 220px;            /* bigger than the tagline text so the
                                wordmark reads as the dominant title */
  width: auto;
  display: block;
  mix-blend-mode: multiply;
  /* Symmetric vertical crop keeps the wordmark inside the flex line
     so it doesn't bleed below the bar. The PNG has substantial
     transparent padding on all four sides; we crop the vertical
     aggressively but leave more horizontal space so the wordmark
     reads as a separate element from the silhouette and the dot. */
  margin: -4rem -2.25rem;
  /* Lift the wordmark visually above the tagline baseline without
     breaking the flex layout. `position: relative` + negative `top`
     shifts the rendered image up; the layout box stays where it was
     so nothing else moves. */
  position: relative;
  top: -0.1rem;
}

/* Tagline sits to the right of the header logo. The "Vagabonds" wordmark is
   baked into the image, so this only carries the "· Royalty Intelligence"
   half of the brand. Typewriter face matches the dashboard hero subtitle
   so the brand voice is consistent at both sizes. */
header h1 .brand-tagline {
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--muted-strong);
  font-family: var(--font-display);
  letter-spacing: 0.04em;
  white-space: nowrap;
  margin-left: 0.15rem;
}
header h1 .brand-tagline::before {
  content: "·";
  margin-right: 0.5rem;
  opacity: 0.55;
}

/* Larger hero version of the logo, used on the dashboard and any landing-style page.
   Restrained version (2026-05-18) — the old layout had decorative red ribbons
   flanking the wordmark that competed with the data below. Now: just logo +
   wordmark + subtitle with a thin rule. */
.brand-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.5rem 1rem 1.5rem;
  margin: 0 0 1.75rem;
  border-bottom: 1px solid var(--border-soft);
}
/* Hero logo — clean and unframed. (2026-05-27 reskin — removed the
   double-line vintage-portrait frame, brass mat, drop-shadow stack.
   Now the logo just sits centered on the page like a masthead.) */
.brand-hero img.brand-logo-hero {
  height: 176px;
  width: auto;
  display: block;
  mix-blend-mode: multiply;
}
.brand-hero .brand-wordmark {
  margin: 0.25rem 0 0;
  font-size: 1.55rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  color: var(--fg-strong);
  font-family: var(--font-display);
  line-height: 1;
}
.brand-hero .brand-subtitle {
  margin: 0.3rem 0 0;
  font-size: 0.72rem;
  color: var(--muted);
  font-family: var(--font-display);
  letter-spacing: 0.18em;
  text-transform: lowercase;
}

header nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  align-items: center;
}

/* Top-level link + dropdown trigger share these styles. Direct links use
   <a class="nav-link">; dropdowns use <button class="nav-trigger">.
   2026-05-27 reskin — flattened from heavy typewriter-key style to
   clean editorial nav. No bezel, no depth, no collar. Just text with
   a subtle underline accent on the active section. Reads commercial,
   not novelty-themed. */
header nav .nav-link,
header nav .nav-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.45rem 0.85rem;
  font-size: 0.88rem;
  font-weight: 500;
  font-family: inherit;
  color: var(--fg);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  letter-spacing: 0.04em;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  transition: color 100ms ease-out, background 120ms ease-out,
              border-color 120ms ease-out;
}
header nav .nav-link:hover,
header nav .nav-trigger:hover {
  color: var(--fg-strong);
  background: var(--surface-2);
}
/* Active section: subtle inked underline + slightly heavier text */
header nav .nav-link.is-active,
header nav .nav-dropdown.is-active > .nav-trigger {
  color: var(--fg-strong);
  font-weight: 600;
  background: var(--surface-2);
  border-color: var(--border-soft);
}
header nav .nav-link.is-active:hover,
header nav .nav-dropdown.is-active > .nav-trigger:hover {
  background: var(--surface-3);
}
header nav .nav-caret {
  font-size: 0.65rem;
  opacity: 0.7;
  margin-top: 1px;
}

/* Dropdown container is positioned relative so the menu can anchor to it. */
header nav .nav-dropdown {
  position: relative;
}

/* Menu hidden by default; revealed when the parent gets `.open` (set by JS
   on trigger click) or when any descendant has focus (keyboard
   accessibility — tab-into menu auto-opens it). */
header nav .nav-menu {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 0.25rem;
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(26, 26, 26, 0.15);
  padding: 0.3rem;
  display: none;
  z-index: 50;
}
header nav .nav-dropdown.open > .nav-menu,
header nav .nav-dropdown:focus-within > .nav-menu {
  display: block;
}
header nav .nav-menu a {
  display: block;
  padding: 0.4rem 0.7rem;
  color: var(--fg);
  font-size: 0.88rem;
  text-decoration: none;
  border-radius: 4px;
  white-space: nowrap;
  transition: background 0.1s;
}
header nav .nav-menu a:hover {
  background: var(--surface-2);
  color: var(--fg-strong);
}

/* Account dropdown — sits at the far right of the nav; its menu opens
   right-aligned so it never spills off-screen. */
header nav .nav-account { margin-left: auto; }
header nav .nav-menu--right { left: auto; right: 0; }
header nav .nav-menu-email {
  padding: 0.3rem 0.7rem 0.45rem;
  font-size: 0.76rem;
  color: var(--muted);
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 0.25rem;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* "Log out" is a form-submit button but should look like the menu's link
   items. High-specificity selector overrides the global solid-button style. */
header nav .nav-menu form { margin: 0; }
header nav .nav-menu button.nav-menu-action {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.4rem 0.7rem;
  color: var(--fg);
  font-size: 0.88rem;
  font-family: inherit;
  font-weight: 400;
  letter-spacing: normal;
  background: transparent;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.1s;
}
header nav .nav-menu button.nav-menu-action:hover {
  background: var(--surface-2);
  color: var(--fg-strong);
}

main {
  padding: 2rem 0 3rem;
  min-height: 60vh;
}

main h2 {
  margin: 0 0 1.25rem;
  font-size: 1.7rem;
  font-weight: 500;
  color: var(--fg-strong);
  letter-spacing: -0.01em;
  text-align: center;
}

main h3 {
  font-weight: 500;
  color: var(--fg-strong);
  font-family: var(--font-display);
}

main h4 {
  color: var(--fg-strong);
  font-weight: 500;
  margin-bottom: 0.5rem;
}

p { color: var(--fg); }

/* ----- Cards ----- */

.card {
  margin: 1rem 0;
  padding: 1.25rem 1.4rem;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(26, 26, 26, 0.04);
}

.card.highlight {
  background: var(--surface-solid);
  border-color: var(--accent);
  border-left: 4px solid var(--accent);
}

.card.alert {
  background: var(--warn-bg);
  border-color: var(--warn-border);
  border-left: 4px solid var(--warn);
}

.card h3 { margin-top: 0; }

/* ----- Tables ----- */

table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
}

td, th {
  padding: 0.65rem 0.85rem;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
  text-align: left;
}

table.data-table {
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--border-soft);
  border-radius: 7px;
  overflow: hidden;
  background: var(--surface);
  box-shadow: none;
}
table.data-table th {
  background: var(--surface-2);
  font-size: 0.72rem;
  text-transform: lowercase;
  letter-spacing: 0.12em;
  font-weight: 600;
  color: var(--muted-strong);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  font-family: var(--font-display);
  /* Center headers + cells by default for a calm, consistent grid (numbers stay
     right-aligned via .num / inline styles, which override this). */
  text-align: center;
}

table.data-table thead th:first-child { border-top-left-radius: 6px; }
table.data-table thead th:last-child  { border-top-right-radius: 6px; }
table.data-table thead th + th { border-left: 1px solid var(--border-soft); }

table.data-table tbody tr { transition: background 0.1s; }
table.data-table tbody tr:hover { background: var(--surface-2); }
table.data-table tr.needs-review { background: var(--row-flagged); }
/* Subtle zebra-stripe — every other row gets a very faint cream tint */
table.data-table tbody tr:nth-child(even) { background: rgba(26, 26, 26, 0.018); }
table.data-table tbody tr:nth-child(even):hover { background: var(--surface-2); }

table.data-table.small td, table.data-table.small th {
  font-size: 0.88rem;
}

table.data-table td {
  font-variant-numeric: tabular-nums;
  border-bottom: 1px solid rgba(142, 142, 142, 0.22);
  text-align: center;
}
/* Opt-out: cells/headers that should stay left (long text, the first label
   column where centering reads oddly) get .l or an inline text-align. */
table.data-table th.l, table.data-table td.l { text-align: left; }

tr:last-child td { border-bottom: none; }

/* Pivot table — total column / row styling. The "Total" column on the
   right and the "Grand total" row at the bottom get a brass-tinted
   highlight so they read as summary cells. The Total HEADER uses a
   slightly richer walnut tone (darker than the regular dark-walnut
   header bar) so it visually separates from the regular column heads
   while still showing the light header text clearly. */
table.data-table th.pivot-total-col {
  background: var(--accent);
  color: var(--accent-fg);
  border-left: 2px solid var(--border);
}
table.data-table td.pivot-total-col {
  background: var(--surface-2);
  border-left: 2px solid var(--border-soft);
  font-weight: 500;
}
table.data-table tbody tr:nth-child(even) td.pivot-total-col {
  background: var(--surface-3);
}
table.data-table tbody tr:hover td.pivot-total-col {
  background: var(--surface-3);
}
table.data-table tr.pivot-grand-row {
  background: var(--surface-2);
  border-top: 2px solid var(--border);
}
table.data-table tr.pivot-grand-row td {
  border-bottom: none;
  font-weight: 600;
  color: var(--fg-strong);
}
table.data-table tr.pivot-grand-row td.pivot-total-col {
  background: var(--surface-3);
}

/* ----- Code & inline IDs ----- */

code {
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, "Courier New", monospace;
  background: var(--code-bg);
  color: var(--code-fg);
  padding: 0.12rem 0.45rem;
  border-radius: 3px;
  font-size: 0.84em;
  border: 1px solid var(--border-soft);
}

.aliases-cell code { margin-right: 0.25rem; display: inline-block; margin-bottom: 0.2rem; }

/* ----- Buttons — vintage typewriter keys (Royal/Hermes/Underwood style) -----

   Real old typewriter keys have, from outside to center:
     1. A drop shadow on the page beneath them
     2. A chrome/brass METAL COLLAR ring around the perimeter (the
        circular bezel that mounted the key to the typebar)
     3. A pale ivory/cream FACE with slight concave shading
     4. A black serif LETTER printed on the face

   We render this with:
     - border-radius: 999px → fully pill-shaped (real keys are circular;
       text-bearing pills are the practical web equivalent)
     - A 2px dark border = the metal collar
     - A 1px brass-colored inset ring = the brighter inner bezel edge
     - Background gradient = ivory face with subtle top-to-bottom shading
     - Drop shadow underneath = the key seated on the paper
     - Press transition: keycap descends into the page (translateY +
       shadow collapse) — feels mechanical, satisfying click.

   Two tiers (same shape language, different "key color"):
     - LETTER KEY (.btn-small, .chip): ivory face, dark serif letters
     - FUNCTION KEY (button, .btn-primary): dark/black face, ivory text
       (like the Tab / Shift / Margin Release keys on a real Royal). */

:root {
  /* Legacy alias tokens — kept for back-compat with any component CSS
     that still references --key-* / --paper-edge-* / --label-bg-*. All
     re-pointed at the warm parchment palette so they blend with the
     rest of the page instead of rendering as pure neutral grays. */
  --key-rise:        3px;
  --key-rise-hover:  4px;
  --key-radius:      999px;
  --key-collar:      #1f1c16;       /* warm-black ink */
  --key-collar-dk:   #0e0c08;       /* deepest warm */
  --key-bezel-hi:    #d4cfc4;       /* warm surface-3 */
  --key-bezel-lo:    #46412f;       /* warm muted-strong */
  --key-bezel-inner: #1f1c16;
  --key-face-top:    #faf6ec;       /* warm surface */
  --key-face-mid:    #f1ede4;       /* warm bg */
  --key-face-bot:    #e6e2d8;       /* warm surface-2 */
  --key-shadow:      rgba(31, 28, 22, 0.18);
  --key-shadow-soft: rgba(31, 28, 22, 0.08);

  /* Border/edge tokens that some component CSS still references */
  --paper-edge:      #9b958a;       /* warm border tan */
  --paper-edge-soft: #cfc9bc;       /* warm border-soft */
  --paper-edge-dk:   #46412f;       /* warm muted-strong */

  /* Legacy "label bg" — used by some table-header gradients. Points to
     the ink-blue accent so headers print as newsprint-ink against the
     parchment-tan cards. */
  --label-bg-top:    #2a3340;
  --label-bg-bot:    #1a2330;

  /* Single unified typewriter font stack — Courier Prime is the primary
     (cleaner, very readable, screenwriting-grade), with vintage fallbacks.
     Display and body both use the SAME stack so the look is fully
     consistent everywhere — no two-font mix. */
  --font-display: "Courier Prime", "Cutive Mono", "American Typewriter",
                  "Courier New", ui-monospace, monospace;
  --font-body:    "Courier Prime", "Cutive Mono", "American Typewriter",
                  "Courier New", ui-monospace, monospace;
}

/* ===== FILTER / TOGGLE BUTTONS — text-link style (2026-05-27 rebuild) =====
   Used everywhere we're TOGGLING what's displayed: filter chips, view
   chips, lens toggles, period range, sort headers, etc.

   Design: bare text + 2px underline on the active item. No pill, no
   border box, no fill. Reads as a row of headlines, like a newspaper
   masthead. Inactive items keep the 2px underline slot reserved
   (transparent) so activation doesn't bump the row vertically. */
.btn-small, .chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem 0.1rem;
  margin: 0;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  font-size: 0.85rem;
  font-weight: 400;
  font-family: inherit;
  color: var(--oxblood);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  letter-spacing: 0.02em;
  box-shadow: none;
  transition: color 100ms ease-out, border-bottom-color 100ms ease-out;
}

.btn-small:hover, .chip:hover {
  color: var(--oxblood);
  border-bottom-color: var(--border-soft);
  background: transparent;
}

.btn-small:active, .chip:active {
  color: var(--oxblood);
}

/* Active state — bold + oxblood underline. No background, no border box.
   The toggle LINKS render in oxblood (set apart from the muted-grey
   descriptive labels); the active one is distinguished by bold + underline. */
.btn-small.is-active, .chip.is-active {
  color: var(--oxblood);
  font-weight: 600;
  border-bottom-color: var(--oxblood);
  background: transparent;
}
.btn-small.is-active:hover, .chip.is-active:hover {
  color: var(--oxblood);
  border-bottom-color: var(--oxblood);
}

/* Grayscale palette has no green/brown variants, so the semantic
   classes collapse to the standard active style. Kept as compatibility
   selectors — templates can reference is-active--green / --brown and
   they just render as the standard active. */
.chip.is-active--green,
.chip.is-active--brown {
  color: var(--oxblood);
  font-weight: 600;
  border-bottom-color: var(--oxblood);
  background: transparent;
}

/* ===== COMMIT / ACTION BUTTONS — solid black rect (button, .btn-primary) =====
   Reserved for actions that SUBMIT or COMMIT: Save, Generate PDF,
   Reparse, etc. Square corners (no pill), single border, no shadow.
   Visually heavier than the text-link chips so the user sees the
   semantic difference at a glance: filter chips toggle a view, action
   buttons DO something. */
button, .btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.42rem 1rem;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 0;
  font-size: 0.84rem;
  font-weight: 500;
  font-family: inherit;
  color: var(--accent-fg);
  text-decoration: none;
  cursor: pointer;
  letter-spacing: 0.04em;
  box-shadow: none;
  transition: background 120ms ease-out, border-color 120ms ease-out;
}

button:hover, .btn-primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: var(--accent-fg);
}

button:active, .btn-primary:active {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

button:disabled, .btn-primary:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Button groups — used inside toolbars to keep a label + its chips on
   one line. Flat horizontal row with comfortable spacing between
   text-link chips. */
.btn-group {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.85rem;
  border: none;
  background: transparent;
  padding: 0;
  border-radius: 0;
}

.chart-toolbar {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 0.5rem 1.75rem;
  flex-wrap: wrap;
  margin: 0.4rem 0 1rem;
  padding: 0.65rem 0;
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
}
.chart-toolbar-buttons {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Hero-stat controls row — small View + Perspective text-link group
   sitting above the hero number. Centered to match the rest of the
   hero block, with a small toolbar-label preceding each group. */
.hero-stat-controls {
  display: flex;
  justify-content: center;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 auto 0.85rem;
  font-size: 0.85rem;
}

/* Top-breakdowns row: a bit wider per card than headline stats — these
   hold mini-tables, not single numbers. */
.stats-row.top-breakdowns {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* ----- Result boxes ----- */

.result { margin-top: 0.75rem; min-height: 1.25rem; }
.result .ok { color: var(--good); font-weight: 500; }

.result-box {
  margin-top: 1rem;
  padding: 0.95rem 1.15rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface-solid);
  color: var(--fg);
}
.result-box.ok    { background: var(--good-bg); border-color: var(--good-border); color: var(--good); }
.result-box.warn  { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn); }
.result-box.bad   { background: var(--bad-bg);  border-color: var(--bad-border);  color: var(--bad); }
.result-box.ok strong, .result-box.warn strong, .result-box.bad strong { color: inherit; }

.inline-status {
  margin: 0.75rem 0;
  padding: 0.55rem 0.85rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  color: var(--fg-strong);
  font-weight: 500;
}

/* ----- HTMX indicator visibility ----- */

.htmx-indicator { display: none; }
.htmx-request .htmx-indicator { display: block; }
.htmx-request.htmx-indicator { display: block; }

/* ----- Progress bar + overlay ----- */

.progress-bar {
  display: inline-block;
  width: 220px;
  height: 6px;
  background: var(--border-soft);
  border-radius: 999px;
  overflow: hidden;
  vertical-align: middle;
  margin-right: 0.6rem;
  position: relative;
}
.progress-bar-inner {
  position: absolute;
  left: 0;
  top: 0;
  width: 35%;
  height: 100%;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-2) 50%, var(--accent) 100%);
  border-radius: 999px;
  animation: progress-sweep 1.4s ease-in-out infinite;
  transition: width 0.25s ease-out;
}
/* Determinate mode — set by JS when we have real percentage data. The
   sweep animation is replaced by a fixed-width fill that grows toward
   100%. The transition smooths poll-to-poll jumps. */
.progress-bar.determinate .progress-bar-inner {
  animation: none;
  transform: none;
  /* width is set inline by progress.js */
}
@keyframes progress-sweep {
  0%   { transform: translateX(-120%); }
  50%  { transform: translateX(160%); }
  100% { transform: translateX(160%); }
}
.progress-elapsed {
  font-variant-numeric: tabular-nums;
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, Menlo, monospace;
  color: var(--muted-strong);
  font-size: 0.85rem;
}
.progress-detail {
  font-variant-numeric: tabular-nums;
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, Menlo, monospace;
  color: var(--muted-strong);
  font-size: 0.85rem;
}

.progress-overlay {
  position: fixed;
  inset: 0;
  background: rgba(26, 26, 26, 0.5);
  backdrop-filter: saturate(120%) blur(4px);
  -webkit-backdrop-filter: saturate(120%) blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease-out;
}
.progress-overlay.visible { opacity: 1; pointer-events: auto; }
.progress-card {
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 1.6rem 2rem;
  border-radius: 8px;
  min-width: 380px;
  max-width: 90vw;
  box-shadow: 0 16px 40px rgba(26, 26, 26, 0.35);
  text-align: center;
  color: var(--fg);
}
.progress-card .progress-title {
  font-size: 1.05rem;
  font-weight: 500;
  margin: 0 0 0.35rem;
  color: var(--fg-strong);
  font-family: var(--font-display);
}
.progress-card .progress-subtitle {
  font-size: 0.88rem;
  color: var(--muted-strong);
  margin: 0 0 1rem;
}
.progress-card .progress-bar {
  width: 100%;
  height: 8px;
  margin: 0.4rem 0 0.9rem;
}
.progress-card .progress-elapsed { font-size: 0.9rem; }

/* ----- 5-year forecast lens switcher -----
   The 5-year section is wrapped in `#forecast-lens-root` with a
   `data-active-lenses` attribute (space-separated list of currently
   visible lens keys, e.g. "internal blended"). Clicking a chip toggles
   that lens in/out of the list — JS handles the attribute mutation,
   CSS does the show/hide via [data-active-lenses~="X"] selectors. */

/* Lens panes (cumulative tile + YoY table rows): show the pane only if
   its lens is in the active set. Hidden by default; CSS rules below
   reveal each one when the root's data-active-lenses contains the
   matching key. `display: revert` lets tile divs render as block AND
   table rows render as table-row without needing two separate rules. */
#forecast-lens-root [data-lens-pane] { display: none; }
#forecast-lens-root[data-active-lenses~="internal"]  [data-lens-pane="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] [data-lens-pane="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   [data-lens-pane="central"],
#forecast-lens-root[data-active-lenses~="blended"]   [data-lens-pane="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] [data-lens-pane="pipeline_adjusted"] {
  display: revert;
}

/* Horizon-aware cumulative tiles: tile must match BOTH the active lens
   AND the active horizon. Hide if either condition fails. The cumulative
   tile grid renders 12 tiles (4 lenses × 3 horizons); the right one
   shows when both attributes line up. */
#forecast-lens-root [data-horizon-pane]:not([data-horizon-pane=""]) { display: none; }
#forecast-lens-root[data-horizon="1"][data-active-lenses~="internal"]  [data-lens-pane="internal"][data-horizon-pane="1"],
#forecast-lens-root[data-horizon="1"][data-active-lenses~="lower_end"] [data-lens-pane="lower_end"][data-horizon-pane="1"],
#forecast-lens-root[data-horizon="1"][data-active-lenses~="central"]   [data-lens-pane="central"][data-horizon-pane="1"],
#forecast-lens-root[data-horizon="1"][data-active-lenses~="blended"]   [data-lens-pane="blended"][data-horizon-pane="1"],
#forecast-lens-root[data-horizon="1"][data-active-lenses~="pipeline_adjusted"] [data-lens-pane="pipeline_adjusted"][data-horizon-pane="1"],
#forecast-lens-root[data-horizon="3"][data-active-lenses~="internal"]  [data-lens-pane="internal"][data-horizon-pane="3"],
#forecast-lens-root[data-horizon="3"][data-active-lenses~="lower_end"] [data-lens-pane="lower_end"][data-horizon-pane="3"],
#forecast-lens-root[data-horizon="3"][data-active-lenses~="central"]   [data-lens-pane="central"][data-horizon-pane="3"],
#forecast-lens-root[data-horizon="3"][data-active-lenses~="blended"]   [data-lens-pane="blended"][data-horizon-pane="3"],
#forecast-lens-root[data-horizon="3"][data-active-lenses~="pipeline_adjusted"] [data-lens-pane="pipeline_adjusted"][data-horizon-pane="3"],
#forecast-lens-root[data-horizon="5"][data-active-lenses~="internal"]  [data-lens-pane="internal"][data-horizon-pane="5"],
#forecast-lens-root[data-horizon="5"][data-active-lenses~="lower_end"] [data-lens-pane="lower_end"][data-horizon-pane="5"],
#forecast-lens-root[data-horizon="5"][data-active-lenses~="central"]   [data-lens-pane="central"][data-horizon-pane="5"],
#forecast-lens-root[data-horizon="5"][data-active-lenses~="blended"]   [data-lens-pane="blended"][data-horizon-pane="5"],
#forecast-lens-root[data-horizon="5"][data-active-lenses~="pipeline_adjusted"] [data-lens-pane="pipeline_adjusted"][data-horizon-pane="5"] {
  display: revert;
}

/* Horizon chip "active" state — driven by data-horizon attribute on root. */
#forecast-horizon-toggle .btn-small { cursor: pointer; }
#forecast-lens-root[data-horizon="1"] #forecast-horizon-toggle [data-horizon-target="1"],
#forecast-lens-root[data-horizon="3"] #forecast-horizon-toggle [data-horizon-target="3"],
#forecast-lens-root[data-horizon="5"] #forecast-horizon-toggle [data-horizon-target="5"] {
  background: var(--fg-strong, #000000);
  color: var(--surface, #fff);
  border-color: var(--fg-strong, #000000);
}

/* Decay glide-path table + Per-year table: hide year columns / rows past
   the active horizon. Year 1 is always visible; yr2-3 hidden at horizon=1;
   yr4-5 hidden at horizon=1 or 3; yr6+ terminal only shown at horizon=5. */
#forecast-lens-root[data-horizon="1"] [data-year-offset="2"],
#forecast-lens-root[data-horizon="1"] [data-year-offset="3"],
#forecast-lens-root[data-horizon="1"] [data-year-offset="4"],
#forecast-lens-root[data-horizon="1"] [data-year-offset="5"],
#forecast-lens-root[data-horizon="1"] [data-year-offset="terminal"],
#forecast-lens-root[data-horizon="3"] [data-year-offset="4"],
#forecast-lens-root[data-horizon="3"] [data-year-offset="5"],
#forecast-lens-root[data-horizon="3"] [data-year-offset="terminal"] {
  display: none;
}

/* Lens chip "active" state — chip lights up when its lens key is in the
   root's data-active-lenses list. Multi-select: any number of chips can
   be active at once. */
#forecast-lens-toggle .btn-small { cursor: pointer; }
#forecast-lens-root[data-active-lenses~="internal"]  #forecast-lens-toggle [data-lens-target="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] #forecast-lens-toggle [data-lens-target="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   #forecast-lens-toggle [data-lens-target="central"],
#forecast-lens-root[data-active-lenses~="blended"]   #forecast-lens-toggle [data-lens-target="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] #forecast-lens-toggle [data-lens-target="pipeline_adjusted"] {
  /* Active lens — match the standard chip active style (.chip.is-active):
     bold oxblood label + oxblood underline, NO solid fill. Keeps the
     forecast lens toggles identical to every other toggle on the dashboard
     (View / Time basis / view-by / catalog + payor chips). */
  color: var(--oxblood);
  font-weight: 600;
  border-bottom-color: var(--oxblood);
  background: transparent;
}

/* Chart lines / dots / legend: only render the series whose lens is in
   the active set. Hidden by default; revealed by matching ~= rules. */
#forecast-lens-root .fc-line,
#forecast-lens-root .fc-dot,
#forecast-lens-root .fc-legend-line,
#forecast-lens-root .fc-legend-text {
  display: none;
  transition: opacity 0.18s ease;
}
#forecast-lens-root[data-active-lenses~="internal"]  .fc-line[data-lens-key="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] .fc-line[data-lens-key="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   .fc-line[data-lens-key="central"],
#forecast-lens-root[data-active-lenses~="blended"]   .fc-line[data-lens-key="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] .fc-line[data-lens-key="pipeline_adjusted"],
#forecast-lens-root[data-active-lenses~="internal"]  .fc-dot[data-lens-key="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] .fc-dot[data-lens-key="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   .fc-dot[data-lens-key="central"],
#forecast-lens-root[data-active-lenses~="blended"]   .fc-dot[data-lens-key="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] .fc-dot[data-lens-key="pipeline_adjusted"],
#forecast-lens-root[data-active-lenses~="internal"]  .fc-legend-line[data-lens-key="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] .fc-legend-line[data-lens-key="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   .fc-legend-line[data-lens-key="central"],
#forecast-lens-root[data-active-lenses~="blended"]   .fc-legend-line[data-lens-key="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] .fc-legend-line[data-lens-key="pipeline_adjusted"],
#forecast-lens-root[data-active-lenses~="internal"]  .fc-legend-text[data-lens-key="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] .fc-legend-text[data-lens-key="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   .fc-legend-text[data-lens-key="central"],
#forecast-lens-root[data-active-lenses~="blended"]   .fc-legend-text[data-lens-key="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] .fc-legend-text[data-lens-key="pipeline_adjusted"] {
  display: inline;
}

/* Per-year comparison table: each column whose lens is in the active set
   is visible. Year column (no `data-lens-col`) is always shown. */
#forecast-lens-root .fc-lens-table [data-lens-col] { display: none; }
#forecast-lens-root[data-active-lenses~="internal"]  .fc-lens-table [data-lens-col="internal"],
#forecast-lens-root[data-active-lenses~="lower_end"] .fc-lens-table [data-lens-col="lower_end"],
#forecast-lens-root[data-active-lenses~="central"]   .fc-lens-table [data-lens-col="central"],
#forecast-lens-root[data-active-lenses~="blended"]   .fc-lens-table [data-lens-col="blended"],
#forecast-lens-root[data-active-lenses~="pipeline_adjusted"] .fc-lens-table [data-lens-col="pipeline_adjusted"] {
  display: table-cell;
}

/* ----- Click-to-sort table headers -----
   The table-sort.js module tags every sortable <th> with `.ts-sortable`
   and appends a `<span class="ts-arrow">` with the indicator glyph. The
   currently-sorted column also gets `.ts-active` on its <th>. */
.data-table th.ts-sortable {
  cursor: pointer;
  user-select: none;
  position: relative;
}
.data-table th.ts-sortable:hover {
  background: var(--surface-2, rgba(0, 0, 0, 0.03));
}
.data-table th .ts-arrow {
  display: inline-block;
  margin-left: 0.35rem;
  font-size: 0.7em;
  opacity: 0.25;
  transition: opacity 0.12s, color 0.12s;
  font-variant-numeric: normal;
  vertical-align: middle;
  /* Don't let the global lowercase transform mangle the arrow glyph
     (it's punctuation, but be explicit). */
  text-transform: none;
}
.data-table th.ts-sortable:hover .ts-arrow {
  opacity: 0.55;
}
.data-table th.ts-sortable.ts-active .ts-arrow,
.data-table th .ts-arrow.ts-active {
  opacity: 1;
  color: var(--accent, var(--fg-strong));
}
.data-table th.ts-active {
  color: var(--fg-strong);
}

/* ----- Top-of-page navigation progress bar -----
   Activates when the user clicks a plain link and there's a perceptible
   delay before the new page paints. Lives fixed at the very top, above
   everything else. Hidden by default; .visible to show. The inner bar
   uses the same sweep keyframe as the inline progress-bar above so the
   pulse animation is consistent across the app. */
.page-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: transparent;
  z-index: 10000;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease-out;
}
.page-progress.visible { opacity: 1; }
.page-progress-inner {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 35%;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-2) 50%, var(--accent) 100%);
  animation: progress-sweep 1.4s ease-in-out infinite;
  box-shadow: 0 0 8px rgba(88, 88, 88, 0.4);
}

/* ----- Roadmap (dashboard) ----- */

.roadmap { margin: 0; padding-left: 1.25rem; line-height: 1.8; color: var(--fg); }
.roadmap li.done { text-decoration: line-through; color: var(--muted); }

/* ----- Stats grid ----- */

/* CSS grid with auto-fit gives every card the same width regardless of
   how many are in the row. The old flex:1 layout produced uneven cards
   when 1, 2, or 3 cards were rendered, and made big dollar amounts
   overflow on narrower viewports. */
.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.9rem;
  background: none;
  border: none;
  padding: 0;
}

.stat {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 1rem 1.15rem 1.05rem;
  text-align: left;
  position: relative;
  overflow: hidden;
  min-width: 0;  /* let the grid clamp it instead of overflowing */
}
.stat::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--accent);
  opacity: 0.55;
}

.stat.stat-warn {
  background: var(--warn-bg);
  border-color: var(--warn-border);
}
.stat.stat-warn::before { background: var(--warn); opacity: 1; }

/* Vagabonds-era stat card — moss accent ("ours, growing") */
.stat.stat-vagabonds {
  background: var(--vagabonds-tint);
  border-color: var(--vagabonds-border);
}
.stat.stat-vagabonds::before { background: var(--vagabonds); opacity: 1; height: 3px; }
.stat.stat-vagabonds .stat-num { color: var(--vagabonds); }
.stat.stat-vagabonds .stat-label { color: var(--vagabonds); }

/* Historical (previous owner) stat card — walnut accent, slightly muted */
.stat.stat-historical {
  background: var(--historical-tint);
  border-color: var(--historical-border);
}
.stat.stat-historical::before { background: var(--historical); opacity: 1; height: 3px; }
.stat.stat-historical .stat-num { color: var(--historical); }
.stat.stat-historical .stat-label { color: var(--historical); }

/* Lifetime / combined stat card — neutral ink, no tint */
.stat.stat-lifetime::before { background: var(--accent); height: 3px; opacity: 0.85; }

/* Feature card — spans 2 grid columns for the single-view emphasis card. */
.stat.stat-feature {
  grid-column: span 2;
}
/* When we drop below ~520px the feature card collapses back to 1 col. */
@media (max-width: 560px) {
  .stat.stat-feature { grid-column: span 1; }
}

/* Section header bar — a thin "Earnings · view" label paired with a
   control on the right (the V/H toggle, or future controls). Keeps the
   horizontal rhythm consistent across the dashboard. */
.section-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0.25rem 0 0.75rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border-soft);
}
.section-label {
  margin: 0;
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: lowercase;
  color: var(--muted-strong);
  font-family: var(--font-display);
  font-weight: 600;
}

/* ----- View toggle (Vagabonds-only / Historical / Both) ----- */

.view-toggle {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  padding: 2px;
  gap: 0;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset;
}
.view-toggle a {
  padding: 0.4rem 0.9rem;
  font-family: var(--font-display);
  font-size: 0.82rem;
  text-transform: lowercase;
  letter-spacing: 0.08em;
  color: var(--muted-strong);
  text-decoration: none;
  border-radius: 4px;
  transition: background 0.12s, color 0.12s;
}
.view-toggle a:hover { color: var(--fg-strong); }
.view-toggle a.active-vagabonds {
  background: var(--vagabonds);
  color: var(--accent-fg);
}
.view-toggle a.active-historical {
  background: var(--historical);
  color: var(--accent-fg);
}
.view-toggle a.active-both {
  background: var(--accent);
  color: var(--accent-fg);
}
/* ----- Catalog selector (click-to-toggle chips) ----- */

.catalog-selector {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset;
}
.catalog-selector-label {
  font-family: var(--font-display);
  font-size: 0.72rem;
  text-transform: lowercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  font-weight: 600;
  margin-right: 0.4rem;
  align-self: center;
}
.catalog-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.85rem;
  font-size: 0.88rem;
  font-weight: 500;
  border: 2px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--muted);
  text-decoration: none;
  opacity: 0.6;
  transition: all 0.14s ease;
}
.catalog-chip::before {
  content: "";
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid var(--muted);
  border-radius: 3px;
  background: transparent;
  transition: all 0.14s ease;
}
.catalog-chip:hover {
  opacity: 0.9;
  border-color: var(--muted-strong);
  color: var(--fg-strong);
  background: var(--surface);
}
.catalog-chip.active {
  background: var(--vagabonds);
  color: var(--accent-fg);
  border-color: var(--vagabonds);
  opacity: 1;
  box-shadow: 0 2px 6px rgba(66, 66, 66, 0.25);
}
.catalog-chip.active::before {
  background: var(--accent-fg);
  border-color: var(--accent-fg);
  /* Checkmark via gradient — works in all modern browsers */
  background-image:
    linear-gradient(45deg, transparent 35%, var(--vagabonds) 36%, var(--vagabonds) 45%, transparent 46%),
    linear-gradient(-45deg, transparent 55%, var(--vagabonds) 56%, var(--vagabonds) 75%, transparent 76%);
}
.catalog-chip.active:hover {
  filter: brightness(1.08);
  box-shadow: 0 3px 8px rgba(66, 66, 66, 0.35);
}
/* "All" chip uses a different accent so it's visually distinct */
.catalog-chip.all-chip.active {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 2px 6px rgba(17, 17, 17, 0.3);
}
.catalog-chip.all-chip.active::before {
  background-image:
    linear-gradient(45deg, transparent 35%, var(--accent) 36%, var(--accent) 45%, transparent 46%),
    linear-gradient(-45deg, transparent 55%, var(--accent) 56%, var(--accent) 75%, transparent 76%);
}
/* Small separator between "All" and the per-catalog chips */
.catalog-selector .catalog-chip.all-chip {
  margin-right: 0.25rem;
}
/* ----- Sortable column headers ----- */

th.sortable {
  user-select: none;
  cursor: pointer;
  white-space: nowrap;
}
th.sortable .sort-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: inherit;
  text-decoration: none;
  font-weight: inherit;
}
th.sortable .sort-link:hover {
  color: var(--accent-hover);
}
th.sortable .sort-link:hover .sort-arrow {
  color: var(--accent);
  opacity: 1;
}
th.sortable .sort-arrow {
  font-size: 0.78rem;
  opacity: 0.35;
  transition: opacity 0.12s;
}
th.sortable .sort-arrow.muted {
  font-size: 0.7rem;
  opacity: 0.25;
}
th.sortable.is-sorted {
  background: var(--surface-2);
  color: var(--fg-strong);
}
th.sortable.is-sorted .sort-arrow {
  opacity: 1;
  color: var(--accent);
  font-weight: 600;
}

/* ----- File row (in statements list) ----- */

.file-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.15rem 0;
  max-width: 460px;
}
.file-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  text-decoration: none;
  color: var(--fg);
  font-size: 0.8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.file-link:hover { color: var(--accent-hover); }
.file-link:hover .file-name { text-decoration: underline; }
.file-name {
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, monospace;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.file-ext {
  display: inline-block;
  min-width: 32px;
  padding: 0.1rem 0.35rem;
  font-size: 0.65rem;
  font-weight: 600;
  text-align: center;
  border-radius: 3px;
  background: var(--surface-3);
  color: var(--muted-strong);
  letter-spacing: 0.05em;
  flex-shrink: 0;
}
.file-ext-pdf { background: var(--muted-strong); color: var(--accent-fg); }
.file-ext-csv { background: var(--muted-strong); color: var(--accent-fg); }
.file-dl {
  display: inline-block;
  padding: 0.1rem 0.35rem;
  font-size: 0.95rem;
  text-decoration: none;
  color: var(--muted);
  border-radius: 3px;
  flex-shrink: 0;
}
.file-dl:hover {
  color: var(--accent);
  background: var(--surface-2);
}

.catalog-selector .selector-divider {
  display: inline-block;
  width: 1px;
  height: 22px;
  background: var(--border);
  margin: 0 0.3rem;
}

.view-toggle .view-toggle-label {
  padding: 0.4rem 0.75rem 0.4rem 0.5rem;
  font-family: var(--font-display);
  font-size: 0.78rem;
  text-transform: lowercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  border-right: 1px solid var(--border-soft);
  align-self: center;
  margin-right: 2px;
}

/* ----- Charts ----- */

.chart-scroll {
  /* Lets wide charts (16+ quarters) scroll horizontally on narrow viewports
     instead of getting scaled into illegibility. The SVG itself uses
     width: 100%; preserveAspectRatio so the chart fills the container
     when it fits, scrolls when it doesn't. Charts are CENTERED in their
     container so when the chart is narrower than the page (year view
     with 4-5 bars, etc.) it doesn't hug the left edge. */
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.75rem 0 0.25rem;
  -webkit-overflow-scrolling: touch;
  display: flex;
  justify-content: center;
}
.chart-scroll svg {
  display: block;
  margin: 0 auto;
}

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.7rem 1.1rem;
  padding: 0.55rem 0 0.2rem;
}

/* Acquisition-cutoff legend — shown above the chart, lists each catalog
   and its cutoff date. Each item starts with a small dashed-line mark
   that matches the in-chart vertical dashed line, so the eye can map
   "Mike Suby (2022-10-01)" → the dashed line at the 2022 boundary. */
.acq-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1.1rem;
  margin: 0.5rem 0 0.25rem;
  padding: 0.45rem 0.75rem;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font-size: 0.82rem;
  color: var(--muted-strong);
}
.acq-legend-label {
  font-family: var(--font-display);
  text-transform: lowercase;
  letter-spacing: 0.1em;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted);
}
.acq-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
}
.acq-legend-mark {
  display: inline-block;
  width: 2px;
  height: 14px;
  background: repeating-linear-gradient(
    to bottom,
    var(--ribbon) 0,
    var(--ribbon) 3px,
    transparent 3px,
    transparent 6px
  );
  opacity: 0.8;
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.82rem;
  color: var(--muted-strong);
}
.legend-swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  border: 1px solid rgba(0,0,0,0.08);
}

/* Forecast-chart legend uses an inline SVG (line + marker) — don't
   constrain its size with the generic .legend-swatch dimensions.
   The SVG's own width/height attributes control the swatch size. */
.legend-swatch.fc-legend-line {
  width: auto;
  height: auto;
  border: none;
  border-radius: 0;
}

/* ----- Numeric / mono utility ----- */

.num {
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, "Courier New", monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
td.num, th.num {
  text-align: right;
}

/* Music/Blink consolidated valuation helpers (Classic fallback; modern.css
   adds the centered-column alignment). */
.val-table { width: 100%; max-width: 640px; }
.val-table tr.rule > td { border-top: 1px solid #d9cba8; }
.val-table tr.hi > td { background: #fbf5e6; }
.val-table .pos { color: #2f5128; }
.val-h { font-size: 1rem; font-weight: 600; margin: 1.4rem 0 0.35rem; }
.val-h.sub { font-size: 0.92rem; margin-top: 1.1rem; }
.val-note { font-size: 0.82em; line-height: 1.5; max-width: 80ch; margin: 0.4rem 0 0; }
.val-more { margin: 1.1rem 0 0; }
.val-more > summary { cursor: pointer; color: #7a2d2d; }

/* Vagabonds-era / Historical column cell coloring in tables */
td.cell-vagabonds, .text-vagabonds { color: var(--vagabonds); font-weight: 500; }
td.cell-historical, .text-historical { color: var(--historical); opacity: 0.85; }
th.col-vagabonds { color: var(--vagabonds); border-bottom-color: var(--vagabonds-border) !important; }
th.col-historical { color: var(--historical); border-bottom-color: var(--historical-border) !important; }

.stat-num {
  /* clamp(min, ideal, max): cards always fit big dollar amounts but
     scale down gracefully on narrow viewports. The old fixed 1.85rem
     overflowed when totals hit eight figures + .2f. */
  font-size: clamp(1.25rem, 2.4vw, 1.65rem);
  font-weight: 500;
  color: var(--fg-strong);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.15;
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, "Courier New", monospace;
  word-break: break-word;  /* belt-and-suspenders so no number ever clips */
}
.stat.stat-feature .stat-num {
  font-size: clamp(1.6rem, 3.4vw, 2.1rem);
}

.stat-label {
  font-size: 0.72rem;
  color: var(--muted-strong);
  text-transform: lowercase;
  letter-spacing: 0.09em;
  margin-top: 0.45rem;
  font-weight: 600;
  font-family: var(--font-display);
}

.stat-link {
  display: block;
  margin-top: 0.55rem;
  font-size: 0.85rem;
  color: var(--accent);
  text-decoration: none;
}
.stat-link:hover { color: var(--accent-hover); text-decoration: underline; }

/* ----- Forms ----- */

.form-row { margin-bottom: 1.05rem; }

.form-row label {
  display: block;
  font-weight: 500;
  font-size: 0.84rem;
  margin-bottom: 0.4rem;
  color: var(--muted-strong);
  letter-spacing: 0.04em;
  text-transform: lowercase;
  font-family: var(--font-display);
}

.form-row label.inline {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: normal;
  letter-spacing: 0;
}

.form-row input[type="text"],
.form-row input[type="number"],
.form-row input[type="date"],
.form-row input[type="email"],
.form-row input[type="password"],
.form-row select,
.form-row textarea {
  width: 100%;
  padding: 0.55rem 0.8rem;
  background: var(--surface);
  color: var(--fg-strong);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: inherit;
  box-shadow: none;
  transition: border-color 0.12s, box-shadow 0.12s, background 0.12s;
}

.form-row input[type="text"]:focus,
.form-row input[type="number"]:focus,
.form-row input[type="date"]:focus,
.form-row input[type="email"]:focus,
.form-row input[type="password"]:focus,
.form-row select:focus,
.form-row textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

/* Global selects / inputs that aren't wrapped in .form-row (e.g. pivot
   dropdowns, year inputs in the sticky toolbar) get the same paper-slip
   treatment so the look stays cohesive everywhere. */
select,
input[type="text"],
input[type="number"],
input[type="date"],
input[type="email"],
input[type="search"] {
  background: var(--surface);
  color: var(--fg-strong);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.36rem 0.7rem;
  font-family: inherit;
  font-size: 0.85rem;
  box-shadow: none;
  transition: border-color 0.12s, box-shadow 0.12s, background 0.12s;
  cursor: pointer;
}
select:focus,
input[type="text"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="email"]:focus,
input[type="search"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

/* Native select arrow doesn't theme cleanly — replace with a custom
   chevron that matches the patina aesthetic. Layered backgrounds: the
   chevron SVG sits on top of the ivory gradient. */
select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background:
    url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3e%3cpath fill='%232a1f0d' d='M0 0l5 6 5-6z'/%3e%3c/svg%3e")
    no-repeat right 0.6rem center / 10px 6px,
    var(--surface);
  padding-right: 1.8rem;
}

.form-row textarea {
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, "Courier New", monospace;
  font-size: 0.88rem;
  line-height: 1.55;
}

.form-row.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.required { color: var(--bad); }

.filter-row {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  align-items: end;
  margin: 0;
}

.filter-row label {
  display: flex;
  flex-direction: column;
  font-size: 0.82rem;
  color: var(--muted-strong);
  text-transform: lowercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  font-family: var(--font-display);
}

.filter-row select,
.filter-row input[type="text"] {
  padding: 0.45rem 0.6rem;
  background: var(--surface-solid);
  color: var(--fg-strong);
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 0.92rem;
  font-family: inherit;
  margin-top: 0.3rem;
  letter-spacing: 0;
}
/* Filter-row text input keeps the user's typed case, but the select's
   option text uses the global lowercase like everywhere else. */
.filter-row input[type="text"] {
  text-transform: none;
}

/* ----- Badges / pills ----- */

.badge {
  display: inline-block;
  padding: 0.05rem 0.38rem;
  border-radius: 4px;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  border: 1px solid transparent;
  font-family: var(--font-display);
  line-height: 1.4;
  vertical-align: middle;
}

.badge-us       { background: var(--good-bg);   color: var(--good);   border-color: var(--good-border); }
.badge-ok       { background: var(--good-bg);   color: var(--good);   border-color: var(--good-border); }
.badge-external { background: var(--surface-2); color: var(--muted-strong); border-color: var(--border); }
.badge-warn     { background: var(--warn-bg);   color: var(--warn);   border-color: var(--warn-border); }

/* ----- Pagination ----- */

.pagination {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}
.pagination a { color: var(--accent); }
.pagination a:hover { color: var(--accent-hover); }

.muted { color: var(--muted); font-size: 0.9rem; }
.muted code { color: var(--muted-strong); }
.result-summary { color: var(--muted); font-size: 0.9rem; }

/* ----- Dropzone ----- */

.dropzone {
  border: 1.5px dashed var(--border);
  border-radius: 6px;
  padding: 1.6rem 1rem;
  text-align: center;
  background: var(--surface-solid);
  transition: background 0.15s, border-color 0.15s;
  cursor: pointer;
  color: var(--muted-strong);
}

.dropzone:hover {
  background: var(--surface-2);
  border-color: var(--accent);
}

.dropzone.dragover {
  background: var(--surface-2);
  border-color: var(--accent);
  border-style: solid;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.dropzone-prompt { pointer-events: none; color: var(--muted-strong); }
.dropzone-prompt strong { color: var(--fg-strong); font-size: 1rem; }

.dropzone input[type="file"] {
  display: block;
  margin: 1rem auto 0;
  cursor: pointer;
  color: var(--muted-strong);
}

.file-list { margin-top: 0.5rem; color: var(--muted-strong); }

/* ----- Detection status colour modifiers ----- */

.detection-status {
  margin-top: 0.55rem;
  padding: 0.55rem 0.8rem;
  border-radius: 4px;
  font-size: 0.88rem;
  min-height: 1.4em;
  border: 1px solid transparent;
}
.detection-status:empty { padding: 0; border: 0; }

.detection-ok   { background: var(--good-bg); border-color: var(--good-border); color: var(--good); }
.detection-warn { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn); }
.detection-info { background: var(--surface-2); border-color: var(--border); color: var(--fg-strong); }
.detection-ai   { background: var(--surface-2); border-color: var(--border-soft); color: var(--muted-strong); }

/* ----- Quick-create disclosure ----- */

.quick-create {
  margin-top: 0.6rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-solid);
}

.quick-create summary {
  cursor: pointer;
  font-size: 0.88rem;
  color: var(--accent);
}
.quick-create summary:hover { color: var(--accent-hover); }

/* ----- Misc ----- */

.reasons { margin: 0; padding-left: 1.1rem; font-size: 0.88rem; }
.reasons li { margin-bottom: 0.15rem; }

details > summary { cursor: pointer; }

input[type="checkbox"] {
  accent-color: var(--accent);
  width: 1rem;
  height: 1rem;
  vertical-align: middle;
}

hr {
  border: none;
  border-top: 1px solid var(--border-soft);
  margin: 1.5rem 0;
}

/* Inset panel for collapsed "more options" sections */
.subtle-panel {
  margin-top: 0.6rem;
  padding: 0.75rem 1rem;
  background: var(--surface-solid);
  border: 1px solid var(--border-soft);
  border-radius: 5px;
}

/* Row + callout styles for items flagged as needs-review */
tr.flag-row, .flag-row {
  background: var(--warn-bg) !important;
}
.flag-callout {
  margin-top: 0.5rem;
  padding: 0.55rem 0.8rem;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-left: 3px solid var(--warn);
  border-radius: 5px;
  color: var(--warn);
}
.flag-callout strong { color: var(--warn); }

/* ----- Footer ----- */

footer {
  border-top: 1px solid var(--border-soft);
  padding: 1.25rem 0;
  margin-top: 3rem;
  color: var(--muted-strong);
  background: transparent;
}

footer small {
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  font-family: var(--font-display);
}

footer .container {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

/* Theme picker — small inline link group in footer. Active theme
   highlighted via accent color + bold; inactive themes click-to-switch. */
.theme-picker { color: var(--muted); }
.theme-picker a {
  color: var(--muted-strong);
  text-decoration: none;
  letter-spacing: 0.05em;
  padding: 0 0.2rem;
}
.theme-picker a:hover { color: var(--fg-strong); text-decoration: underline; }
.theme-picker a.is-active {
  color: var(--accent);
  font-weight: 600;
  border-bottom: 2px solid var(--accent);
}


/* ----- Scrollbar (webkit only — graceful degrade elsewhere) ----- */

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: var(--surface-3); background-clip: content-box; }

/* ============================================================================
   DASHBOARD POLISH OVERHAUL — 2026-05-25
   ----------------------------------------------------------------------------
   Cleaner spacing, tighter type hierarchy, Apple-ish restraint.
   Applies to the dashboard hero / filter bar / metric strips / sections.
   Older classes (.card, .stat, .stats-row) continue to work for the rest
   of the app; the overhaul classes (.hero-, .metric-, .section--, .toolbar)
   are NEW and used only on /home.
   ============================================================================ */

/* Container — tighter max-width + comfortable horizontal padding */
.container.container--wide { max-width: 1240px; padding: 0 2rem; }
@media (max-width: 720px) {
  .container.container--wide { padding: 0 1.25rem; }
}

/* ---------- Brand hero (compact) ----------
   The "Vagabonds" wordmark is baked into the image artwork. We only render
   the "Royalty Intelligence" subtitle underneath — in the same typewriter
   face as the header tagline for visual consistency. */
.brand-hero.brand-hero--compact {
  /* Symmetric vertical padding so the figure has the same headroom
     above as the subtitle has gap below. */
  padding: 1.5rem 0 1.5rem;
  margin: 0 0 1rem;
  border-bottom: none;
}
.brand-hero--compact img.brand-logo-hero {
  height: 336px;            /* 30% smaller than the previous 480px */
  max-width: 90%;
  width: auto;
  object-fit: contain;
  filter: drop-shadow(0 4px 14px rgba(44, 44, 44, 0.18));
  mix-blend-mode: multiply;
  /* Only the BOTTOM is heavily cropped — the PNG's bottom whitespace
     is absorbed so the subtitle hugs the wordmark. Top stays at
     0 (or a small negative) so the silhouette's hat has clear
     headroom under the header bar. */
  margin-top: 0;
  margin-bottom: -4.5rem;
}
.brand-hero--compact .brand-subtitle {
  font-size: 0.95rem;
  letter-spacing: 0.22em;
  margin: 0;
}

/* ---------- Hero stat — the big primary number ---------- */
.hero-stat {
  padding: 1.6rem 1.8rem 1.5rem;
  border-radius: 12px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0) 100%),
    var(--surface);
  border: 1px solid var(--border-soft);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.55) inset,
    0 4px 16px -8px rgba(44, 44, 44, 0.18);
  margin-bottom: 1.5rem;
  text-align: center;
}
.hero-stat--vagabonds {
  background:
    linear-gradient(180deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 100%),
    var(--vagabonds-tint);
  border-color: var(--vagabonds-border);
}
.hero-stat--historical {
  background:
    linear-gradient(180deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 100%),
    var(--historical-tint);
  border-color: var(--historical-border);
}
.hero-stat-eyebrow {
  font-family: var(--font-display);
  font-size: 0.7rem;
  text-transform: lowercase;
  letter-spacing: 0.14em;
  font-weight: 600;
  color: var(--muted-strong);
  margin: 0 0 0.5rem;
}
.hero-stat--vagabonds .hero-stat-eyebrow { color: var(--vagabonds); }
.hero-stat--historical .hero-stat-eyebrow { color: var(--historical); }
.hero-stat-num {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.4rem, 5.5vw, 3.5rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.005em;
  color: var(--fg-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0 0 0.4rem;
  /* Inked-typebar emboss — faint shadow underneath, like the digit was
     struck onto the page. 1920s ledger feel. */
  text-shadow: 0 1px 0 rgba(249, 249, 249, 0.5), 0 2px 3px rgba(31, 31, 31, 0.08);
}
.hero-stat--vagabonds .hero-stat-num { color: var(--vagabonds); }
.hero-stat--historical .hero-stat-num { color: var(--historical); }
.hero-stat-caption {
  color: var(--muted-strong);
  font-size: 0.9rem;
  margin: 0;
}

/* ---------- Metric strip — compact "label · value" pairs ---------- */
.metric-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0;
  padding: 1.1rem 0 0;
  margin-top: 1.1rem;
  border-top: 1px solid var(--border-soft);
}
.metric {
  padding: 0 1.2rem;
  border-left: 1px solid var(--border-soft);
  min-width: 0;
}
.metric:first-child { border-left: none; }
.metric-label {
  font-family: var(--font-display);
  font-size: 0.66rem;
  text-transform: lowercase;
  letter-spacing: 0.13em;
  font-weight: 600;
  color: var(--muted);
  margin: 0 0 0.3rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.metric-value {
  font-family: "Courier Prime", "JetBrains Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  font-weight: 500;
  color: var(--fg-strong);
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.metric-sub {
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 0.25rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.metric-trend--up   { color: var(--good); }
.metric-trend--down { color: var(--bad); }

/* ---------- Sections — generous whitespace, typewriter-strip headers ----
   Sections feel like sheets of paper rolled into the typewriter — each
   one's title sits at the top with a thin brass-tone underline (like a
   typewriter ruled line). Generous top margin between sections so the
   page reads as a stack of distinct documents, not one long scroll. */
.section {
  margin: 2.5rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border-soft);
  position: relative;
}
.section::before {
  display: none;
}
.section:first-of-type {
  margin-top: 0;
  border-top: none;
  padding-top: 0;
}
.section:first-of-type::before {
  display: none;
}
.section-header {
  display: flex;
  align-items: baseline;
  justify-content: center;
  text-align: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.2rem;
}
.section-title {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--fg-strong);
  letter-spacing: 0.01em;
  font-family: var(--font-display);
  text-align: center;
}
.section-hint {
  color: var(--muted-strong);
  font-size: 0.82rem;
  font-style: italic;
  text-align: center;
}

/* ---------- Sticky global toolbar wrapper ----------
   The View / Time basis / Perspective / Granularity / Catalogs / Payors
   chip rows live inside this wrapper so they pin to the top of the
   viewport when scrolling. Keeps the user's filter context visible at
   all times. The cream parchment background extends edge-to-edge with
   a subtle bottom shadow when scrolled-past so it visually separates
   from the content underneath. */
/* Full-viewport-width sticky toolbar.
   Breaks out of the .container's max-width using the negative-margin /
   100vw trick: `width: 100vw; margin-left: calc(50% - 50vw)` shifts it
   to the left edge of the viewport regardless of where the parent is.
   Inner .toolbar rows keep the .container's max-width so the chips
   don't sprawl across an ultra-wide monitor. */
.dashboard-toolbar-sticky {
  position: sticky;
  top: 0;
  z-index: 100;
  /* Full-width breakout */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  margin-bottom: 1.5rem;
  padding: 0.6rem 0;
  background: rgba(253, 253, 253, 0.96);
  backdrop-filter: saturate(120%) blur(6px);
  -webkit-backdrop-filter: saturate(120%) blur(6px);
  border-bottom: 1px solid var(--border-soft);
  box-shadow: 0 1px 0 var(--border-soft);
}
/* Inner toolbar rows respect the page's max-width so chips stay aligned
   with the rest of the dashboard content, not edge-aligned to the
   viewport. */
.dashboard-toolbar-sticky .toolbar {
  max-width: 1200px;
  margin: 0 auto 0.4rem;
  padding: 0 1rem;
}
.dashboard-toolbar-sticky .toolbar:last-child {
  margin-bottom: 0;
}

/* ---------- Toolbar — single-row filter strip ---------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem 1.2rem;
  padding: 0.6rem 0.85rem;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 0;
}
.toolbar-label {
  font-family: var(--font-display);
  font-size: 0.68rem;
  text-transform: lowercase;
  letter-spacing: 0.14em;
  font-weight: 600;
  color: var(--muted);
  margin-right: 0.4rem;
  /* Match the baseline of the text-link chips next to it */
  padding-bottom: 2px;
}
.toolbar-divider {
  display: inline-block;
  width: 1px;
  height: 18px;
  background: var(--border-soft);
  margin: 0 0.35rem;
  vertical-align: middle;
}

/* Toolbar group — wraps a label + its chips as ONE unit so the row
   wraps cleanly between groups instead of splitting "Granularity / Year"
   across two lines. Each group is its own inline-flex row that stays
   together (nowrap inside), and the outer .toolbar wraps groups
   between them when there's not enough horizontal space. */
.toolbar-group {
  display: inline-flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 0.4rem;
}
/* Duplicate .chip block removed 2026-05-27. The chip + btn-small unified
   keycap styling lives near the top of this file (line ~685). Having a
   second .chip definition here was overriding the unified styles with
   a less-developed version (1px border, smaller bezel, no triple-layer
   bezel) — causing toolbar chips to render visibly DIFFERENT from the
   lens chips and the nav buttons. With this block gone, all .chip
   instances share the same vintage-key look. */

/* ---------- Stat card grid (refined .card style) ---------- */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}
.tile {
  padding: 1.2rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(26, 26, 26, 0.04);
  min-width: 0;
}
.tile-title {
  margin: 0 0 0.85rem;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--fg-strong);
  letter-spacing: -0.005em;
}
.tile-title-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0 0 0.85rem;
}
.tile-title-row .tile-title { margin: 0; }
.tile-link {
  font-size: 0.8rem;
  color: var(--muted-strong);
  text-decoration: none;
}
.tile-link:hover { color: var(--accent-hover); text-decoration: underline; }

/* Tighter data-table inside tiles */
.tile .data-table { font-size: 0.85rem; }
.tile .data-table th {
  font-size: 0.7rem;
  text-transform: lowercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-weight: 500;
  border-bottom: 1px solid var(--border-soft);
  padding: 0.45rem 0.7rem;
}
.tile .data-table td {
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--border-soft);
}
.tile .data-table tr:last-child td { border-bottom: none; }

/* ============================================================
   Statements list page — polished layout
   ============================================================ */

/* Consolidated filter panel — replaces three stacked .catalog-selector
   boxes with one card holding three internal rows. Reduces vertical
   chrome before the data table. */
.filter-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset;
  padding: 0.55rem 0.9rem;
  margin-bottom: 1rem;
}
.filter-panel-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0;
}
.filter-panel-row + .filter-panel-row {
  border-top: 1px dashed var(--border-soft);
  margin-top: 0.1rem;
}

/* Visible "click to sort" hint above the table — addresses the "I don't
   understand the sorting here" feedback by making the affordance explicit
   instead of relying on subtle arrows alone. */
.sort-hint-line {
  margin: 0.1rem 0 0.6rem;
  padding: 0.5rem 0.85rem;
  font-size: 0.85rem;
  color: var(--muted-strong);
  background: var(--surface-2);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
}
.sort-hint-line strong { color: var(--fg-strong); }
.sort-hint-icon {
  display: inline-block;
  margin-right: 0.3rem;
  color: var(--accent);
  font-weight: 600;
}

/* Statements table cells — tighter, more proportional */
table.statements-table {
  table-layout: auto;
  font-size: 0.88rem;
}
table.statements-table th,
table.statements-table td {
  padding: 0.5rem 0.55rem;
  vertical-align: top;
}
table.statements-table tr.row-historical { opacity: 0.72; }
table.statements-table .stmt-cell {
  min-width: 180px;
  max-width: 260px;
}
table.statements-table .stmt-label { color: var(--fg-strong); text-decoration: none; }
table.statements-table .stmt-label:hover { color: var(--accent); text-decoration: underline; }

/* Period column — stacked dates, tight and narrow */
.period-cell {
  white-space: nowrap;
  font-size: 0.78rem;
  line-height: 1.35;
}
.period-cell .num { display: block; }
.period-cell .period-arrow { display: none; }   /* stack vertically, no arrow */

/* File row variant used inside the statement cell — smaller, tighter */
.file-row.file-row-compact {
  max-width: 240px;
  margin: 0.25rem 0 0;
}
.file-row.file-row-compact .file-link { font-size: 0.72rem; }
.file-row.file-row-compact .file-ext {
  font-size: 0.58rem;
  min-width: 26px;
  padding: 0.05rem 0.28rem;
}

/* Combined matches column — one row of three numbers with subtle separators */
.matches-cell { white-space: nowrap; }
.match-counts {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-variant-numeric: tabular-nums;
}
.match-auto      { color: var(--vagabonds); font-weight: 500; }
.match-pending   { color: var(--muted-strong); font-weight: 500; text-decoration: none; }
.match-pending:hover   { text-decoration: underline; }
.match-unmatched { color: var(--fg-strong); font-weight: 500; text-decoration: none; }
.match-unmatched:hover { text-decoration: underline; }
.match-zero      { color: var(--muted); }
.match-sep       { color: var(--border); margin: 0 0.05rem; }

.match-legend {
  margin: 0.6rem 0 0;
  padding: 0 0.2rem;
  font-size: 0.78rem;
}
.match-legend .match-auto,
.match-legend .match-pending,
.match-legend .match-unmatched {
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
  background: var(--surface-2);
  font-weight: 500;
}

/* ----- Universal table overflow containment -----
   Any .card that contains a .data-table will scroll horizontally
   *inside* the card rather than letting columns spill past its right
   edge onto the page background. Applied via :has() so no template
   markup change is required — every list page on the site benefits.

   .data-card is kept as an explicit alias for templates that want the
   tighter padding too. */
.card:has(.data-table),
.data-card {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.card:has(.data-table) > .data-table,
.data-card > .data-table { min-width: 0; }
.data-card { padding: 0.4rem 0.6rem; }

/* ----- Universal sort-header visibility -----
   Inactive ⇅ arrows used to be at 25% opacity (basically invisible).
   Bump to 55% everywhere so column headers consistently read as
   clickable across statements, parties, works, and any future pages. */
th.sortable .sort-arrow.muted { opacity: 0.55; }
th.sortable .sort-link {
  border-bottom: 1px dotted transparent;
  padding-bottom: 1px;
}
th.sortable .sort-link:hover { border-bottom-color: var(--accent); }

/* Compact badge size when used inside the data table — the parse_status
   badges were rendering oversized relative to the table density. */
table.statements-table .badge {
  font-size: 0.7rem;
  padding: 0.15rem 0.45rem;
}

/* The "Open" action button — keep it small and right-aligned so it doesn't
   eat horizontal room. */
table.statements-table td:last-child { white-space: nowrap; text-align: right; }
table.statements-table td:last-child .btn-small {
  padding: 0.25rem 0.65rem;
  font-size: 0.78rem;
}

/* "PDF only" badge — distinct amber styling so cover-sheet-only statements
   stand apart from fully parsed ones at a glance. Slightly more visible
   than badge-warn (failed) because these are still good data, just
   awaiting line-level detail. */
.badge.badge-pdf-only {
  background: var(--surface-3);
  color: var(--muted-strong);
  border: 1px dashed var(--border);
  font-weight: 500;
}

/* ============================================================
   UMPG sub-account audit page
   ============================================================ */
.audit-catalog-card { padding: 0.6rem 0.9rem 0.9rem; }
.audit-catalog-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.2rem 0 0.6rem;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 0.5rem;
}
.audit-catalog-summary {
  display: inline-flex;
  gap: 0.45rem;
  align-items: center;
  font-size: 0.85rem;
  flex-wrap: wrap;
}

.audit-pivot {
  font-size: 0.82rem;
}
.audit-pivot th,
.audit-pivot td {
  padding: 0.35rem 0.55rem;
  white-space: nowrap;
}
.audit-pivot th.sub-active {
  color: var(--vagabonds);
  font-weight: 600;
}
.audit-pivot .sub-active-dot {
  display: inline-block;
  margin-left: 0.2rem;
  color: var(--vagabonds);
}
.audit-pivot tr.row-latest {
  background: var(--surface-2);
  border-top: 2px solid var(--accent);
}
.audit-pivot tr.row-latest td { font-weight: 500; }

.audit-pivot td.cell-has-money a {
  color: var(--fg-strong);
  text-decoration: none;
}
.audit-pivot td.cell-has-money a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* Multi-statement cells show each contributing payment inline with a "+"
   between them. Slightly smaller and tighter so two figures fit
   comfortably in a normal-width cell; the "+" is dimmed so the dollar
   amounts are the visual anchor. Each amount is its own link. */
.audit-pivot td.cell-has-money .audit-cell-multi {
  display: inline-block;
  font-size: 0.88em;
  white-space: nowrap;
  letter-spacing: -0.01em;
}
.audit-pivot td.cell-has-money .audit-cell-multi a {
  font-variant-numeric: tabular-nums;
}
.audit-pivot td.cell-has-money .audit-plus {
  color: var(--muted);
  margin: 0 0.25rem;
  font-weight: 400;
}
.audit-pivot td.cell-empty {
  color: var(--border);
}
.audit-pivot td.cell-missing {
  background: var(--surface-2);
  color: var(--fg-strong);
  font-weight: 500;
  border: 1px dashed var(--fg-strong);
}
.audit-pivot tr.row-missing-quarter {
  background: var(--surface-2);
  border: 1px dashed var(--muted-strong);
}
.audit-pivot tr.row-missing-quarter td:first-child {
  color: var(--muted-strong);
  font-weight: 600;
}
.audit-pivot td.quarter-missing-banner {
  color: var(--muted-strong);
  font-weight: 500;
  font-size: 0.82rem;
  letter-spacing: 0.01em;
}

/* Legend chips above the pivot */
.legend-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.55rem;
  font-size: 0.78rem;
  border-radius: 4px;
  margin-right: 0.4rem;
}
.legend-cell--has-money {
  background: var(--surface-2);
  color: var(--fg-strong);
}
.legend-cell--empty {
  background: transparent;
  color: var(--muted);
  border: 1px dashed var(--border-soft);
}
.legend-cell--missing {
  background: var(--surface-2);
  color: var(--fg-strong);
  border: 1px dashed var(--fg-strong);
  font-weight: 500;
}

/* ---------- Statements list: bulk download + per-row actions ---------- */
.bulk-dl-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 0.85rem;
}
.bulk-dl-count {
  font-size: 0.85rem;
  font-weight: 600;
}
.bulk-dl-hint {
  font-size: 0.8rem;
}
.row-actions {
  white-space: nowrap;
}
.row-actions .btn-small { margin-right: 0.25rem; }
/* keep the select-all / row checkboxes tidy + easy to tap */
.statements-table input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
}
@media (max-width: 720px) {
  .bulk-dl-hint { display: none; }
}


/* ============================================================
   Statements filter bar — checkmark dropdowns + typed year
   (replaces the old chip rows; same URL contract). 2026-05-29
   ============================================================ */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1rem;
  margin-bottom: 1rem;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
}
.filter-dd { position: relative; }
.filter-dd-trigger {
  font: inherit;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.4rem 0.7rem;
  color: var(--oxblood);
  white-space: nowrap;
}
.filter-dd-trigger:hover { border-color: var(--oxblood); }
.filter-dd-trigger .filter-dd-summary { font-weight: 600; }
.filter-dd-trigger .nav-caret { color: var(--muted); }
.filter-dd-panel {
  position: absolute;
  z-index: 200;
  top: calc(100% + 0.35rem);
  left: 0;
  min-width: 230px;
  max-height: 340px;
  overflow-y: auto;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  padding: 0.4rem;
}
.filter-dd-opt {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.34rem 0.5rem;
  border-radius: 5px;
  cursor: pointer;
  white-space: nowrap;
}
.filter-dd-opt:hover { background: var(--border-soft); }
.filter-dd-opt input { margin: 0; flex: none; }
.filter-dd-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  padding: 0.45rem 0.3rem 0.15rem;
  border-top: 1px solid var(--border-soft);
  margin-top: 0.35rem;
  position: sticky;
  bottom: 0;
  background: var(--surface-solid);
}
.filter-year { display: flex; align-items: center; gap: 0.45rem; }
.filter-year-input {
  width: 5.5rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font: inherit;
}
.filter-clear-all { margin-left: auto; color: var(--muted); font-size: 0.85rem; }
.filter-clear-all:hover { color: var(--oxblood); }

/* Armed (second-click) state for two-step delete buttons — see confirm-delete.js */
.armed-delete {
  background: var(--bad) !important;
  border-color: var(--bad) !important;
  color: #fff !important;
  font-weight: 600;
}

/* Statements filter — from–to date range */
.filter-dates { display: flex; align-items: center; gap: 0.4rem; }
.filter-date-input {
  padding: 0.32rem 0.45rem;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font: inherit;
}
.filter-dates-sep { color: var(--muted); }
