/* ==========================================================================
   StockProof design system — "working paper"
   Light document ground, ink-navy text, provenance-teal + aged-ledger ochre.
   Type: Archivo (display) / IBM Plex Sans (body) / IBM Plex Mono (data).
   Self-hosted fonts live in ../fonts (vendored, no CDN).
   ========================================================================== */

/* ---- fonts: latin + latin-ext (latin-ext carries the ₹ glyph, U+20B9) ---- */
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/Archivo-600.cd56e2ec63d7.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/Archivo-600-ext.c5e41aa17045.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../fonts/Archivo-700.cd56e2ec63d7.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../fonts/Archivo-700-ext.c5e41aa17045.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 800; font-display: swap;
  src: url("../fonts/Archivo-800.cd56e2ec63d7.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 800; font-display: swap;
  src: url("../fonts/Archivo-800-ext.c5e41aa17045.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/IBMPlexSans-400.b2c9031d9fd6.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/IBMPlexSans-400-ext.f0e2925b3fa6.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/IBMPlexSans-500.b2c9031d9fd6.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/IBMPlexSans-500-ext.f0e2925b3fa6.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/IBMPlexSans-600.b2c9031d9fd6.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/IBMPlexSans-600-ext.f0e2925b3fa6.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/IBMPlexMono-400.79936b18df9f.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/IBMPlexMono-400-ext.8450d5944de2.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/IBMPlexMono-500.b1c8a895f5fd.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/IBMPlexMono-500-ext.fa8d8838b94a.woff2") format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* ---- tokens ---- */
:root {
  --paper: #EEF0EC;
  --surface: #FBFCFA;
  --ink: #182231;
  --verified: #0E6E63;
  --verified-ink: #0A5751;
  --attention: #875710;
  --slate: #5B6572;
  --rule: #D7DBD5;
  --rule-strong: #BFC5BD;
  --risk: #A23B2E;
  /* Text color for content sitting on a SOLID accent-colored fill (the
     primary button, the active portfolio-switcher tab, a share-link
     badge) -- white reads fine on light-mode's mid-dark --verified, but
     the dark palette's brighter --verified needs a dark ink text instead
     to still clear AA, so this is redefined per theme rather than the
     three fill+text rules hardcoding white each (Task 3). */
  --on-accent: #FFFFFF;
  /* Raw R,G,B triplets for the accent/neutral colors, so a tint background
     or a translucent border can write rgba(var(--verified-rgb), 0.45)
     instead of a hardcoded rgba literal repeating --verified's own hex as
     numbers -- the latter would silently stay light-mode-colored once the
     dark palette (Task 3) redefines --verified to a different hex; the
     rgb-triplet version updates automatically alongside it. */
  --verified-rgb: 14,110,99;
  --attention-rgb: 135,87,16;
  --risk-rgb: 162,59,46;
  --ink-rgb: 24,34,49;
  --slate-rgb: 91,101,114;
  --verified-tint: rgba(var(--verified-rgb), 0.08);
  --attention-tint: rgba(var(--attention-rgb), 0.12);
  --risk-tint: rgba(var(--risk-rgb), 0.09);
  /* Two-tier elevation scale, tokenizing the two shadow treatments already
     validated in this design system rather than inventing new ones:
     --shadow-1 is .auth-card's existing resting shadow, --shadow-2 is the
     hover lift every .paper-card-family element already used inline,
     repeated at 5 call sites. Built on --ink-rgb, which is deliberately
     theme-invariant (see the dark-palette block below) -- a shadow needs
     to stay dark regardless of theme, so these need no dark-mode redefine
     of their own. */
  --shadow-1: 0 2px 6px rgba(var(--ink-rgb), 0.08), 0 1px 2px rgba(var(--ink-rgb), 0.06);
  --shadow-2: 0 4px 12px -6px rgba(var(--ink-rgb), 0.18);

  --font-display: 'Archivo', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', 'Consolas', monospace;

  --fs-display: clamp(1.7rem, 1.15rem + 2.2vw, 2.35rem);
  --fs-h2: 1.05rem;
  --fs-body: 1rem;
  --fs-sm: 0.855rem;
  --fs-xs: 0.72rem;
  --fs-ratio: clamp(1.9rem, 1.4rem + 1.6vw, 2.35rem);
  /* The de-emphasized "N/A" variant of every headline stat below --
     smaller, mono, muted -- shares this one size so the degraded state is
     as visually consistent as the emphasized one (visual richness pass,
     headline typography audit). */
  --fs-ratio-na: 1.4rem;

  --s1: 0.25rem; --s2: 0.5rem; --s3: 0.75rem; --s4: 1rem;
  --s5: 1.5rem; --s6: 2rem; --s7: 3rem;
  --r: 3px; --r-lg: 6px;
  /* Content column width -- wider than a typical text-reading column on
     purpose: the multi-year statement and multi-quarter trend tables
     (up to ~11 and ~11 columns respectively) genuinely benefit from the
     extra horizontal room before falling back to horizontal scroll.
     Fluid past that floor (responsive audit, 2026-08-24), widened further
     (ultrawide layout pass, 2026-08-28): a single fixed column stretching
     the SAME amount everywhere still reads as one block "just getting
     wider" rather than the page actually using the space -- so past this
     floor, prose text is capped separately (--maxw-prose / .prose below)
     while this column keeps growing for the data-dense stuff (ledger
     tables, statement tables, chart canvases, card grids) that genuinely
     benefits from more room. Below ~2100px viewport, 78vw stays under the
     1360px floor so nothing changes there; a 34" ultrawide (3440px) now
     gets ~2680px of column instead of capping at 2100px, still bounded so
     the page never goes full-bleed. */
  --maxw: clamp(1360px, 78vw, 2700px);
  /* Comfortable reading width for prose/narrative text (disclaimers, help
     copy, descriptions) -- these must NOT stretch to fill --maxw just
     because their container grew; capped independently of the data-dense
     column above so both requirements (wide tables, narrow paragraphs)
     hold at the same time on the same page. */
  --maxw-prose: 46rem;

  /* Tells the browser which system palette to paint NATIVE widget chrome
     from -- the closed <select> button, the OS-drawn <option> popup list,
     the date-picker calendar, scrollbars, spin buttons, the caret. None of
     those obey our custom CSS colors; without this they stay light-mode
     even under the dark palette, which is what made Compare's sector
     dropdown render dark-background/black-text (dark-mode form-control
     audit). Set once per theme alongside the tokens, never per-element. */
  color-scheme: light;
}

/* ---- dark palette (Task 3, dark mode session) ----
   A genuine second palette, not an inversion: base surfaces come from the
   same ink-navy family as the light mode's --ink (never pure black), and
   every accent (teal/ochre/risk-red) gets its OWN recalculated hex rather
   than reusing the light-mode value, verified for AA contrast against the
   new dark background (ratios recorded below; also reported in the
   session summary). Mono/data typography, spacing, and layout tokens are
   untouched -- only color changes between themes.

   Two ways in: (1) the visitor's OS-level prefers-color-scheme, when they
   haven't made an explicit choice (no `data-theme` attribute on <html> at
   all -- see base.html and screener/theme.py); (2) an explicit toggle
   choice, via `data-theme="dark"`/`"light"` on <html>, which always wins
   over the OS setting once made. The same token block is written twice
   (once gated by the media query + :not([data-theme="light"]), once for
   the explicit attribute) since CSS has no way to share a token list
   across two different selectors otherwise.

   Contrast ratios (WCAG 2.1), against both --paper (#10151E) and
   --surface (#1A2330):
     --ink        (#E7EAF0) on paper 15.18:1 / surface 13.13:1  (need 4.5)
     --slate      (#94A1B3) on paper  6.98:1 / surface  6.03:1  (need 4.5)
     --verified-ink (#5FDCC7, link/citation text) on paper 10.93:1 / surface 9.46:1
     --verified   (#2FC7AF, decorative/accent, 3:1 target) on paper 8.63:1 / surface 7.47:1
     --attention  (#E0A430) on paper 8.29:1 / surface 7.18:1
     --risk       (#F28B7D) on paper 7.63:1 / surface 6.60:1
     --on-accent  (#10151E) on --verified (button fill) 8.63:1; on --attention 8.29:1
   Every pair clears AA (4.5:1 text, 3:1 large/decorative) with margin. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #10151E;
    --surface: #1A2330;
    --ink: #E7EAF0;
    --verified: #2FC7AF;
    --verified-ink: #5FDCC7;
    --attention: #E0A430;
    --slate: #94A1B3;
    --rule: #202A38;
    --rule-strong: #2E3A4B;
    --risk: #F28B7D;
    --on-accent: #10151E;
    --verified-rgb: 47,199,175;
    --attention-rgb: 224,164,48;
    --risk-rgb: 242,139,125;
    --slate-rgb: 148,161,179;
    /* --ink-rgb is used ONLY for box-shadows (see .paper-card:hover etc.)
       -- a shadow needs to stay dark/black regardless of theme, so this
       does NOT track --ink's new light value the way the accent triplets
       above track their hex. */
    --ink-rgb: 0,0,0;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --paper: #10151E;
  --surface: #1A2330;
  --ink: #E7EAF0;
  --verified: #2FC7AF;
  --verified-ink: #5FDCC7;
  --attention: #E0A430;
  --slate: #94A1B3;
  --rule: #202A38;
  --rule-strong: #2E3A4B;
  --risk: #F28B7D;
  --on-accent: #10151E;
  --verified-rgb: 47,199,175;
  --attention-rgb: 224,164,48;
  --risk-rgb: 242,139,125;
  --slate-rgb: 148,161,179;
  --ink-rgb: 0,0,0;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--verified-ink); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--verified); }

h1, h2, h3 { font-family: var(--font-display); font-weight: 800; letter-spacing: -0.01em; color: var(--ink); margin: 0; }
h1 { font-size: var(--fs-display); line-height: 1.08; }
h2 { font-size: var(--fs-h2); font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--slate); }
.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

/* focus — visible on every interactive element */
:focus-visible { outline: 2px solid var(--verified); outline-offset: 2px; border-radius: 1px; }

/* ---- native form controls (dark-mode form-control audit) ----
   Belt-and-suspenders to the `color-scheme` token above. `color-scheme`
   fixes the browser-drawn chrome; these element-level rules fix the parts
   the browser paints from its OWN defaults (`field` / `fieldtext`) rather
   than inheriting, which no amount of styling on an ancestor reaches.

   Deliberately element selectors, not classes: the bug that started this
   (Compare's sector <select>: dark --surface background from
   `.calc-picker select`, but BLACK text, because that rule set a
   background and never set a color) is a whole class of bug that recurs
   every time a new form control is added without remembering to restate
   `color`. A base rule keyed on the element means a control is themed
   correctly by default and a class only overrides what it means to.

   Specificity is low on purpose (0,0,1) -- every existing `.field input`,
   `.auth-card input`, `.calc-picker select` etc. still wins on whichever
   properties IT declares (usually background + sizing) and inherits the
   rest from here.

   <option> is listed separately as well as in the group because on some
   platforms (Windows Chrome/Edge in particular) the popup list items are
   painted independently of the closed control.

   type="checkbox" is excluded from the blanket background/border rule
   (the column picker, Task: screener column selection, is the first
   checkbox in the app): forcing a background-color/border-color on a
   native checkbox box fights the OS-drawn control on most platforms
   rather than fixing anything, unlike a text input or select. The
   already-declared `color-scheme` on :root (see above) is what actually
   keeps a checkbox's native chrome legible in dark mode; `accent-color`
   below themes its checked-state fill to match the app's own accent. */
input:not([type="checkbox"]), select, textarea {
  background-color: var(--surface);
  color: var(--ink);
  border-color: var(--rule-strong);
}
select option, option, optgroup {
  background-color: var(--surface);
  color: var(--ink);
}
/* accent-color: the app's own teal rather than the browser's default blue,
   for every widget the browser paints an "accent" onto -- checkboxes today
   (the column picker), and any range/radio/progress control added later,
   for free, without a new rule each time. Inherited from :root rather than
   redeclared per element (native browser control pass). */
:root { accent-color: var(--verified); }
/* Native <select> arrow: browsers draw their own, which doesn't pick up
   theme colors -- `appearance: none` removes it and this draws a plain
   chevron from two CSS gradients (no image asset, no per-theme duplication
   needed since `var(--slate)` already resolves per theme). `[multiple]` and
   `[size]` selects are excluded -- they render as a listbox, not a closed
   dropdown, and have no arrow to replace. */
select:not([multiple]):not([size]) {
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--slate) 50%),
    linear-gradient(135deg, var(--slate) 50%, transparent 50%);
  background-position: calc(100% - 17px) center, calc(100% - 12px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 1.9rem !important;
}
select:not([multiple]):not([size]):disabled {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--rule-strong) 50%),
    linear-gradient(135deg, var(--rule-strong) 50%, transparent 50%);
}
/* Placeholders: browsers default these to a fixed grey that lands too
   close to the dark palette's background. --slate is AA-verified against
   both --paper and --surface in both themes; opacity:1 undoes Firefox's
   extra fade on top of the color. */
input::placeholder, textarea::placeholder { color: var(--slate); opacity: 1; }
/* Disabled/readonly: keep them legible-but-clearly-inert rather than
   letting the browser grey them into the background. The <option
   disabled> entries in the company-detail metric selector are the live
   case (unavailable metrics). */
input:disabled, select:disabled, textarea:disabled, option:disabled {
  color: var(--slate); opacity: 1; cursor: not-allowed;
}

/* ---- shared top bar (nav-shell-design-2026-08, Phase 2) ----
   The cross-product shell: persistent on every page of every product in
   the bundle, same markup pattern rebuilt natively per repo (no shared
   frontend package). Three slots -- mark / section switcher / theme+account
   -- per the design doc's "Anatomy of the shared top bar". Full-bleed like
   the masthead it replaces (Task 1): edge-to-edge, not capped to --maxw. */
.top-shell {
  background: var(--surface);
  border-bottom: 1px solid var(--rule-strong);
}
.top-shell-inner {
  width: 100%; margin: 0 auto; padding: var(--s3) var(--s6); box-sizing: border-box;
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
}
/* Mark slot -- reserved for a future unified bundle mark. Deliberately NOT
   the "STOCKPROOF" wordmark (that's each product's own identity and lives
   in its section-local sub-nav below): just the small teal glyph already
   used elsewhere in this design system, until a real cross-product mark
   exists to put here instead. */
.mark-slot { display: inline-flex; align-items: center; text-decoration: none; flex-shrink: 0; }
.mark-slot .mark-glyph { width: 14px; height: 14px; background: var(--verified); display: inline-block; }
/* Section switcher -- the actual "one product" signal. Always the same
   three items in the same order on every page: Screener / Charting / F&O.
   The active section (StockProof = Screener, always, in this repo) is a
   bold filled pill in the shared accent teal; inactive sections are muted
   slate. Reuses the .pf-tab.active fill/pill pattern already established
   for the portfolio switcher, rather than inventing a second "active pill"
   treatment. */
.section-switch { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.section-pill {
  display: inline-flex; align-items: center;
  padding: 0.35rem var(--s4); border-radius: 999px;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-sm);
  letter-spacing: 0.01em; text-decoration: none; color: var(--slate);
  border: 1px solid transparent;
}
.section-pill.muted:hover { color: var(--ink); border-color: var(--rule-strong); }
.section-pill.active {
  background: var(--verified); color: var(--on-accent); font-weight: 800;
  box-shadow: none;
}
.section-pill.disabled { cursor: default; opacity: 0.6; }
.top-shell-right { margin-left: auto; display: flex; align-items: center; gap: var(--s4); font-size: var(--fs-sm); flex-wrap: wrap; }
.top-shell-right a { font-weight: 500; color: var(--ink); text-decoration: none; }
.top-shell-right a:hover { color: var(--verified); }
.top-shell-right .who { color: var(--slate); font-family: var(--font-mono); font-size: var(--fs-xs); }
.top-shell-logout { display: inline; margin: 0; }
.top-shell-right .linkish { background: none; border: none; color: var(--ink); cursor: pointer; font: inherit; font-weight: 500; padding: 0; }
.top-shell-right .linkish:hover { color: var(--verified); }

/* ---- section-local sub-nav (StockProof's own, one level below the shared
   shell above) ----
   Carries this product's identity (wordmark + tagline) and its 11 pages,
   grouped by intent rather than flattened into one row -- the fix the
   design doc calls out specifically for StockProof's pre-existing 12-item
   clutter. The double rule + verified top accent is the bar's own visual
   signature, echoing what the single masthead used to carry alone. */
.section-nav {
  background: var(--paper);
  border-top: 4px solid var(--verified);
  border-bottom: 3px double var(--rule-strong);
}
.section-nav-inner {
  width: 100%; margin: 0 auto; padding: var(--s3) var(--s6); box-sizing: border-box;
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
}
.section-brand { display: inline-flex; flex-direction: column; gap: 0.1rem; text-decoration: none; flex-shrink: 0; }
.wordmark {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-family: var(--font-display); font-weight: 800; font-size: 1.15rem;
  letter-spacing: 0.04em; color: var(--ink); text-decoration: none;
}
.section-brand:hover .wordmark { color: var(--ink); }
.wordmark .tie { width: 12px; height: 12px; background: var(--verified); display: inline-block; }
.tagline { color: var(--slate); font-size: var(--fs-xs); font-family: var(--font-mono); letter-spacing: 0.02em; }
.section-nav-links { margin-left: auto; display: flex; align-items: center; gap: var(--s5); font-size: var(--fs-sm); flex-wrap: wrap; }
.nav-group { display: inline-flex; align-items: center; gap: var(--s4); padding-left: var(--s4); border-left: 1px solid var(--rule); }
.nav-group-label {
  font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--slate); flex-shrink: 0;
}
.nav-group a { font-weight: 500; color: var(--ink); text-decoration: none; display: inline-flex; align-items: center; gap: var(--s1);
  padding-bottom: 0.2rem; box-shadow: 0 2px 0 0 transparent; white-space: nowrap; }
.nav-group a:hover { color: var(--verified); }
/* Current-page indicator (visual richness pass) -- box-shadow rather than
   border-bottom so the extra 2px never shifts the row's height/baseline. */
.nav-group a.active { color: var(--verified-ink); font-weight: 700; box-shadow: 0 2px 0 0 var(--verified); }

/* mobile nav toggle (hidden above the mobile breakpoint -- see
   @media(max-width:640px) below for its visible/collapsed-nav rules) */
.nav-toggle {
  display: none; margin-left: auto; background: var(--surface);
  border: 1px solid var(--rule-strong); border-radius: var(--r);
  width: 2.75rem; height: 2.75rem; padding: 0; cursor: pointer;
  align-items: center; justify-content: center; flex-shrink: 0;
}
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  display: block; width: 1.1rem; height: 2px; background: var(--ink);
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before, .nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after { top: 6px; }

/* nav pending-updates badge (ochre — the "something's dated" signal) */
.nav-badge {
  display: inline-block; min-width: 1.15rem; text-align: center;
  background: var(--attention); color: var(--surface);
  font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-xs);
  padding: 0.05rem 0.35rem; border-radius: 999px; line-height: 1.4;
}

/* nav ₹ unit toggle (Lakh/Crore ⇄ Billions) — a quiet segmented control */
.unit-toggle {
  display: inline-flex; align-items: center; gap: 0.15rem;
  border: 1px solid var(--rule-strong); border-radius: 2px;
  padding: 0.05rem 0.2rem 0.05rem 0.3rem; background: var(--surface);
  font-family: var(--font-mono); font-size: var(--fs-xs); line-height: 1.4;
}
.unit-toggle .unit-tag { color: var(--slate); margin-right: 0.1rem; }
.unit-toggle .unit-opt {
  padding: 0.02rem 0.3rem; border-radius: 2px; color: var(--slate);
  text-decoration: none; font-weight: 500;
}
.unit-toggle a.unit-opt:hover { color: var(--verified); background: var(--paper); }
.unit-toggle .unit-opt.active { background: var(--ink); color: var(--surface); }

/* headline reconciliation companion figures (gross revenue / total net
   profit shown beside the net/owners figures the ratios use) */
.recon {
  display: block; margin-top: 0.15rem; font-size: var(--fs-xs);
  color: var(--slate); font-family: var(--font-mono); white-space: nowrap;
}
.recon-inline { font-family: var(--font-mono); color: var(--slate); font-size: 0.95em; }
.col-note { display: block; font-weight: 400; font-size: var(--fs-xs); color: var(--slate); font-family: var(--font-mono); }

/* ---- layout ---- */
main { max-width: var(--maxw); margin: 0 auto; padding: var(--s6) var(--s5) var(--s7); }
/* A handful of pages are genuinely sparse regardless of how much data is
   behind them -- one form, one question box, one glossary column -- never
   the wide tables/charts/card-grids --maxw exists for. Growing <main> to
   78vw on those turns a short page into a strip of text and controls lost
   in an otherwise-empty 34" monitor (ultrawide dead-space pass). Opt in
   per template with {% block main_class %}main-narrow{% endblock %},
   reusing --maxw-prose rather than a third width value. Page-type
   judgment, not a blanket cap -- data-dense pages are untouched. */
main.main-narrow { max-width: var(--maxw-prose); }

/* Wide-viewport margins. The ultrawide pass originally gave <main> a
   "sheet of paper lifted off a drafting table" treatment here -- a
   dot-grid texture on <body>, plus a gutter border and drop shadow on
   the content column. In use that read as a page pasted on top of
   another page: two visually distinct layers, in BOTH themes. That
   device is right for a single component sitting inside a page and wrong
   for the page's own primary container, so it is gone: no texture, no
   border, no shadow, one continuous --paper surface from viewport edge
   to viewport edge.

   What deliberately stays is the FUNCTIONAL half of that pass -- the
   --maxw column above still grows to 78vw (to 2700px), so tables, chart
   canvases and card grids keep using the extra width on a wide monitor.
   The margins are simply plain paper now: the width behaviour and the
   floating-card look are decoupled, and only the look was the problem.

   Component-level elevation is untouched -- .paper-card, .ratio-card,
   .trace-panel, .query-slip et al keep their --surface fill, border and
   hover shadow, which is the scale that treatment belongs at. */

.page-head { margin-bottom: var(--s5); }
/* .sub is the general muted-description paragraph, used throughout (not
   only under a .page-head) -- prose-capped like every other narrative
   block below, wherever it lands. */
.sub { color: var(--slate); font-size: var(--fs-sm); max-width: var(--maxw-prose); }
.page-head .sub { margin-top: var(--s2); }

/* ---- prose: narrative/explanatory text, capped to a comfortable reading
   width wherever it appears, independent of how wide --maxw grows (Task 1,
   ultrawide layout pass). Data-dense siblings (tables, charts, card grids)
   are NOT wrapped in this and keep using the full column. ---- */
.prose, .empty-note, .screen-desc, .limitation-note,
.calc-note, .assumption-note, .statement-note, .metric-window,
.roce-caveat, .currency-warn {
  max-width: var(--maxw-prose);
}
.backlink { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); text-decoration: none; text-transform: uppercase; letter-spacing: 0.04em; }
.backlink:hover { color: var(--verified); }

/* ---- flash messages ---- */
.messages { list-style: none; padding: 0; margin: 0 0 var(--s5); }
.messages li {
  padding: var(--s3) var(--s4); border-radius: var(--r); margin-bottom: var(--s2);
  font-size: var(--fs-sm); border: 1px solid var(--rule); background: var(--surface);
  border-left: 3px solid var(--slate);
}
.messages li.success { border-left-color: var(--verified); background: var(--verified-tint); }
.messages li.error { border-left-color: var(--risk); background: var(--risk-tint); }
.messages li.info { border-left-color: var(--attention); background: var(--attention-tint); }

/* ---- filters: the "query slip" ---- */
.query-slip {
  border: 1px solid var(--rule-strong); background: var(--surface);
  border-radius: var(--r); padding: var(--s4) var(--s4) var(--s4);
  margin: 0 0 var(--s5); position: relative;
}
.query-slip::before {
  content: "FILTERS"; position: absolute; top: -0.62rem; left: var(--s3);
  background: var(--surface); padding: 0 var(--s2);
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.12em;
  color: var(--slate);
}
.query-slip .fields { display: flex; gap: var(--s5); align-items: flex-end; flex-wrap: wrap; }
.field label { display: block; font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.04em; color: var(--slate); margin-bottom: var(--s1); text-transform: uppercase; }
.field input, .field select {
  background: var(--paper); border: 1px solid var(--rule-strong); color: var(--ink);
  font-family: var(--font-mono); font-size: var(--fs-sm); padding: 0.45rem 0.6rem;
  border-radius: var(--r); width: 11rem; height: 2.25rem;
}
.field input:hover, .field select:hover { border-color: var(--slate); }

/* ---- buttons ---- */
.btn, .btn-ghost {
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-sm);
  padding: 0.5rem 1.1rem; border-radius: var(--r); cursor: pointer; height: 2.25rem;
  box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none;
}
.btn { background: var(--verified); color: var(--on-accent); border: 1px solid var(--verified-ink); font-weight: 600; }
.btn:hover { background: var(--verified-ink); }
.btn-ghost { background: transparent; color: var(--slate); border: 1px solid var(--rule-strong); font-weight: 500; }
.btn-ghost:hover { background: var(--paper); border-color: var(--slate); color: var(--ink); }
.clear-link { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); text-decoration: none; letter-spacing: 0.03em; }
.clear-link:hover { color: var(--verified); }

/* ---- extract (export) affordance ---- */
.extract { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate);
  letter-spacing: 0.03em; display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.extract .glyph { color: var(--verified); }
.extract a { color: var(--verified-ink); text-decoration: none; }
.extract a:hover { text-decoration: underline; }

/* ---- results meta line ---- */
.results-meta { display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s2); }
.results-meta .count { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--slate); }

/* ---- ledger table ---- */
.table-scroll { overflow-x: auto; border: 1px solid var(--rule-strong); border-radius: var(--r); background: var(--surface); }
table.ledger { width: 100%; border-collapse: collapse; min-width: 780px; }
table.ledger thead th {
  font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-xs);
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--slate);
  text-align: left; padding: var(--s3) var(--s3); white-space: nowrap;
  border-bottom: 3px double var(--rule-strong); background: var(--surface);
}
table.ledger thead th.num { text-align: right; }
.sort-link { font: inherit; color: inherit; text-decoration: none; text-transform: inherit; letter-spacing: inherit; }
.sort-link:hover { color: var(--verified-ink); }
.sort-link.active { color: var(--verified-ink); font-weight: 700; }
.sort-glyph { margin-left: 0.25rem; }
table.ledger tbody td { padding: var(--s3) var(--s3); border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm); vertical-align: baseline; }
table.ledger tbody tr:last-child td { border-bottom: none; }
table.ledger tbody tr:hover td { background: var(--verified-tint); }
table.ledger .company { font-family: var(--font-body); color: var(--ink); }
table.ledger .sector { font-family: var(--font-body); color: var(--slate); font-size: var(--fs-xs); }

/* ---- inline row sparklines (visual richness session): a compressed
   shape of the company's own recent stored daily closes, colored by net
   direction over the window -- teal up / red down / slate flat, the same
   convention as .gain/.loss elsewhere. Small and unobtrusive on purpose:
   sized to sit quietly inside a ledger row, never wider than the column
   needs. ---- */
.spark-th { width: 4.5rem; }
.spark-td { padding-top: 0.3rem; padding-bottom: 0.3rem; }
.sparkline { display: inline-block; vertical-align: middle; }
.spark-line { stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.spark-up { stroke: var(--verified-ink); }
.spark-down { stroke: var(--risk); }
.spark-flat { stroke: var(--slate); }

/* traceable ticker: tie-tick + monospace symbol linking to the audit detail */
.ticker-cell { white-space: nowrap; }
.trace-tick { color: var(--verified); font-family: var(--font-mono); margin-right: 0.35rem; }
a.ticker-link { font-family: var(--font-mono); font-weight: 500; color: var(--verified-ink); text-decoration: none; }
a.ticker-link:hover { text-decoration: underline; }

/* N/A — a deliberate ledger "nil" entry, not plain text */
.na {
  display: inline-block; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--slate); border: 1px dashed var(--rule-strong); border-radius: 2px;
  padding: 0.02rem 0.3rem; letter-spacing: 0.03em; background: repeating-linear-gradient(
    135deg, transparent, transparent 4px, rgba(var(--slate-rgb),0.06) 4px, rgba(var(--slate-rgb),0.06) 5px);
}
.na-reason { color: var(--slate); font-style: normal; }

/* ---- freshness: period stamp + newer-available marker (Task 2) ---- */
.asof-cell { white-space: nowrap; }
.period-stamp {
  display: inline-flex; align-items: center; gap: 0.25rem;
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink);
  border: 1px solid var(--rule-strong); border-radius: 2px; padding: 0.05rem 0.35rem;
  background: var(--paper); letter-spacing: 0.02em;
}
.period-stamp .glyph { color: var(--slate); }
.new-filing-badge {
  display: inline-flex; align-items: center; gap: 0.25rem; margin-top: 0.3rem;
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500;
  color: var(--attention); background: var(--attention-tint);
  border: 1px solid rgba(var(--attention-rgb),0.45); border-radius: 2px; padding: 0.05rem 0.35rem;
  letter-spacing: 0.02em; white-space: nowrap;
}
.new-filing-badge.block { display: inline-flex; margin-top: 0; }

/* stale price marker (fetched_at > 24h) — same ochre family, distinct shape */
.stale-badge {
  display: inline-block; margin-left: 0.4rem; font-family: var(--font-mono);
  font-size: var(--fs-xs); font-weight: 500; color: var(--attention);
  background: var(--attention-tint); border: 1px solid rgba(var(--attention-rgb),0.45);
  border-radius: 2px; padding: 0.02rem 0.3rem; vertical-align: middle; letter-spacing: 0.03em;
}
tr.stale-row td { opacity: 0.82; }

/* watchlist controls */
/* The detail-head action cluster holds the watchlist toggle and the
   "+ Add to portfolio" shortcut side by side (Task 1); wrap to a tidy column
   on a narrow viewport rather than letting them collide. */
.detail-head .action { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; justify-content: flex-end; }
.wl-form { display: inline; margin: 0; }
.wl-btn { font-family: var(--font-mono); font-size: var(--fs-xs); background: transparent;
  border: 1px solid var(--rule-strong); color: var(--ink); border-radius: var(--r);
  padding: 0.22rem 0.55rem; cursor: pointer; white-space: nowrap; letter-spacing: 0.02em; }
.wl-btn.add { color: var(--verified-ink); border-color: rgba(var(--verified-rgb),0.45); }
.wl-btn.add:hover { background: var(--verified-tint); }
.wl-btn.remove { color: var(--risk); border-color: rgba(var(--risk-rgb),0.4); }
.wl-btn.remove:hover { background: var(--risk-tint); }
.wl-login { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); text-decoration: none; }
.wl-login:hover { color: var(--verified); }
a.wl-btn { display: inline-block; text-decoration: none; }
a.wl-btn:hover { background: var(--verified-tint); }

/* ---- portfolio ---- */
.portfolio-actions { display: inline-flex; gap: var(--s2); align-items: center; }
table.ledger tfoot .ledger-total td { border-top: 2px solid var(--rule-strong);
  font-family: var(--font-mono); font-weight: 600; color: var(--ink); padding-top: var(--s3); }
.gain { color: var(--verified-ink); }
.loss { color: var(--risk); }
.portfolio-summary { display: flex; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s5); }
.summary-tile { flex: 1 1 12rem; background: var(--surface); border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--verified); border-radius: var(--r); padding: var(--s4);
  display: flex; flex-direction: column; gap: var(--s2); box-shadow: var(--shadow-1); }
/* Elevation lifts on hover, not border-color -- the left edge's teal
   accent is a deliberate identity marker, not a plain neutral border to
   darken (elevation pass). */
.summary-tile:hover { box-shadow: var(--shadow-2); }
.summary-tile .tile-label { font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.03em; color: var(--slate); text-transform: uppercase; }
.summary-tile .tile-value { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-ratio);
  line-height: 1.05; color: var(--ink); font-variant-numeric: tabular-nums; }
.summary-tile .tile-value.gain { color: var(--verified-ink); }
.summary-tile .tile-value.loss { color: var(--risk); }
.summary-tile .tile-pct { font-size: var(--fs-sm); font-family: var(--font-mono); font-weight: 500; }
.price-asof { display: block; font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
.gl-pct { font-size: var(--fs-xs); }
.muted { color: var(--slate); }
.summary-tile .tile-value.muted { color: var(--slate); font-size: var(--fs-sm); font-weight: 600; }
.badge-buy, .badge-sell { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: 0.04em; padding: 0.1rem 0.4rem; border-radius: var(--r); }
.badge-buy { color: var(--verified-ink); background: color-mix(in srgb, var(--verified) 18%, transparent); }
.badge-sell { color: var(--risk); background: color-mix(in srgb, var(--risk) 15%, transparent); }
.consumption-list { margin: 0; padding-left: var(--s4); font-size: var(--fs-sm); }
.consumption-list li { margin: 0.1rem 0; }

/* ---- capital gains: STCG/LTCG classification (this session) ---- */
.badge-stcg, .badge-ltcg { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: 0.04em; padding: 0.1rem 0.4rem; border-radius: var(--r); }
.badge-stcg { color: var(--risk); background: color-mix(in srgb, var(--risk) 15%, transparent); }
.badge-ltcg { color: var(--verified-ink); background: color-mix(in srgb, var(--verified) 18%, transparent); }
/* bold and unmissable on purpose -- risk-toned, not the calmer ochre
   cooldown-note styling, because this is the one place the app must not be
   mistaken for asserting a rate or giving tax advice */
.tax-disclaimer {
  font-family: var(--font-body); font-size: var(--fs-sm); color: var(--risk);
  background: color-mix(in srgb, var(--risk) 10%, transparent); border: 1px solid rgba(var(--risk-rgb),0.45);
  border-left: 3px solid var(--risk); border-radius: var(--r);
  padding: var(--s3) var(--s4); margin: var(--s3) 0 var(--s4); font-weight: 600;
}
.rate-calc-form { display: flex; gap: var(--s4); flex-wrap: wrap; align-items: flex-end; margin-bottom: var(--s4); }
.rate-calc-form .field-row { display: flex; flex-direction: column; gap: var(--s1); }
.rate-calc-form label { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
.rate-calc-form input { width: 8rem; }

/* ---- portfolio risk metrics ---- */
.metric-assumptions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s5); }
.metric-assumptions .assumption { flex: 1 1 16rem; background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r); padding: var(--s3) var(--s4); display: flex; flex-direction: column; gap: var(--s1); }
.assumption-label { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--slate); }
.assumption-value { font-family: var(--font-mono); font-size: var(--fs-h2); color: var(--ink); }
.assumption-note { font-size: var(--fs-xs); color: var(--slate); line-height: 1.4; }
.metric-card { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r);
  padding: var(--s4) var(--s5); margin-bottom: var(--s4); box-shadow: var(--shadow-1); }
.metric-card.portfolio-level { border-color: var(--rule-strong); }
.metric-card:hover { border-color: var(--slate); box-shadow: var(--shadow-2); }
.metric-card h2 { margin-bottom: var(--s2); }
.metric-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); }
.metric-card-head .ticker-link { font-family: var(--font-mono); font-weight: 700; }
.metric-qty { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
.metric-company { font-size: var(--fs-sm); color: var(--slate); margin-bottom: var(--s3); }
.section-heading { margin: var(--s6) 0 var(--s2); }
.metric-window { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); margin-bottom: var(--s3); }
.metric-table { width: 100%; border-collapse: collapse; }
.metric-table td { padding: var(--s2) var(--s2); border-bottom: 1px solid var(--rule); vertical-align: top; }
.metric-table tr:last-child td { border-bottom: none; }
.metric-table tbody tr:hover td { background: var(--verified-tint); }
.metric-name { font-size: var(--fs-sm); color: var(--ink); white-space: nowrap; }
.metric-val { font-family: var(--font-mono); font-weight: 600; white-space: nowrap; }
.metric-formula { font-size: var(--fs-xs); color: var(--slate); }
.metric-formula code { font-family: var(--font-mono); font-size: var(--fs-xs); word-break: break-word; }
.na-reason { color: var(--slate); font-style: italic; }
.metric-unavailable { color: var(--slate); font-style: italic; font-size: var(--fs-sm); }
.limitation-note { background: var(--surface); border-left: 3px solid var(--rule-strong);
  padding: var(--s3) var(--s4); margin: var(--s3) 0; font-size: var(--fs-sm); color: var(--slate); border-radius: 0 var(--r) var(--r) 0; }
.limitation-note strong { color: var(--ink); }
.xirr-headline { display: flex; align-items: baseline; gap: var(--s3); margin: var(--s3) 0 var(--s2); }
.xirr-value { font-family: var(--font-display); font-size: var(--fs-ratio); font-weight: 800; line-height: 1; }
.xirr-sub { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); text-transform: uppercase; letter-spacing: 0.03em; }
.xirr-schedule { margin-top: var(--s3); }
.xirr-schedule summary { cursor: pointer; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--verified-ink); text-transform: uppercase; letter-spacing: 0.03em; }
.xirr-schedule table { margin-top: var(--s3); }
.beta-block { margin-top: var(--s4); padding-top: var(--s3); border-top: 1px dashed var(--rule-strong); }
.beta-headline { display: flex; align-items: baseline; gap: var(--s3); }
.beta-label { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--slate); }
.beta-value { font-family: var(--font-mono); font-size: var(--fs-h2); font-weight: 700; }
.beta-formula code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); word-break: break-word; }
.beta-inputs { list-style: none; padding: 0; margin: var(--s2) 0 0; font-size: var(--fs-sm); }
.beta-inputs li { padding: 0.1rem 0; color: var(--slate); }
.beta-inputs strong { color: var(--ink); font-family: var(--font-mono); }
.holding-metrics-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr)); gap: var(--s4); }

/* ---- factor exposures (Fama-French Phase C) ----
   The caveats are the load-bearing part of this section, so they are styled
   to be READ, not to be dismissed: .factor-alert uses the same --risk tint
   the forensic red-flag badge does, sits at full width ABOVE the loadings
   table, and is never collapsed behind a <details>. .factor-caveat is the
   quieter three-up row beneath it -- still open, still adjacent to the
   numbers, just not competing with the one alert that matters most.
   Deliberately no `display:none` or `max-height` rule anywhere here: a
   disclosure that a stylesheet can hide is a disclosure that will one day be
   hidden by accident. ---- */
.factor-alert { border: 1px solid rgba(var(--risk-rgb), 0.45); border-left: 4px solid var(--risk);
  background: var(--risk-tint); border-radius: var(--r); padding: var(--s3) var(--s4);
  margin: var(--s4) 0; font-size: var(--fs-sm); color: var(--ink); }
.factor-alert p { margin: 0; }
.factor-alert p + p { margin-top: var(--s2); }
.factor-alert-head { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--risk); }
.factor-caveats { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--s3); margin: var(--s4) 0; }
.factor-caveat { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r);
  padding: var(--s3); font-size: var(--fs-xs); color: var(--slate); line-height: 1.5; }
.factor-caveat p { margin: 0; }
.factor-caveat-head { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--ink); margin-bottom: var(--s2) !important; }
.factor-table .smb-row td { background: var(--risk-tint); }
.smb-marker { display: inline-block; font-family: var(--font-mono); font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--risk);
  border: 1px solid rgba(var(--risk-rgb), 0.4); border-radius: var(--r); padding: 0 0.35rem;
  margin-left: var(--s2); white-space: nowrap; }
/* The significance tag sits UNDER its t-statistic in a right-aligned numeric
   cell whose parent sets white-space: nowrap. It has to opt back out and cap
   its own width, or the phrase runs out of the column and across the reading
   beside it. */
.ns-tag { display: block; font-family: var(--font-mono); font-size: 0.65rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.02em; color: var(--slate);
  white-space: normal; max-width: 7rem; margin-left: auto; line-height: 1.25; }
.se-inline { font-size: var(--fs-xs); font-weight: 400; color: var(--slate); white-space: nowrap; }
.factor-fit { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s4) 0; }
.factor-fit-item { flex: 1 1 12rem; background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r); padding: var(--s3); display: flex; flex-direction: column; gap: 0.15rem; }
.factor-fit-item.highlight { border-color: var(--rule-strong); background: var(--verified-tint); }
.factor-fit-label { font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--slate); }
.factor-fit-value { font-family: var(--font-mono); font-size: var(--fs-h2); font-weight: 700; color: var(--ink); }
.factor-fit-note { font-size: var(--fs-xs); color: var(--slate); }
.factor-subhead { margin: var(--s5) 0 var(--s2); }
.factor-formations { margin: var(--s4) 0; }
.factor-formations summary { cursor: pointer; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--verified-ink); text-transform: uppercase; letter-spacing: 0.03em; }
.factor-formations table { margin-top: var(--s3); }

/* ---- panel-pair: two conceptually-parallel blocks side by side once
   there's room, one column when there isn't (Task 1, ultrawide layout
   pass) -- same flex-wrap/flex-basis mechanism as .frontier-layout below,
   generalized for any pair of same-level sections (source documents,
   picker forms, compact summary cards) rather than just the frontier
   chart+table. Deliberately NOT gated behind a min-width media query --
   like .frontier-layout, it wraps to one column on its own once the
   combined flex-basis no longer fits, so it degrades correctly at any
   width including mobile. Only used where both children are reasonably
   compact -- a wide multi-column ledger table stays full-width and
   stacked instead of being squeezed into a half column. ---- */
.panel-pair { display: flex; flex-wrap: wrap; gap: var(--s5); align-items: flex-start; }
.panel-pair > * { flex: 1 1 28rem; min-width: 0; }

/* ---- efficient frontier ---- */
.frontier-layout { display: flex; flex-wrap: wrap; gap: var(--s5); align-items: flex-start; }
.frontier-chart-wrap { flex: 1 1 26rem; min-width: 0; height: 26rem; }
.frontier-side { flex: 1 1 18rem; min-width: 0; }
/* Chart.js canvases (visualization session): responsive:true reads its
   PARENT's box to size itself (via a ResizeObserver) and then sets the
   canvas's own width/height as an inline style, which always wins over any
   CSS class rule on the canvas -- so (unlike the old SVG's self-sizing
   viewBox) the explicit height has to live on the WRAPPER, not the canvas
   itself, or Chart.js's own inline style silently overrides it. */
.frontier-chart { width: 100%; height: 100%; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: var(--s3); box-sizing: border-box; }
.history-chart-wrap { margin: var(--s4) 0; position: relative; height: 22rem; }
.history-chart { width: 100%; height: 100%; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: var(--s3); box-sizing: border-box; }
.chart-reset-zoom { position: absolute; top: calc(var(--s3) + var(--s2)); right: calc(var(--s3) + var(--s2));
  background: var(--surface); border: 1px solid var(--rule-strong); color: var(--slate);
  font-family: var(--font-mono); font-size: var(--fs-xs); padding: 0.25rem 0.6rem; border-radius: var(--r); cursor: pointer; }
.chart-reset-zoom:hover { background: var(--paper); color: var(--ink); border-color: var(--slate); }
.metric-table thead th { text-align: left; font-family: var(--font-mono); font-size: var(--fs-xs);
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--slate); padding: var(--s2); border-bottom: 1px solid var(--rule-strong); }
.metric-table thead th.num { text-align: right; }
.current-row td { border-top: 1px solid var(--rule-strong); font-weight: 600; }
.frontier-notes { margin-top: var(--s6); }
.frontier-notes ul { font-size: var(--fs-sm); color: var(--slate); line-height: 1.6; padding-left: var(--s5); }
.frontier-notes li { margin-bottom: var(--s2); }
.frontier-notes strong { color: var(--ink); }

/* ---- correlation matrix ---- */
.correlation-section { margin-top: var(--s6); }
table.corr-matrix { border-collapse: collapse; font-family: var(--font-mono); font-size: var(--fs-xs); }
table.corr-matrix th { font-weight: 600; color: var(--slate); padding: var(--s2) var(--s3); text-align: center; white-space: nowrap; }
table.corr-matrix .corr-row-label { text-align: right; color: var(--ink); }
table.corr-matrix .corr-cell { padding: var(--s2) var(--s3); text-align: center; color: var(--ink);
  border: 1px solid var(--surface); min-width: 3.4rem; }
table.corr-matrix .corr-diagonal { color: var(--slate); }
.corr-legend { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s3);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
.corr-legend .corr-swatch { display: inline-block; width: 0.9rem; height: 0.9rem; border-radius: 2px;
  vertical-align: middle; margin-right: 0.3rem; border: 1px solid var(--rule); }

/* ---- financial calculators ---- */
.calc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr)); gap: var(--s4); }
.calc-card { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: var(--s5); box-shadow: var(--shadow-1); }
.calc-card:hover { border-color: var(--slate); box-shadow: var(--shadow-2); }
.calc-card h2 { margin-bottom: var(--s2); }
.calc-formula { margin-bottom: var(--s3); }
.calc-formula code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); word-break: break-word; }
.calc-field { margin-bottom: var(--s3); display: flex; flex-direction: column; gap: var(--s1); }
.calc-field label { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); text-transform: uppercase; letter-spacing: 0.03em; }
.calc-field input { width: 100%; background: var(--paper); color: var(--ink); border: 1px solid var(--rule-strong);
  border-radius: var(--r); padding: 0.5rem 0.6rem; font-family: var(--font-mono); font-size: var(--fs-sm); box-sizing: border-box; }
.calc-cite { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--verified-ink); }
.calc-note { font-size: var(--fs-xs); color: var(--slate); font-style: italic; margin: var(--s2) 0; }
.calc-picker { background: var(--paper); border: 1px solid var(--rule-strong); border-radius: var(--r);
  padding: var(--s3); margin-bottom: var(--s4); }
.calc-picker label { display: block; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--slate); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: var(--s2); }
.calc-picker-row { display: flex; gap: var(--s2); flex-wrap: wrap; }
.calc-picker select, .calc-picker input[type="text"] { flex: 1 1 12rem; min-width: 0; background: var(--surface); color: var(--ink); border: 1px solid var(--rule-strong);
  border-radius: var(--r); padding: 0.45rem 0.5rem; font-size: var(--fs-sm); font-family: var(--font-body); box-sizing: border-box; }
.calc-result { margin-top: var(--s4); border-top: 2px solid var(--rule-strong); padding-top: var(--s3); }
.calc-result-table { width: 100%; border-collapse: collapse; }
.calc-result-table td { padding: var(--s2); border-bottom: 1px solid var(--rule); }
.calc-result-table tr:last-child td { border-bottom: none; }
.calc-result-table tbody tr:hover td { background: var(--verified-tint); }
.calc-result-label { color: var(--slate); font-size: var(--fs-sm); }
.calc-result-value { font-family: var(--font-mono); font-weight: 700; color: var(--ink); }
.calc-result-formula { margin-top: var(--s2); }
.calc-result-formula code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); word-break: break-word; }
.calc-error { margin-top: var(--s3); color: var(--risk); font-size: var(--fs-sm); background: var(--risk-tint);
  padding: var(--s2) var(--s3); border-radius: var(--r); }
.calc-row-list-label { display: block; font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate);
  text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: var(--s2); }
.calc-row-list { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s3); }
.calc-row { display: flex; gap: var(--s2); align-items: center; }
.calc-row input { flex: 1 1 auto; min-width: 0; background: var(--paper); border: 1px solid var(--rule-strong);
  border-radius: var(--r); padding: var(--s2); font: inherit; color: var(--ink); }
.calc-row-remove { flex: 0 0 auto; background: transparent; border: 1px solid var(--rule-strong); border-radius: var(--r);
  color: var(--slate); cursor: pointer; width: 2rem; height: 2rem; line-height: 1; font-size: var(--fs-sm); }
.calc-row-remove:hover { color: var(--risk); border-color: var(--risk); }
.calc-add-row { margin-bottom: var(--s3); }
.calc-cross-link { background: var(--attention-tint); border: 1px solid var(--attention); border-radius: var(--r);
  padding: var(--s2) var(--s3); font-size: var(--fs-sm); color: var(--ink); margin-bottom: var(--s3); }
.calc-cross-link a { font-weight: 600; }

/* Solid border + left accent + faint tint, the same "note box" language
   .messages li/.provenance already use, rather than a dashed border --
   dashed reads as wireframe/unfinished (elevation + disclaimer-box pass).
   .screen-caveat below still overrides border-color/background to its own
   --attention accent; this is the neutral/informational default. */
.empty-note { color: var(--slate); font-size: var(--fs-sm); background: rgba(var(--slate-rgb), 0.05);
  border: 1px solid var(--rule-strong); border-left: 3px solid var(--slate);
  border-radius: var(--r); padding: var(--s5); }

/* ---- company detail ---- */
.detail-head { display: flex; align-items: flex-start; gap: var(--s4); flex-wrap: wrap; justify-content: space-between; margin-bottom: var(--s2); }
.detail-head .ident h1 { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.detail-head .ident .sym { font-family: var(--font-mono); color: var(--verified-ink); font-weight: 500; }
.detail-head .ident .sector { color: var(--slate); font-size: var(--fs-sm); margin-top: var(--s2); }

/* In-page section nav (company-detail sticky-toc pass): populated at
   runtime from the page's own rendered <h2 id> elements -- see the
   company_detail.html script beside it. Sticks to the very top of the
   viewport since nothing else on the page is position:sticky; an opaque
   --surface background is required for a sticky bar so scrolled content
   doesn't show through underneath it. */
.section-toc {
  position: sticky; top: 0; z-index: 5;
  display: flex; flex-wrap: wrap; gap: var(--s2);
  background: var(--surface); border: 1px solid var(--rule-strong); border-radius: var(--r);
  padding: var(--s2) var(--s3); margin-bottom: var(--s4);
  box-shadow: var(--shadow-1);
}
.section-toc a {
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.02em;
  color: var(--slate); text-decoration: none; padding: 0.3rem 0.6rem;
  border-radius: var(--r); white-space: nowrap;
}
.section-toc a:hover { color: var(--ink); background: var(--verified-tint); }
/* So an anchor jump doesn't land a heading directly under the sticky bar
   floating above it. */
main h2[id] { scroll-margin-top: 4rem; }

/* provenance banner — the honest freshness statement (Task 2), prominent */
.provenance {
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--verified); border-radius: var(--r);
  padding: var(--s4); margin: var(--s4) 0 var(--s5);
}
.provenance .line { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--ink);
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.provenance .line .glyph { color: var(--slate); }
.provenance .warn {
  margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--rule);
  border-left: 3px solid var(--attention); padding-left: var(--s3); margin-left: -0.75rem;
  color: var(--attention); font-family: var(--font-mono); font-size: var(--fs-sm);
}
.currency-warn { color: var(--risk); font-size: var(--fs-sm); margin: var(--s3) 0 0; }

/* ---- ratios: "working paper" cards + Source Trace (signature) ---- */
.ratio-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--s4); margin: var(--s4) 0; }
.paper-card {
  background: var(--surface); border: 1px solid var(--rule-strong); border-radius: var(--r);
  padding: var(--s4); position: relative; box-shadow: var(--shadow-1);
}
.paper-card:hover { border-color: var(--slate); box-shadow: var(--shadow-2); }
.paper-card .tab {
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--slate);
}
.paper-card .ratio-value { font-family: var(--font-display); font-weight: 800;
  font-size: var(--fs-ratio); line-height: 1.05; color: var(--ink); font-variant-numeric: tabular-nums; margin: var(--s2) 0 0; }
.paper-card .ratio-value.na-value { font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-ratio-na); color: var(--slate); }
.paper-card .ratio-name { color: var(--slate); font-size: var(--fs-sm); margin-top: var(--s1); }
.paper-card .formula { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); margin-top: var(--s3); }

/* THE signature: Source Trace — citation as an audit tie-line */
.source-trace {
  margin-top: var(--s3); padding: var(--s3) 0 var(--s2) var(--s4);
  border-left: 2px solid var(--verified); position: relative;
}
.source-trace::before {
  content: ""; position: absolute; left: -5px; top: 0; width: 8px; height: 8px;
  background: var(--verified); /* the ledger tie-node */
}
.source-trace .trace-label {
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--verified-ink); display: flex; align-items: center; gap: 0.3rem;
  margin-bottom: var(--s2);
}
.source-trace .citation {
  font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--ink);
  line-height: 1.6; word-break: break-word;
}
.source-trace .citation .doc { color: var(--verified); }
.source-trace .unavailable { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--slate); }
.source-trace .stamp { display: inline-block; margin-top: var(--s2); }

/* source documents (raw statements) */
.source-doc { margin-top: var(--s4); }
.source-doc > summary {
  cursor: pointer; font-family: var(--font-mono); font-size: var(--fs-sm);
  color: var(--verified-ink); list-style: none; display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) 0; border-top: 1px solid var(--rule);
}
.source-doc > summary::before { content: "▸"; color: var(--verified); }
.source-doc[open] > summary::before { content: "▾"; }
.original-filing { margin: var(--s2) 0 var(--s3); font-size: var(--fs-sm); }
.original-filing a { font-family: var(--font-mono); color: var(--verified-ink); }
.original-filing-note { display: block; font-size: var(--fs-xs); color: var(--slate); margin-top: var(--s1); line-height: 1.4; }
.raw-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: var(--fs-xs); margin-top: var(--s2); }
.raw-table td { padding: 0.2rem var(--s3); border-bottom: 1px solid var(--rule); }
.raw-table td:last-child { text-align: right; color: var(--slate); font-variant-numeric: tabular-nums; }
.raw-table tr:hover td { background: var(--verified-tint); }

/* ---- full statement pages (Task 2) ---- */
.statement-tabs { display: flex; gap: var(--s3); flex-wrap: wrap; margin: var(--s3) 0 var(--s4);
  font-family: var(--font-mono); font-size: var(--fs-sm); }
.stab { color: var(--slate); text-decoration: none; padding: 0.15rem 0; border-bottom: 2px solid transparent; }
.stab:hover { color: var(--verified-ink); }
.stab.active { color: var(--ink); font-weight: 500; border-bottom-color: var(--verified); }
table.statement-ledger .mono-src { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }

/* multi-year / multi-quarter columns (Tasks 2 & 3): a year or quarter per
   column, so headers get a bit of breathing room and each numeric column
   keeps a sane minimum width instead of collapsing when there are many. */
table.statement-ledger th.year-col { text-align: right; vertical-align: bottom; }
table.statement-ledger td.num, table.statement-ledger th.num { min-width: 7.5rem; }
.basis-badge {
  display: block; margin-top: 0.3rem; font-family: var(--font-mono);
  font-size: var(--fs-xs); font-weight: 500; color: var(--attention);
  background: var(--attention-tint); border: 1px solid rgba(var(--attention-rgb),0.45);
  border-radius: 2px; padding: 0.02rem 0.35rem; letter-spacing: 0.02em;
  white-space: nowrap; text-align: right;
}
.statement-links { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate);
  letter-spacing: 0.03em; display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s2); }
.statement-links .glyph { color: var(--verified); }
.statement-links a { color: var(--verified-ink); text-decoration: none; }
.statement-links a:hover { text-decoration: underline; }
.statement-note { color: var(--slate); font-size: var(--fs-xs); margin-top: var(--s3); }
.roce-caveat { color: var(--attention); font-family: var(--font-mono); font-size: var(--fs-xs);
  margin-top: var(--s2); line-height: 1.5; }

/* ---- peer comparison (Task 3) ---- */
table.peer-table th[data-sort] { cursor: pointer; user-select: none; }
table.peer-table th[data-sort]:hover { color: var(--verified-ink); }
tr.this-company td { background: var(--verified-tint); }
.this-badge { display: inline-block; margin-left: 0.4rem; font-family: var(--font-mono);
  font-size: var(--fs-xs); color: var(--verified-ink); background: var(--verified-tint);
  border: 1px solid rgba(var(--verified-rgb),0.45); border-radius: 2px; padding: 0.02rem 0.3rem; letter-spacing: 0.03em; }

/* ---- auth: credentials slip ---- */
.auth-card {
  max-width: 24rem; background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r); padding: var(--s5); position: relative; margin: var(--s4) auto 0;
  box-shadow: var(--shadow-1);
}
.auth-card .field-row { margin-bottom: var(--s4); }
.auth-card label { display: block; font-family: var(--font-mono); font-size: var(--fs-xs);
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--slate); margin-bottom: var(--s1); }
.auth-card input { width: 100%; background: var(--paper); border: 1px solid var(--rule-strong);
  color: var(--ink); font-family: var(--font-body); font-size: var(--fs-sm); padding: 0.5rem 0.6rem; border-radius: var(--r); }
.auth-card .help { font-size: var(--fs-xs); color: var(--slate); margin-top: var(--s1); display: block; line-height: 1.4; }
/* The secondary "or sign in via factory login" card on the signup/login pages
   (screener/platform_auth/). Rendered only when a PLATFORM_AUTH_* flag is on,
   so with the pilot off these rules match nothing. Reuses .auth-card wholesale
   and only steps the emphasis down a notch -- it is an alternative to the
   primary form above it, not a competing call to action. */
.auth-alt-card { margin-top: var(--s5); }
.auth-alt-card h2 { font-size: var(--fs-sm); margin: 0 0 var(--s2); }
.auth-alt-card > .help { margin-bottom: var(--s4); }
.auth-card .btn { width: 100%; margin-top: var(--s2); }
.auth-alt { color: var(--slate); font-size: var(--fs-sm); margin-top: var(--s4); }
.errorlist { color: var(--risk); font-size: var(--fs-xs); list-style: none; padding: 0; margin: var(--s1) 0 0; }
/* rate-limit cooldown notice — a "wait", not an error (ochre, calm) */
.cooldown-note {
  font-family: var(--font-body); font-size: var(--fs-sm); color: var(--attention);
  background: var(--attention-tint); border: 1px solid rgba(var(--attention-rgb),0.45);
  border-left: 3px solid var(--attention); border-radius: var(--r);
  padding: var(--s3) var(--s4); margin-bottom: var(--s4);
}

/* ---- preset screens (Task 1) ---- */
.screen-desc { margin-bottom: var(--s4); }
.screen-desc strong { color: var(--ink); }
.screen-score { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); margin-top: 0.2rem; }
.screen-pass { display: inline-block; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500;
  color: var(--verified-ink); background: var(--verified-tint); border: 1px solid rgba(var(--verified-rgb),0.45);
  border-radius: 2px; padding: 0.02rem 0.35rem; letter-spacing: 0.02em; }
.crit-met { color: var(--verified-ink); font-weight: 700; margin-right: 0.3rem; white-space: nowrap; }
.crit-unmet { color: var(--risk); font-weight: 700; margin-right: 0.3rem; white-space: nowrap; }
.screen-caveat { color: var(--attention); border-color: rgba(var(--attention-rgb),0.45); background: var(--attention-tint); font-size: var(--fs-xs); }
.screen-note { color: var(--slate); font-size: var(--fs-xs); font-style: italic; }

/* "score"-kind screens (Piotroski): a strength BAND, never a Pass badge --
   deliberately NOT reusing .screen-pass's solid fill/color so it can never
   be mistaken for a binary pass/fail claim at a glance. Outlined, with a
   direction glyph instead of a checkmark. */
.band-strong, .band-weak {
  display: inline-block; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500;
  background: transparent; border-radius: 2px; padding: 0.02rem 0.35rem; letter-spacing: 0.02em;
}
.band-strong { color: var(--verified-ink); border: 1px solid var(--verified-ink); }
.band-weak { color: var(--risk); border: 1px solid var(--risk); }

/* Price/volume "reading" screens (RSI, 52-week proximity): a NEUTRAL
   labeled reading, deliberately NOT .band-strong/.band-weak's colored
   quality-judgment styling -- those two imply "the company is
   fundamentally strong/weak"; a technical price reading is neither, and
   coloring it green/red risks reading as an implied buy/sell signal. Same
   shape as the quality bands (outlined stamp, no solid fill, so it's
   never confused with .screen-pass's binary claim either) but in a
   single neutral tone with no directional color coding. */
.band-reading {
  display: inline-block; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500;
  background: transparent; border-radius: 2px; padding: 0.02rem 0.35rem; letter-spacing: 0.02em;
  color: var(--slate); border: 1px solid var(--slate);
}

/* Criterion breakdown rows: a criterion StockProof couldn't COMPUTE must
   never read the same as one the company FAILED. Not-met stays plain (red
   label only, matches the ledger's existing failure language); N/A gets
   the same "nil entry" hatched treatment as .na elsewhere plus a muted row
   wash, so it visually reads as "excluded from scoring", not "struck
   down". */
.crit-na {
  display: inline-block; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--slate); border: 1px dashed var(--rule-strong); border-radius: 2px;
  padding: 0.02rem 0.35rem; margin-right: 0.3rem; letter-spacing: 0.02em; white-space: nowrap;
  background: repeating-linear-gradient(135deg, transparent, transparent 4px, rgba(var(--slate-rgb),0.06) 4px, rgba(var(--slate-rgb),0.06) 5px);
}
tr.crit-row-na td { color: var(--slate); background: rgba(var(--slate-rgb),0.035); }
tr.crit-row-na td:last-child { color: var(--slate); }
tr.crit-row-unmet td:first-child { color: var(--risk); }

/* ---- trend analytics (Task 2, company detail) ---- */
.trend-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s4); margin: var(--s4) 0; }
.trend-card { background: var(--surface); border: 1px solid var(--rule-strong); border-radius: var(--r); padding: var(--s4); box-shadow: var(--shadow-1); }
.trend-card:hover { border-color: var(--slate); box-shadow: var(--shadow-2); }
.trend-card h3 { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--slate); margin: 0 0 var(--s3); }
.cagr-row { display: flex; justify-content: space-between; align-items: baseline; padding: 0.25rem 0;
  border-bottom: 1px solid var(--rule); font-size: var(--fs-sm); }
.cagr-row:last-child { border-bottom: none; }
.cagr-row .cagr-value { font-family: var(--font-mono); font-weight: 600; color: var(--ink); }
.cagr-row .cagr-value.negative { color: var(--risk); }
.margin-direction, .flag-badge {
  display: inline-block; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 500;
  border-radius: 2px; padding: 0.05rem 0.4rem; letter-spacing: 0.02em;
}
.margin-direction.expanding, .flag-badge.clear { color: var(--verified-ink); background: var(--verified-tint); border: 1px solid rgba(var(--verified-rgb),0.45); }
.margin-direction.eroding, .flag-badge.flagged { color: var(--risk); background: var(--risk-tint); border: 1px solid rgba(var(--risk-rgb),0.4); }
.margin-direction.flat { color: var(--slate); background: var(--paper); border: 1px solid var(--rule-strong); }
.percentile-row { display: flex; align-items: center; gap: var(--s3); padding: 0.3rem 0; font-size: var(--fs-sm); }
.percentile-row .label { width: 6.5rem; font-family: var(--font-mono); color: var(--slate); font-size: var(--fs-xs); }
.percentile-bar { flex: 1; height: 0.55rem; background: var(--paper); border: 1px solid var(--rule); border-radius: 3px; position: relative; overflow: hidden; }
.percentile-bar .fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--verified); opacity: 0.55; }
.percentile-row .pct-value { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink); width: 3.5rem; text-align: right; }

/* ---- Trace Score (composite quality synthesis) ---- */
/* The headline number and its disclaimer are ONE block on purpose: the
   "not a rating/recommendation/forecast" caveat must sit in direct visual
   proximity to the figure it qualifies, never be readable apart from it
   (same proximity discipline as the Growth Without Dilution / RSI notes).
   Deliberately monochrome: a low score renders in the identical neutral
   ink as a high one -- no red/green, no warning styling on the composite
   itself, since the number carries no qualitative band. */
.trace-headline {
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--verified); border-radius: var(--r);
  padding: var(--s5) var(--s4); margin: var(--s4) 0 var(--s5);
}
.trace-number { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-ratio);
  line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.trace-number.na { font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-ratio-na); color: var(--slate); }
.trace-outof { font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-sm); color: var(--slate); margin-left: 0.35rem; }
.trace-computed-from { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); margin-top: var(--s2); }
.trace-disclaimer {
  margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--rule);
  color: var(--ink); font-size: var(--fs-sm); line-height: 1.5; max-width: 60ch;
}
.trace-disclaimer .glyph { color: var(--slate); margin-right: 0.25rem; }
.trace-pillars { margin-top: var(--s4); }
.trace-pillar-score { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-ratio);
  line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; margin-top: var(--s2); }
.trace-pillar-score.na { font-family: var(--font-mono); font-weight: 500; font-size: var(--fs-ratio-na); color: var(--slate); }
.trace-pillar-sub { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); margin-top: var(--s1); }
.trace-pillar-sub .trace-count { color: var(--ink); }
.trace-cite { margin-top: var(--s3); font-family: var(--font-mono); font-size: var(--fs-xs); }
.trace-cite a { color: var(--verified-ink); text-decoration: none; }
.trace-cite a:hover { text-decoration: underline; }
.trace-method { margin-top: var(--s5); }
.trace-method .statement-note { max-width: 70ch; line-height: 1.55; }

/* ---- utility ---- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---- home page ---- */
.hero { text-align: center; padding: var(--s7) var(--s4) var(--s6); }
.hero h1 { font-size: var(--fs-display); max-width: 38rem; margin: 0 auto; }
.hero .sub { color: var(--slate); font-size: var(--fs-body); max-width: 34rem; margin: var(--s3) auto 0; }
.hero-search {
  display: flex; justify-content: center; gap: var(--s3); flex-wrap: wrap;
  margin: var(--s5) auto 0; max-width: 34rem;
}
.hero-search input {
  flex: 1; min-width: 14rem; background: var(--surface); border: 1px solid var(--rule-strong);
  color: var(--ink); font-family: var(--font-body); font-size: var(--fs-body);
  padding: 0.6rem 0.9rem; border-radius: var(--r); height: 2.75rem;
}
.hero-search input:hover, .hero-search input:focus { border-color: var(--verified); }
.hero-search .btn { height: 2.75rem; padding: 0.5rem 1.4rem; }
.hero-stats { display: flex; justify-content: center; gap: var(--s7); margin-top: var(--s6); }
.stat { text-align: center; text-decoration: none; }
a.stat:hover .stat-label { color: var(--verified-ink); }
.stat-value {
  display: block; font-family: var(--font-display); font-weight: 800;
  font-size: var(--fs-ratio); color: var(--verified-ink); font-variant-numeric: tabular-nums;
}
.stat-label { display: block; font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--slate); margin-top: var(--s1); }

.section-sub { color: var(--slate); font-size: var(--fs-sm); margin: var(--s2) 0 var(--s4); max-width: 42rem; }

.quick-access { display: flex; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s6); }
.quick-chip {
  display: inline-flex; flex-direction: column; gap: 0.1rem;
  border: 1px solid var(--rule-strong); background: var(--surface); border-radius: var(--r);
  padding: var(--s2) var(--s4); text-decoration: none; min-width: 9rem;
}
.quick-chip:hover { border-color: var(--verified); background: var(--verified-tint); }
.quick-chip .qc-ticker { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--verified-ink); letter-spacing: 0.02em; }
.quick-chip .qc-name { font-size: var(--fs-sm); color: var(--ink); }

.screen-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--s4); }
.screen-card {
  display: block; border: 1px solid var(--rule-strong); background: var(--surface);
  border-radius: var(--r); padding: var(--s4); text-decoration: none;
}
.screen-card:hover { border-color: var(--verified); box-shadow: 0 1px 0 var(--verified); }
.screen-card .sc-name { font-family: var(--font-display); font-weight: 700; font-size: 1rem; color: var(--ink); }
.screen-card .sc-desc { color: var(--slate); font-size: var(--fs-sm); margin-top: var(--s2); line-height: 1.4; }

/* ---- company detail: price history + quarterly chart (visualization session) ---- */
.price-history-section { margin: var(--s5) 0; }
.range-toggle { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); }
.range-opt {
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: 0.02em;
  color: var(--slate); text-decoration: none; padding: 0.28rem 0.65rem;
  border: 1px solid var(--rule-strong); border-radius: var(--r);
}
.range-opt:hover { background: var(--verified-tint); color: var(--ink); }
.range-opt.active { background: var(--ink); border-color: var(--ink); color: var(--surface); }

/* Task 3: metric selector for the multi-metric historical chart. Sits above
   the shared canvas; the range toggles above still window the daily axis. */
.metric-select-label { font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.02em; color: var(--slate); margin-right: var(--s2); }
.metric-select { font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--ink); background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r); padding: 0.28rem 0.5rem; cursor: pointer; }
.metric-select:hover { border-color: var(--slate); }

/* Indicator-expansion session: the Bollinger Bands overlay checkbox (sits
   beside the metric selector or above the plain price chart) and the
   technical-indicator sub-chart's own selector/tiles reuse metric-select's
   styling and .portfolio-summary's tile grid exactly -- no new visual
   language for either. */
.chart-overlay-toggle { font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--slate); margin-left: var(--s3); cursor: pointer; user-select: none; }
.chart-overlay-toggle input { vertical-align: middle; margin-right: 0.3rem; }

/* The canvas-holding box and the legend below it are separate elements
   (responsive audit follow-up, 2026-08-25) -- they used to be nested,
   legend-inside-fixed-height-canvas-wrap. Chart.js's "the wrapper's
   height sizes the canvas" contract (see .history-chart-wrap above)
   means that wrapper's height must fit ONLY the canvas; the legend was
   being squeezed into the SAME fixed box, had no room left in it (most
   visibly on the mobile-height override), and visually overflowed
   underneath into whatever followed in the DOM -- the quarterly table's
   own header row -- rendering the two on top of each other. Keeping the
   legend as an ordinary sibling AFTER the fixed-height box, not a child
   inside it, means it always gets its own real flow space regardless of
   canvas height. */
.qtr-chart-canvas-wrap { margin: var(--s3) 0 0; height: 20rem; }
.qtr-chart { width: 100%; height: 100%; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: var(--s3); box-sizing: border-box; }
.qtr-chart-legend { display: flex; flex-wrap: wrap; gap: var(--s4); margin: var(--s3) 0 var(--s4);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
.chart-swatch { display: inline-block; width: 0.9rem; height: 0.9rem; border-radius: 2px;
  vertical-align: middle; margin-right: 0.3rem; border: 1px solid var(--rule); }
.bar-revenue-swatch { background: var(--slate); opacity: 0.35; }
.bar-profit-swatch { background: var(--verified-ink); }
.bar-loss-swatch { background: var(--risk); }

/* ---- ultrawide: cap the two card grids whose item count is large/
   unbounded (Task 1). Every other auto-fit/flex-wrap grid in this file
   (.ratio-grid, .trend-grid, .calc-grid, .portfolio-summary,
   .metric-assumptions) already grows to more columns as --maxw grows and
   is self-limiting to its own (small, fixed) item count -- nothing to add
   there. These two aren't: .screen-cards always renders all 20 preset
   screens and .holding-metrics-grid renders one card per holding, so past
   ~1900px the plain auto-fit minmax would spread them across 8-11 skinny
   columns instead of a few comfortably-wide ones. */
@media (min-width: 1900px) {
  .screen-cards { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .holding-metrics-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .calc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ---- responsive ---- */
/* Nav collapses behind the hamburger toggle on its OWN, wider breakpoint
   (responsive audit, 2026-08-24): at seven items for a logged-in visitor,
   the plain flex-wrap nav still fit at 768px (tablet) without overflowing,
   but only by wrapping to an untidy second row -- not "collapsed
   sensibly" as asked. 860px comfortably covers both the 375px and 768px
   checkpoints with the same hamburger, single clean row above it. Kept
   separate from the narrower @media(max-width:640px) block below (touch-
   target sizing, chart heights, etc.) since those genuinely are phone-only
   concerns, not tablet ones. */
@media (max-width: 860px) {
  .tagline { display: none; }
  .nav-toggle { display: inline-flex; }
  /* The top bar's own three items (mark, section pills, theme+account)
     always fit at this width without collapsing -- only the section-local
     sub-nav below it, which now carries 11 grouped links instead of the
     old flat row, needs the hamburger. */
  .section-nav-links {
    display: none; width: 100%; margin-left: 0; margin-top: var(--s3);
    flex-direction: column; align-items: stretch; gap: 0;
    border-top: 1px solid var(--rule); padding-top: var(--s2);
  }
  .section-nav-links.open { display: flex; }
  .section-nav-links .unit-toggle { align-self: flex-start; margin-bottom: var(--s3); }
  .nav-group {
    display: flex; flex-direction: column; align-items: stretch; gap: 0;
    width: 100%; padding-left: 0; border-left: none;
    border-top: 1px solid var(--rule); padding-top: var(--s2); margin-top: var(--s2);
  }
  .nav-group-label { padding: var(--s2) var(--s1) var(--s1); }
  .nav-group a { width: 100%; box-sizing: border-box; }
  /* Touch targets: every nav row a comfortable >=44px tap height, not a
     mouse-sized text link. */
  .nav-group a {
    padding: var(--s3) var(--s1); min-height: 44px; box-sizing: border-box;
    border-bottom: 1px solid var(--rule);
  }
}

@media (max-width: 640px) {
  main { padding: var(--s5) var(--s4) var(--s6); }
  .top-shell-inner, .section-nav-inner { padding: var(--s3) var(--s4); gap: var(--s3); }

  .query-slip .fields { gap: var(--s3); }
  .field { width: 100%; }
  .ratio-grid { grid-template-columns: 1fr; }
  .hero { padding: var(--s6) var(--s3); }
  .hero-stats { gap: var(--s5); }
  .quick-chip { min-width: 0; flex: 1 1 40%; }
  .history-chart-wrap, .qtr-chart-canvas-wrap { height: 16rem; }
  .frontier-chart-wrap { height: 20rem; }

  /* Touch targets (responsive audit, 2026-08-24): the same controls sized
     for a mouse cursor on desktop get a comfortably tappable >=44px
     height here -- buttons, table row actions, form fields, the price-
     chart period toggle, and sortable column headers. box-sizing:border-box
     is already global, so min-height already accounts for padding/border. */
  .btn, .btn-ghost { min-height: 44px; padding: 0.6rem 1.1rem; }
  .wl-btn, a.wl-btn { min-height: 40px; padding: 0.5rem 0.75rem; }
  .range-opt { min-height: 40px; padding: 0.5rem 0.85rem; display: inline-flex; align-items: center; }
  .field input, .field select,
  .auth-card input,
  .calc-field input,
  .calc-picker select, .calc-picker input[type="text"] {
    width: 100%; min-height: 44px;
  }
  .sort-link { display: inline-block; padding: 0.35rem 0.1rem; margin: -0.35rem -0.1rem; }
  .clear-link { display: inline-block; padding: 0.5rem 0; }
}

/* ---- motion ---- */
@media (prefers-reduced-motion: no-preference) {
  a, .btn, .btn-ghost, .wl-btn, .nav-group a, .section-pill, .top-shell-right .linkish, .field input, .field select {
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
  }
  /* Cards + the portfolio-switcher tab (visual richness pass): the same
     quiet 120ms feel as the interactive elements above, extended to the
     new border/shadow hover lift. Every other toggle/pill/chip already
     gets this for free above -- they're plain <a> tags. */
  .paper-card, .summary-tile, .metric-card, .calc-card, .trend-card, .pf-tab {
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
  }
}

/* --- Portfolio switcher (multi-portfolio session) ------------------------ */
.pf-switcher {
  margin-bottom: var(--s4); padding: var(--s3) var(--s4);
  border: 1px solid var(--rule-strong); border-radius: var(--r-lg);
  background: var(--surface);
}
.pf-tabs { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2); }
.pf-tabs-label { font-size: var(--fs-sm); color: var(--slate); font-weight: 600; margin-right: var(--s1); }
.pf-tab-form { display: inline; margin: 0; }
.pf-tab {
  display: inline-flex; align-items: center; gap: var(--s1);
  padding: var(--s1) var(--s3); border-radius: var(--r);
  border: 1px solid var(--rule-strong); background: var(--paper);
  color: var(--slate); font: inherit; font-size: var(--fs-sm); cursor: pointer;
}
button.pf-tab:hover { border-color: var(--slate); color: var(--ink); }
.pf-tab.active {
  background: var(--verified); color: var(--on-accent); border-color: var(--verified);
  font-weight: 600; cursor: default;
}
.pf-default-badge {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.03em;
  padding: 0.05rem 0.3rem; border-radius: 2px;
  background: rgba(0,0,0,0.08); color: inherit;
}
.pf-tab.active .pf-default-badge { background: rgba(255,255,255,0.22); }
.pf-manage { margin-left: auto; }
.pf-manage-toggle {
  list-style: none; cursor: pointer; font-size: var(--fs-sm);
  color: var(--slate); padding: var(--s1) var(--s2);
}
.pf-manage-toggle::-webkit-details-marker { display: none; }
.pf-manage[open] .pf-manage-toggle { color: var(--ink); font-weight: 600; }
.pf-manage-panel {
  margin-top: var(--s3); padding-top: var(--s3);
  border-top: 1px solid var(--rule);
  display: flex; flex-direction: column; gap: var(--s2);
}
.pf-manage-row { display: flex; gap: var(--s2); align-items: center; margin: 0; flex-wrap: wrap; }
.pf-manage-row input[type="text"] {
  padding: var(--s1) var(--s2); border: 1px solid var(--rule-strong);
  background: var(--paper); color: var(--ink);
  border-radius: var(--r); font: inherit; font-size: var(--fs-sm); min-width: 12rem;
}
.pf-delete { color: var(--attention); border-color: var(--rule-strong); }
.pf-delete:hover { border-color: var(--attention); color: var(--attention); background: var(--paper); }
.pf-scope-note { margin: var(--s3) 0 0; font-size: var(--fs-sm); color: var(--slate); }
.confirm-box {
  max-width: 44rem; padding: var(--s4); border: 1px solid var(--rule-strong);
  border-radius: var(--r-lg); background: var(--surface);
}
.confirm-actions { display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; margin-top: var(--s4); }

/* --- Market Context: sector rotation + watchlist digest ------------------ */
.window-pills { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); }
.window-label { font-size: var(--fs-sm); color: var(--slate); font-weight: 600; margin-right: var(--s1); }
.window-pill {
  padding: var(--s1) var(--s3); border-radius: 999px;
  border: 1px solid var(--rule-strong); background: var(--paper);
  color: var(--slate); font-size: var(--fs-sm); text-decoration: none;
}
a.window-pill:hover { border-color: var(--slate); color: var(--ink); }
.window-pill.active { background: var(--ink); color: var(--surface); border-color: var(--ink); font-weight: 600; }
.sector-details > summary { cursor: pointer; font-weight: 600; }
.sector-details > summary::-webkit-details-marker { color: var(--slate); }
.mini-table { width: 100%; margin-top: var(--s2); border-collapse: collapse; font-size: var(--fs-sm); }
.mini-table th, .mini-table td { text-align: left; padding: var(--s1) var(--s2); border-bottom: 1px solid var(--rule); }
.mini-table th.num, .mini-table td.num { text-align: right; }
.mini-table tbody tr:hover td { background: var(--verified-tint); }
.digest-section { margin-bottom: var(--s5, 1.5rem); }
.notable-tag {
  display: inline-block; padding: 0.05rem 0.4rem; border-radius: 2px;
  background: var(--attention); color: var(--surface);
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.03em; font-weight: 600;
}

/* Sector rotation: emphasize the currently-selected weighting column. */
.ledger th.col-active, .ledger td.col-active { background: var(--paper); }
.ledger th.col-active { border-bottom-color: var(--slate); }

/* --- Market Context: market breadth --------------------------------------
   New highs/lows' two <details> lists side by side on wide screens; the
   sector heatmap grid. Heatmap cell fills are computed server-side
   (market_breadth.heat_intensity) as an inline color-mix() against the
   existing --verified/--risk accents -- no new color tokens. */
.mb-highlow-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s4); margin: var(--s3) 0 var(--s4); }
.breadth-heatmap { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--s2); margin: var(--s3) 0 var(--s4); }
.heat-cell {
  display: flex; flex-direction: column; gap: var(--s1); padding: var(--s3);
  border: 1px solid var(--rule-strong); border-radius: var(--r);
  background: var(--surface);
}
.heat-cell-na { background: var(--surface); opacity: 0.6; }
.heat-sector { font-size: var(--fs-xs); color: var(--slate); font-weight: 600; }
.heat-value { font-family: var(--font-mono); font-weight: 700; font-size: var(--fs-body); color: var(--ink); }

/* --- Shareable read-only links ------------------------------------------ */
.shared-banner {
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
  padding: var(--s3) var(--s4); margin-bottom: var(--s4);
  border: 1px solid var(--rule-strong); border-left: 4px solid var(--verified);
  border-radius: var(--r); background: var(--surface); font-size: var(--fs-sm); color: var(--slate);
}
.shared-tag {
  display: inline-block; padding: 0.1rem 0.5rem; border-radius: 2px;
  background: var(--verified); color: var(--on-accent); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em; font-size: 0.72rem;
}
.share-panel {
  margin-bottom: var(--s4); border: 1px solid var(--rule-strong);
  border-radius: var(--r-lg); background: var(--surface); padding: var(--s3) var(--s4);
}
.share-toggle { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); color: var(--ink); }
.share-toggle::-webkit-details-marker { color: var(--slate); }
.share-body { margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--rule); }
.share-create { margin: var(--s2) 0 var(--s3); }
.share-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.share-table th, .share-table td { text-align: left; padding: var(--s2); border-bottom: 1px solid var(--rule); vertical-align: middle; }
.share-table tbody tr:hover td { background: var(--verified-tint); }
.col-picker-grid {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); margin-bottom: var(--s3);
}
.col-picker-opt {
  display: inline-flex; align-items: center; gap: var(--s1);
  font-size: var(--fs-sm); color: var(--ink); cursor: pointer;
}

/* --- Custom formula screener (screener/formula/) ------------------------ */
/* The formula input is a filter, so it lives in the query slip beside the
   others -- but it needs far more room than a number box, hence its own
   width rule rather than the shared .field sizing. Colours come from the
   base input rule (see the "native form controls" note at the top of this
   file): a control must NEVER set a background without also setting a
   colour, or it reads black-on-dark in dark mode. */
.formula-field { flex: 1 1 26rem; min-width: 18rem; }
input.formula-input {
  width: 100%; font-family: var(--font-mono, monospace); font-size: 0.85rem;
}
.field-help { display: block; margin-top: var(--s1); font-size: var(--fs-xs); color: var(--slate); }
.formula-errors {
  margin: var(--s1) 0 0; padding-left: 1.1rem; list-style: disc;
  font-size: var(--fs-xs); color: var(--attention);
}
input.formula-input:has(~ .formula-errors) { border-color: var(--attention); }
.formula-group-head {
  margin: var(--s3) 0 var(--s2); font-size: var(--fs-sm); color: var(--slate);
  text-transform: uppercase; letter-spacing: 0.04em;
}
table.formula-metric-table { font-size: var(--fs-xs); }
table.formula-metric-table td.mono { white-space: nowrap; }
.formula-saved-list, .formula-unevaluable-list { list-style: none; margin: 0 0 var(--s3); padding: 0; }
.formula-saved-list li, .formula-unevaluable-list li {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
  padding: var(--s2) 0; border-bottom: 1px solid var(--rule); font-size: var(--fs-sm);
}
.formula-saved-list li form { margin: 0; }
.formula-saved-list .mono {
  font-family: var(--font-mono, monospace); font-size: 0.8rem; color: var(--slate);
}
.formula-save-form .fields { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: flex-end; }
.formula-unevaluable .na { color: var(--slate); font-size: var(--fs-xs); }

.share-url-cell { display: flex; gap: var(--s2); align-items: center; }
input.share-url {
  min-width: 16rem; flex: 1; padding: var(--s1) var(--s2); font-family: var(--font-mono, monospace);
  font-size: 0.8rem; border: 1px solid var(--rule-strong); border-radius: var(--r); background: var(--paper); color: var(--ink);
}
.share-actions { display: flex; gap: var(--s2); }
.share-actions form { margin: 0; }
.share-revoke { color: var(--attention); border-color: var(--rule-strong); }
.share-revoke:hover { border-color: var(--attention); color: var(--attention); background: var(--paper); }

.notes-panel {
  margin-bottom: var(--s5); border: 1px solid var(--rule-strong);
  border-radius: var(--r-lg); background: var(--surface); padding: var(--s3) var(--s4);
}
.notes-panel h2 { font-size: var(--fs-body); margin-bottom: var(--s3); }
.note-form { margin-bottom: var(--s3); }
.note-form textarea, .note-edit-toggle textarea {
  width: 100%; background: var(--paper); border: 1px solid var(--rule-strong);
  color: var(--ink); font-family: var(--font-body); font-size: var(--fs-sm);
  padding: 0.5rem 0.6rem; border-radius: var(--r); resize: vertical; margin-bottom: var(--s2);
}
.note-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--s3); }
.note-card { border: 1px solid var(--rule); border-radius: var(--r); background: var(--paper); padding: var(--s3); }
.note-meta { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); margin-bottom: var(--s2); }
.note-text { font-size: var(--fs-sm); color: var(--ink); white-space: pre-wrap; margin: 0 0 var(--s2); line-height: 1.5; }
.note-actions { display: flex; gap: var(--s2); align-items: flex-start; }
.note-edit-toggle summary { cursor: pointer; }
.note-edit-toggle summary::-webkit-details-marker { color: var(--slate); }
.note-edit-toggle form { margin-top: var(--s2); }
.note-delete-form { margin: 0; }
.note-delete { color: var(--risk); border-color: rgba(var(--risk-rgb),0.4); }
.note-delete:hover { background: var(--risk-tint); }

/* ---- Learning Mode + AI Mode -------------------------------------------
   Uses only the existing tokens (--paper/--surface/--rule/--slate/--verified/
   --risk and the --s* spacing scale); no new colours, no new type scale, no
   new layout primitive. The explanation panels are <details> because they are
   OPT-IN EXPLANATORY content, which is a different thing from the mandatory
   caveats elsewhere in this app -- those stay uncollapsed and unmoved. See
   screener/learning.py's docstring. */

.learn-note {
  margin-top: var(--s2);
  border-left: 2px solid var(--rule-strong);
  background: var(--paper);
  border-radius: 2px;
}
.learn-note > summary {
  cursor: pointer; list-style: none;
  padding: var(--s2) var(--s3);
  font-size: var(--fs-xs); color: var(--slate);
  display: flex; align-items: center; gap: var(--s2);
}
.learn-note > summary::-webkit-details-marker { display: none; }
.learn-note > summary:hover { color: var(--verified); }
.learn-note[open] > summary { color: var(--ink); border-bottom: 1px solid var(--rule); }
.learn-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.05rem; height: 1.05rem; flex: 0 0 auto;
  border: 1px solid var(--rule-strong); border-radius: 50%;
  font-family: var(--font-mono); font-size: 0.62rem; line-height: 1;
  color: var(--verified); background: var(--surface);
}
.learn-body { padding: var(--s3); font-size: var(--fs-xs); line-height: 1.65; color: var(--ink); }
.learn-body p { margin: 0 0 var(--s2); }
.learn-body p:last-child { margin-bottom: 0; }
.learn-short { font-weight: 600; }
.learn-formula {
  font-family: var(--font-mono); color: var(--verified-ink);
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: 2px; padding: var(--s2); overflow-x: auto;
}
.learn-inapp { color: var(--slate); }
.learn-inapp-tag {
  font-family: var(--font-mono); font-size: 0.68rem; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--verified); margin-right: var(--s2);
}
.learn-video a { color: var(--verified); }
.learn-video-src {
  display: block; color: var(--slate); font-size: 0.68rem;
  font-family: var(--font-mono); margin-top: 0.1rem;
}
.learn-inline-group { margin-bottom: var(--s4); display: grid; gap: var(--s2); }

.learn-index {
  font-size: var(--fs-xs); color: var(--slate); line-height: 2;
  margin-bottom: var(--s5); padding-bottom: var(--s3);
  border-bottom: 1px solid var(--rule);
}
.learn-index a { color: var(--verified); text-decoration: none; }
.learn-index a:hover { text-decoration: underline; }
.learn-card { margin-bottom: var(--s4); }
.learn-card p { font-size: var(--fs-sm); line-height: 1.7; margin: 0 0 var(--s3); }
.learn-card p:last-child { margin-bottom: 0; }

/* ---- AI Mode ---- */
.ai-scope {
  border: 1px solid var(--rule-strong); border-radius: 2px;
  background: var(--surface); padding: var(--s4); margin-bottom: var(--s4);
}
.ai-scope-head {
  font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--slate); margin: 0 0 var(--s3);
}
.ai-scope-cols { display: grid; grid-template-columns: 1fr; gap: var(--s4); }
@media (min-width: 760px) { .ai-scope-cols { grid-template-columns: 1fr 1fr; } }
.ai-scope-label {
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: 600;
  margin: 0 0 var(--s2);
}
.ai-scope-label.ai-yes { color: var(--verified); }
.ai-scope-label.ai-no { color: var(--risk); }
.ai-scope ul { margin: 0; padding-left: 1.1rem; }
.ai-scope li { font-size: var(--fs-xs); color: var(--ink); line-height: 1.7; }
.ai-scope-foot {
  margin: var(--s3) 0 0; padding-top: var(--s3); border-top: 1px solid var(--rule);
  font-size: var(--fs-xs); color: var(--slate); line-height: 1.65;
}

.ai-meta {
  display: flex; flex-wrap: wrap; gap: var(--s3);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate);
  margin-bottom: var(--s4);
}
.ai-meta-item { border: 1px solid var(--rule); border-radius: 2px; padding: 0.1rem var(--s2); }

.ai-form { margin-bottom: var(--s5); }
.ai-form label { display: block; font-size: var(--fs-xs); color: var(--slate); margin-bottom: var(--s2); }
.ai-question-input { width: 100%; box-sizing: border-box; font-size: var(--fs-sm); line-height: 1.6; }
.ai-help { font-size: var(--fs-xs); color: var(--slate); margin: var(--s2) 0 var(--s3); }

.ai-answer-block {
  border: 1px solid var(--rule-strong); border-left: 3px solid var(--verified);
  border-radius: 2px; background: var(--surface);
  padding: var(--s4); margin-bottom: var(--s4);
}
/* The disclaimer is the FIRST thing in the block, above the answer, always
   visible. Its placement is asserted by test_ai_mode_views.py -- do not move
   it below the answer and do not collapse it. */
.ai-disclaimer {
  margin: 0 0 var(--s3); padding-bottom: var(--s3);
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-xs); color: var(--ink); line-height: 1.65;
}
.ai-disclaimer strong { color: var(--risk); }
.ai-source {
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate);
  margin: 0 0 var(--s3);
}
.ai-source-foot { font-size: var(--fs-xs); color: var(--slate); margin: var(--s3) 0 0; }
.ai-answer-text { font-size: var(--fs-sm); line-height: 1.75; }
.ai-answer-text p { margin: 0 0 var(--s3); }
.ai-answer-concept { margin-bottom: var(--s4); }
.ai-answer-concept h3 { font-size: var(--fs-sm); margin: 0 0 var(--s2); }
.ai-answer-concept p { font-size: var(--fs-xs); line-height: 1.7; }
.ai-refusal-head {
  font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--risk); margin: 0 0 var(--s2);
}
.ai-refusal { font-size: var(--fs-sm); line-height: 1.7; margin: 0; }

/* ---- Learning Notes (Task 1, the Learning Notes session) ---------------
   Reuses .learn-note's base card/summary styling verbatim (border-left,
   collapsed by default, same reasoning as the explanation panels: this is
   opt-in personal content next to the concept, not a page-wide block like
   the per-company .notes-panel). .learn-my-notes only overrides the badge
   accent so a reader's OWN note is visually distinct from StockProof's
   explanation text, and reuses .note-form/.note-list/.note-card/.note-*
   from the per-company notes feature verbatim -- same journal shape,
   same visual language, deliberately not reinvented. */
.learn-my-notes { margin-top: var(--s3); }
.learn-my-notes > summary { color: var(--slate); }
.learn-badge-note { color: var(--slate); font-size: 0.58rem; }
.learn-my-notes .note-form { margin-bottom: var(--s3); }
.learn-my-notes-login { margin-top: var(--s3); font-size: var(--fs-xs); }

/* ---- Company detail: notes + price box, side by side at page bottom ----
   The notes panel moved here from the top of the page (Task 2, the Learning
   Notes / notes-position session). Same flex pairing shape as .panel-pair
   (the income/balance-sheet source-doc pair further up this page), but with
   its own class rather than reusing .panel-pair directly: that rule forces
   `flex: 1 1 28rem` on every child, which would make the small price box
   claim as much width as the notes panel -- here the notes panel is the
   majority column and the price box is a narrow sidebar beside it. */
.notes-price-row {
  display: flex; flex-wrap: wrap; gap: var(--s5); align-items: flex-start;
}
.notes-price-row > .notes-panel { flex: 3 1 28rem; min-width: 0; margin-bottom: 0; }
.price-box {
  flex: 1 1 12rem; max-width: 16rem;
  display: flex; flex-direction: column; gap: 0.15rem;
  background: var(--surface); border: 1px solid var(--rule-strong);
  border-radius: var(--r-lg); padding: var(--s3) var(--s4);
}
.price-box .tile-label {
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.price-box .tile-value {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-ratio); color: var(--ink);
}
.price-box-sub { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
.price-box-asof { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--slate); }
