/* Inter for interface text, JetBrains Mono for anything that is a number or a
   ticker. Two families, one job each: a page full of one typeface cannot tell
   the reader "this is prose" from "this is data" without saying so in words.
   Both fall back to the system stack immediately, so a blocked or slow font
   request costs layout nothing - no invisible text, no reflow. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;650;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

:root {
    color-scheme: light;
    --font-sans: 'Inter', system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --page:           #f9f9f7;
    --surface-1:      #fcfcfb;
    --text-primary:   #0b0b0b;
    --text-secondary: #52514e;
    /* #898781 was only 3.4:1 on the page in light mode. It is used for ~60
       small-text labels (timestamps, sources, units), so it failed the 4.5:1
       floor everywhere at once while reading as "just a subtle grey". Darkened
       to 4.8:1; the dark-theme value already passed and is unchanged. */
    --text-muted:     #706e68;
    --grid:           #e1e0d9;
    --border:         rgba(11,11,11,0.10);
    /* An institutional indigo rather than a generic sky blue - chosen and
       measured, not eyeballed: 7.67:1 against this page, 8.08:1 under white
       button text, both comfortably clear of the old blue's 4.19:1 (a
       pre-existing near-miss on body text this replaces rather than
       inherits). --bar is the text/link/focus role; --bar-solid is a
       separate token for a WHITE-TEXT FILL, because the light value that
       glows correctly against a near-black page in dark mode is too light
       to hold 4.5:1 under white text, and one token cannot serve both without
       failing one of them silently. */
    --bar:            #3538cd;   /* sequential indigo: signal magnitude, text/link/focus */
    --bar-solid:      #3538cd;   /* white-text button fill */
    --bar-glow:       rgba(53,56,205,.35);
    --bar-track:      #f0efec;   /* neutral diverging midpoint (light) */
    /* Both poles clear 4.5:1 on the light card surface. #0ca30c reached only
       3.3:1 there, which is unreadable for a lot of people and is the number
       carrying the whole bullish/bearish meaning. Always paired with a sign and
       a word regardless, so colour is never the only channel. */
    --bull:           #097a09;   /* bullish pole - always paired with +sign & label */
    --bear:           #d03b3b;   /* bearish pole - always paired with -sign & label */
    /* Two roles, two ramps. The vivid colours below are for BORDERS AND FILLS,
       where the bar is 3:1 (non-text UI) and vividness is the point: the stale
       banner and the concentration callout need to be seen from across a room.
       Text needs 4.5:1, and the same amber that works as a 4px border is 1.7:1
       as body copy - which is what "notable" severity on the health page and
       the mixed-evidence markers were rendering at, i.e. nearly invisible.
       Anything that colours TEXT uses a *-text token. */
    --status-good:     #097a09;   /* text: matches --bull, which was fixed for this */
    /* #fab219 is 1.7:1 on this page - a warning outline you cannot see. Amber
       on white is simply low contrast, so the light theme uses a goldenrod that
       clears the 3:1 non-text bar and still reads as amber. Dark mode keeps the
       bright one, where it is the readable choice. */
    --status-warning:  #b8860b;   /* fill/border only */
    --status-critical: #d03b3b;   /* text and fill: clears both */
    --status-warning-text: #8a6200;
    /* --status-serious was removed: defined since the health page landed and
       referenced by nothing, so it was a colour nobody could see being wrong. */
  }
  @media (prefers-color-scheme: dark) {
    :root {
      color-scheme: dark;
      --page:           #0d0d0d;
      --surface-1:      #1a1a19;
      --text-primary:   #ffffff;
      --text-secondary: #c3c2b7;
      --text-muted:     #898781;
      --grid:           #2c2c2a;
      --border:         rgba(255,255,255,0.10);
      /* Same split as light mode, for the same reason, on a bug this replaces:
         the old dark --bar (#3987e5) held white text at only 3.64:1, below the
         4.5:1 floor every other colour in this file was tuned to - it had
         simply never been checked in the "button fill" role. #818cf8 is the
         glow: 6.52:1 against the page, 5.84:1 against a card. #4f46e5 is the
         fill: 6.29:1 under white text. */
      --bar:            #818cf8;   /* text/link/focus - glows against near-black */
      --bar-solid:      #4f46e5;   /* white-text button fill */
      --bar-glow:       rgba(129,140,248,.45);
      --bar-track:      #383835; /* neutral diverging midpoint (dark) */
      --bull:           #0ca30c;
      /* Lighter than the light-mode red: #d03b3b only reaches 3.6:1 on the card
         surface, below the 4.5:1 needed for normal text. This clears it on both
         the page and the cards, and balances the green's weight. */
      --bear:           #e35d5d;
      /* The same fix, which the status ramp never got. --status-critical kept
         the light-mode red here and sat at 3.6:1 on cards - and it is what the
         Portfolio Health page colours a "critical" severity with, so the most
         urgent label on the site was the least readable one. The other three
         status colours already clear 4.5:1 on both dark surfaces unchanged. */
      --status-critical: #e35d5d;
      /* Both of these invert with the ground: the darkened variants that rescue
         light mode are the unreadable ones here, and the vivid originals are
         the readable ones (green 5.8:1, amber 10.6:1 on the dark page). */
      --status-good:     #0ca30c;
      --status-warning:      #fab219;
      --status-warning-text: #fab219;
    }
  }
  /* Aliases, and one status colour that was deleted while still in use.
     --muted, --panel and --warn were referenced by the diffusion and impact
     panels but never defined anywhere, so those rules fell through to hardcoded
     light fallbacks and rendered light-on-light in dark mode. --status-serious
     was removed as "referenced by nothing" while .hz-struct .hz-dot still used
     it with NO fallback, so that dot resolved to an invalid value and painted
     nothing in either theme. Aliases rather than new values, so there is one
     source of truth per colour instead of a second parallel ramp. */
  :root {
    --muted:  var(--text-muted);
    --panel:  var(--surface-1);
    --warn:   var(--status-warning-text);
    --status-serious: var(--status-warning);
    /* Quiet tinted grounds for pills and callouts. These are defined per theme
       because a tint is the one thing that cannot be derived from a foreground
       token: it has to invert with the ground. */
    --tint-critical: #fbd5d5;
    --tint-neutral:  #e8e8e4;
    --tint-quiet:    #f0efec;
    --tint-warning:  #fffaf0;
    --tint-warning-edge: #d8b430;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --tint-critical: #3a1f1f;
      --tint-neutral:  #2c2c2a;
      --tint-quiet:    #232322;
      --tint-warning:  #2a2415;
      --tint-warning-edge: #6b5a1c;
    }
  }

  /* ===================================================================
     ELEVATION
     No colour here, on purpose: every existing accessibility ratio in this
     file was tuned against a flat card, and a shadow is a neutral-black
     alpha overlay that cannot shift a foreground/background contrast
     figure. It only changes how far off the page a surface reads as
     sitting, which is the one thing a 1px border cannot do on its own. A
     second surface tone (--surface-2) is what a card looks like when it is
     raised further than --surface-1, e.g. on hover or inside another card.
     =================================================================== */
  :root {
    --surface-2: #f2f1ed;
    --shadow-sm: 0 1px 2px rgba(20,20,18,.04), 0 1px 1px rgba(20,20,18,.03);
    --shadow-md: 0 4px 16px rgba(20,20,18,.07), 0 1px 3px rgba(20,20,18,.05);
    --shadow-lg: 0 12px 40px rgba(20,20,18,.10), 0 2px 8px rgba(20,20,18,.06);
    --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --surface-2: #232321;
      --shadow-sm: 0 1px 2px rgba(0,0,0,.4), 0 1px 1px rgba(0,0,0,.3);
      --shadow-md: 0 6px 20px rgba(0,0,0,.45), 0 1px 3px rgba(0,0,0,.4);
      --shadow-lg: 0 16px 48px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.4);
    }
  }

  * { box-sizing: border-box; margin: 0; }

  /* Keyboard focus must be visible on every interactive thing, including the
     table rows that open a drill-down. :focus-visible keeps it off mouse
     clicks, so this costs the pointer experience nothing. */
  :focus-visible {
    outline: 2px solid var(--bar);
    outline-offset: 2px;
    border-radius: 3px;
  }
  tr.clickable:focus-visible { outline-offset: -2px; }

  /* Lets a keyboard or screen-reader user pass the header and go straight to
     the briefing, rather than tabbing through the nav on every page. */
  .skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--bar-solid); color: #fff; padding: 10px 16px;
    border-radius: 0 0 8px 0; font-size: 14px; text-decoration: none;
  }
  .skip-link:focus { left: 0; }
  body {
    background: var(--page);
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 14.5px;
    line-height: 1.45;
    padding: 24px;
    max-width: 1180px;
    margin: 0 auto;
  }
  header { display: flex; align-items: baseline; gap: 8px 12px; margin-bottom: 4px; flex-wrap: wrap; }
  #account { margin-left: auto; font-size: 12.5px; line-height: 1.9; }
  #account a { color: var(--text-secondary); text-decoration: none; }
  #account a:hover { color: var(--text-primary); }
  .pull {
    margin-left: auto; background: none; border: 1px solid var(--grid);
    color: var(--text-secondary); border-radius: 7px; padding: 5px 12px;
    font: inherit; font-size: 12.5px; cursor: pointer;
  }
  .pull:hover { color: var(--text-primary); border-color: var(--text-muted); }
  .pull:disabled { opacity: 0.5; cursor: wait; }
  h1 { font-size: 19px; font-weight: 650; letter-spacing: -0.015em; }
  .brand { display: flex; align-items: center; gap: 9px; }
  .brand h1 { margin: 0; }
  .brand h1 b { font-weight: 700; }
  .brand h1 span { font-weight: 450; color: var(--text-secondary); }
  .logo-mark { width: 24px; height: 24px; flex: none; display: block; }
  .sub { color: var(--text-muted); font-size: 13px; }

  /* Slim wayfinding, shared by every authenticated screen. The product used to
     route between Book / Research / Evidence entirely through prose links at
     the bottom of a page, which is real restraint but leaves no way to tell,
     from any one screen, what else exists. Five words, one underline each,
     nothing that competes with the content underneath it. */
  .appnav { display: flex; align-items: center; flex-wrap: nowrap;
    overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
    border-bottom: 1px solid var(--grid); margin: 2px 0 var(--s-5); }
  .appnav::-webkit-scrollbar { display: none; }
  .appnav a { display: inline-flex; align-items: center; flex: none; margin-right: 22px;
    padding: 9px 1px 10px; font-size: 13px; font-weight: 600;
    color: var(--text-secondary); text-decoration: none;
    border-bottom: 2px solid transparent; }
  .appnav a:hover { color: var(--text-primary); }
  .appnav a.active { color: var(--text-primary); border-bottom-color: var(--bar);
    box-shadow: 0 1px 8px -1px var(--bar-glow); }
  .disclaimer { color: var(--text-muted); font-size: 12px; margin: 4px 0 20px; }

  .tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 24px; }
  .tile {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    box-shadow: var(--shadow-sm);
    transition: box-shadow .16s var(--ease), transform .16s var(--ease);
  }
  .tile .label { color: var(--text-secondary); font-size: 12px; margin-bottom: 6px; }
  .tile .value { font-size: 26px; font-weight: 650; line-height: 1.1;
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .tile .hint { color: var(--text-muted); font-size: 12px; margin-top: 4px; }

  section { margin-bottom: 28px; }
  h2 { font-size: 14px; font-weight: 650; margin-bottom: 10px; color: var(--text-primary); }
  .card { background: var(--surface-1); border: 1px solid var(--border);
    border-radius: var(--radius-md); overflow-x: auto; box-shadow: var(--shadow-sm); }
  table { width: 100%; border-collapse: collapse; }
  th {
    text-align: left; font-size: 11px; font-weight: 600; text-transform: uppercase;
    letter-spacing: 0.04em; color: var(--text-muted);
    padding: 10px 12px; border-bottom: 1px solid var(--grid);
    white-space: nowrap;
  }
  td { padding: 9px 12px; border-bottom: 1px solid var(--grid); vertical-align: middle; }
  tr:last-child td { border-bottom: none; }
  tr:hover td { background: color-mix(in srgb, var(--text-primary) 3%, transparent); }
  .num { font-variant-numeric: tabular-nums; font-family: var(--font-mono); text-align: right; }
  .ticker { font-weight: 650; font-family: var(--font-mono); }
  .sec { color: var(--text-secondary); }
  .mut { color: var(--text-muted); font-size: 12.5px; }

  .scorecell { display: flex; align-items: center; gap: 8px; min-width: 130px; }
  .track { flex: 1; height: 6px; border-radius: 4px; background: var(--bar-track); overflow: hidden; }
  .fill { height: 100%; border-radius: 4px; background: var(--bar); }
  .scoreval { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 600; width: 34px; text-align: right; }

  /* Diverging sentiment bar: fills left (bearish, red) or right (bullish,
     green) of a marked zero midpoint. Color never carries meaning alone -
     every value is signed and every chip carries the direction word. */
  .sentcell { display: flex; align-items: center; gap: 8px; min-width: 160px; }
  .strack { flex: 1; height: 8px; border-radius: 4px; background: var(--bar-track); position: relative; }
  .strack .zeroline { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 2px;
    margin-left: -1px; background: var(--text-muted); opacity: .55; border-radius: 1px; }
  .sfill { position: absolute; top: 0; bottom: 0; }
  .sfill.bull { left: 50%; background: var(--bull); border-radius: 0 4px 4px 0; }
  .sfill.bear { right: 50%; background: var(--bear); border-radius: 4px 0 0 4px; }
  .sval { width: 44px; text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 650; }
  .sval.bull { color: var(--bull); }
  .sval.bear { color: var(--bear); }
  .sval.neut { color: var(--text-muted); }

  /* Net-exposure compass: one diverging bar per macro theme (portfolio weight
     that gains right/green vs loses left/red if that theme escalates). */
  .compass-headline { font-size: 15px; font-weight: 650; line-height: 1.4;
    margin: 2px 2px 14px; }
  .compass-headline .em-bull { color: var(--bull); }
  .compass-headline .em-bear { color: var(--bear); }
  .theme-row { display: grid; grid-template-columns: 200px 1fr 96px; align-items: center;
    gap: 12px; padding: 6px 2px; }
  .theme-label { font-size: 13px; color: var(--text-secondary); }
  .theme-bar { position: relative; height: 16px; background: var(--bar-track); border-radius: 4px; }
  .theme-bar .mid { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 2px;
    margin-left: -1px; background: var(--text-muted); opacity: .55; border-radius: 1px; }
  .theme-bar .b-ben { position: absolute; left: 50%; top: 0; bottom: 0; background: var(--bull);
    border-radius: 0 3px 3px 0; }
  .theme-bar .b-hurt { position: absolute; right: 50%; top: 0; bottom: 0; background: var(--bear);
    border-radius: 3px 0 0 3px; }
  .theme-net { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 650; font-size: 13px; }
  .theme-net small { display: block; font-weight: 500; font-size: 10.5px; color: var(--text-muted); }
  .compass-axis { display: grid; grid-template-columns: 200px 1fr 96px; gap: 12px;
    color: var(--text-muted); font-size: 10.5px; margin-top: 4px; }
  .compass-axis .ends { display: flex; justify-content: space-between; }
  .concen-flag { font-size: 12.5px; line-height: 1.5; margin: 2px 2px 14px; padding: 9px 12px;
    border-radius: 8px; border: 1px solid color-mix(in srgb, var(--status-warning) 45%, var(--border));
    background: color-mix(in srgb, var(--status-warning) 12%, var(--surface-1)); }
  .peer-chip { font-size: 10.5px; color: var(--text-muted); font-weight: 500;
    border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }
  /* Explainable confidence: the score, then the checks behind it. Collapsed by
     default so it informs without competing with the evidence itself. */
  .confbox { margin: 2px 0 12px; border: 1px solid var(--border); border-radius: 9px;
    padding: 10px 13px; background: var(--page); }
  .confbox summary { cursor: pointer; font-size: 13px; }
  .confscore { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .conflist { margin-top: 10px; }
  .cfrow { display: grid; grid-template-columns: 16px 148px 1fr 34px; gap: 8px;
    align-items: baseline; padding: 4px 0; font-size: 12.5px;
    border-top: 1px solid var(--grid); }
  .cfrow:first-child { border-top: none; }
  .cfmark { font-weight: 700; }
  .cf-yes .cfmark { color: var(--bull); }
  .cf-no .cfmark { color: var(--bear); }
  .cf-mixed .cfmark { color: var(--status-warning-text); }
  .cf-none { color: var(--text-muted); }
  .cflabel { color: var(--text-primary); }
  .cf-none .cflabel { color: var(--text-muted); }
  .cfdetail { color: var(--text-secondary); }
  .cfdelta { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono);
    color: var(--text-muted); }
  @media (max-width: 640px) {
    .cfrow { grid-template-columns: 16px 1fr 34px; }
    .cfdetail { grid-column: 2 / -1; }
  }

  /* The two named calls, side by side under the briefing grid. */
  .callcard { border: 1px solid var(--border); border-radius: var(--radius-md);
    padding: 15px 17px; background: var(--surface-1); box-shadow: var(--shadow-sm); }
  .callcard h3 { font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-muted); font-weight: 600; margin-bottom: 9px; }
  .callcard.risk { border-left: 3px solid var(--bear); }
  .callcard.opp  { border-left: 3px solid var(--bull); }
  /* Nothing material: no accent bar, because there is no call to make. */
  .callcard.quiet { border-left: 3px solid var(--grid); }
  /* How many articles carry the driving story. A lone report and a forty-wire
     story used to render identically, hiding the fourfold damping the engine
     had already applied to the first. */
  .callsrc { font-size: 11.5px; color: var(--text-muted); margin-left: auto;
    white-space: nowrap; }
  /* The ring carries the caution; the text stays on a readable token. Amber is
     a fill colour - as text on this background it lands around 2:1. */
  .callsrc.thin { color: var(--text-secondary); font-weight: 600;
    border: 1px solid var(--status-warning); border-radius: 999px;
    padding: 1px 8px; }
  .callhead { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
  .calltk { font-size: 19px; font-weight: 700; font-family: var(--font-mono); }
  .callv { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .callwhy { font-size: 13.5px; line-height: 1.5; color: var(--text-secondary);
    margin-bottom: 8px; }
  #brief-calls { display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
    margin-top: var(--s-4); }
  @media (max-width: 720px) { #brief-calls { grid-template-columns: 1fr; } }

  /* Watch list: conditions that would change today's reading. */
  #brief-watch { margin-top: var(--s-4); }
  #brief-watch h3 { font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-muted); font-weight: 600; margin-bottom: 8px; }
  .watchitem { font-size: 13.5px; line-height: 1.55; color: var(--text-secondary);
    padding: 6px 0 6px 14px; position: relative; max-width: 84ch; }
  .watchitem::before { content: ""; position: absolute; left: 0; top: 13px;
    width: 5px; height: 5px; border-radius: 50%; background: var(--text-muted); }
  .watchitem b { color: var(--text-primary); }

  .readtime { margin-top: var(--s-4); font-size: 12px; color: var(--text-muted); }

  /* How far the data would have to move for a reading to become something
     else. Sits under the reading it qualifies, quieter than it. */
  .falsify-line { font-size: 12.5px; line-height: 1.5; color: var(--text-secondary);
    max-width: 76ch; margin-top: 10px; padding-left: 11px;
    border-left: 2px solid var(--grid); }

  /* New since the reader last looked. Sits above the current state, so it is
     quieter than the hero figure but louder than the evidence columns. */
  .brief-new { border: 1px solid var(--border); border-left: 3px solid var(--bar);
    border-radius: 10px; padding: 13px 16px; margin: 14px 0 4px;
    background: var(--surface-1); }

  /* The record, at the top of the page. Quiet and dense rather than a hero
     banner: this is a research figure being shown to someone who reads them for
     a living, so the number carries it and nothing else shouts. */
  .edge { border: 1px solid var(--border); border-radius: 12px;
    background: var(--surface-1); padding: var(--s-5) var(--s-5) var(--s-4);
    margin: 0 0 var(--s-5); }
  .edge-head { display: flex; flex-wrap: wrap; align-items: baseline;
    gap: var(--s-3) var(--s-5); }
  .edge-fig { display: flex; align-items: baseline; gap: 9px; }
  .edge-n { font-size: 42px; font-weight: 700; line-height: 1;
    letter-spacing: -.02em; color: var(--status-good);
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .edge-vs { font-size: 13.5px; color: var(--text-secondary);
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .edge-vs b { color: var(--text-primary); font-weight: 650; }
  .edge-say { flex: 1; min-width: 260px; font-size: 13.5px; line-height: 1.55;
    color: var(--text-secondary); max-width: 62ch; }
  .edge-say strong { color: var(--text-primary); font-weight: 650; }
  .edge-say .mut { display: block; font-size: 12.5px; margin-top: 2px; }

  .edge-chart { margin: var(--s-4) 0 var(--s-3); }
  .edge-chart svg { width: 100%; height: 116px; display: block; overflow: visible; }
  .ec-fill { fill: var(--status-good); opacity: .10; }
  .ec-line { fill: none; stroke: var(--status-good); stroke-width: 2;
    stroke-linejoin: round; }
  .ec-base { stroke: var(--text-muted); stroke-width: 1; stroke-dasharray: 3 3; }
  .ec-dot  { fill: var(--status-good); }
  .ec-tick { fill: var(--text-muted); font-size: 10px; text-anchor: end;
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .ec-tick.strong { fill: var(--text-primary); font-weight: 650; }
  .ec-date { fill: var(--text-muted); font-size: 10px; }
  .ec-date.end { text-anchor: end; }
  .edge-cap { font-size: 12px; color: var(--text-muted); margin: 4px 0 0; }

  .edge-grid { display: grid; gap: var(--s-3);
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    border-top: 1px solid var(--grid); padding-top: var(--s-4);
    margin-top: var(--s-4); }
  .edge-cell { display: flex; flex-direction: column; gap: 3px; }
  /* The failing check is marked, not hidden. */
  .edge-cell.warnish { border-left: 3px solid var(--status-warning);
    padding-left: 10px; }
  .edge-lbl { font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase;
    color: var(--text-muted); }
  .edge-val { font-size: 18px; font-weight: 650; color: var(--text-primary);
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .edge-val.small { font-size: 13px; font-weight: 400;
    color: var(--text-secondary); line-height: 1.5; }
  .edge-val .mut { font-size: 12px; font-weight: 400; color: var(--text-muted); }
  .edge-foot { font-size: 12.5px; line-height: 1.55; color: var(--text-secondary);
    margin: var(--s-4) 0 0; max-width: 76ch; }

  /* The event, opened.

     The source link is the point of this panel, so it is never smaller or
     quieter than the prose around it, and a source that does not exist says so
     in warning colour rather than rendering as a dead link. */
  .ed-head { font-size: 14px; font-weight: 650; color: var(--text-primary);
    line-height: 1.4; }
  .ed-block { margin-top: 10px; padding-top: 9px;
    border-top: 1px solid var(--grid); }
  .ed-block.warn { border-left: 3px solid var(--status-warning);
    background: var(--tint-warning); border-radius: 6px;
    padding: 8px 10px; border-top: none; }
  .ed-block > summary { cursor: pointer; font-size: 12px; font-weight: 650;
    color: var(--text-primary); margin-bottom: 6px; }
  .ed-fact { display: grid; grid-template-columns: 9rem 1fr; gap: 4px 10px;
    padding: 4px 0; font-size: 12.5px; }
  .ed-field { color: var(--text-muted); text-transform: uppercase;
    font-size: 10.5px; letter-spacing: .05em; padding-top: 2px; }
  .ed-val { color: var(--text-primary); font-weight: 600; }
  .ed-quote { grid-column: 1 / -1; font-size: 12px; line-height: 1.5;
    color: var(--text-secondary); border-left: 2px solid var(--grid);
    padding-left: 9px; margin-top: 3px; }
  .ed-same { grid-column: 1 / -1; font-size: 11px; color: var(--text-muted);
    padding-left: 9px; margin-top: 1px; }
  .ed-section > summary { cursor: pointer; font-size: 11.5px;
    color: var(--text-muted); margin-top: 5px; }
  .ed-src { display: flex; gap: 9px; align-items: baseline; padding: 5px 0;
    border-top: 1px solid var(--grid); font-size: 12.5px; }
  .ed-src:first-of-type { border-top: none; }
  .ed-kind { flex: none; font-size: 9.5px; letter-spacing: .06em;
    font-weight: 700; border-radius: 999px; padding: 2px 7px;
    border: 1px solid var(--border); background: var(--tint-neutral);
    color: var(--text-secondary); }
  .ed-kind.primary { color: var(--status-good); background: var(--tint-quiet); }
  .ed-kind.context, .ed-kind.secondary { color: var(--text-muted); }
  .ed-srcbody { min-width: 0; }
  .ed-srctitle { color: var(--text-primary); }
  .ed-open { display: block; margin-top: 2px; }
  .ev-none { color: var(--status-warning-text); }

  /* One headline against the whole book.

     The holdings it does NOT reach are styled as a real answer rather than as
     absence, because a panel that lists only the hits reads as one that found
     something everywhere it looked. */
  .eventbook { margin-top: 8px; border-top: 1px solid var(--grid);
    padding-top: 8px; font-size: 12.5px; }
  .eb-head { font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-muted); margin-bottom: 5px; }
  .eb-split { border-left: 3px solid var(--status-warning);
    background: var(--tint-warning); border-radius: 6px;
    padding: 6px 9px; margin-bottom: 7px; color: var(--text-secondary); }
  .eb-split strong { color: var(--text-primary); }
  /* Through what the event arrived, above the per-holding routes it
     summarises. Deliberately quieter than .eb-split: a single mechanism is
     not an alarm, it is a statement that the reading rests on one assumption.
     Text colour is --text-secondary, never a fill-only status token. */
  .eb-conduit { border-left: 3px solid var(--grid);
    background: var(--tint-quiet); border-radius: 6px;
    padding: 6px 9px; margin-bottom: 7px; color: var(--text-secondary); }
  .eb-conduit.several { border-left-color: var(--status-warning-text); }
  .eb-row { display: grid; grid-template-columns: 4.5rem 3.5rem 1fr auto;
    gap: 8px; align-items: baseline; padding: 3px 0;
    border-top: 1px solid var(--grid); }
  .eb-row:first-of-type { border-top: none; }
  .eb-tk { font-weight: 650; color: var(--text-primary); font-family: var(--font-mono); }
  .eb-v { font-variant-numeric: tabular-nums; font-family: var(--font-mono); text-align: right; }
  .eb-row.bullish .eb-v { color: var(--bull); }
  .eb-row.bearish .eb-v { color: var(--bear); }
  .eb-row.miss .eb-v, .eb-row.miss .eb-tk { color: var(--text-muted); }
  .eb-why { color: var(--text-secondary); }
  .eb-row.miss .eb-why { color: var(--text-muted); }

  /* One-word actions to confirm, reject or flag a missing exposure route,
     right on the row they describe. Never a scoring input: see
     analysis/review.py. Text-only links, not buttons, because there can be
     several holdings on one event and a bank of buttons per row would be
     louder than the judgement itself. */
  .eb-verdict { white-space: nowrap; font-size: .78rem; }
  .ed-vlink { color: var(--text-muted); text-decoration: none;
    margin-left: 8px; cursor: pointer; }
  .ed-vlink:first-child { margin-left: 0; }
  .ed-vlink:hover { color: var(--text-primary); text-decoration: underline; }

  /* The judgement panel: an action bar and the team's own record, kept apart
     from everything computed above it by the same rule as /investigate. */
  .ed-judge .ed-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
  .ed-judge button { font: inherit; font-size: .82rem; padding: 4px 11px;
    border-radius: var(--radius-sm); border: 1px solid var(--border);
    background: var(--surface-1); color: var(--text-primary); cursor: pointer; }
  .ed-judge button:hover { border-color: var(--text-secondary); }
  .ed-jrow { border-left: 2px solid var(--grid); padding: 7px 0 7px 11px;
    margin-bottom: 8px; }
  .ed-jstatus { font-size: .74rem; letter-spacing: .03em; font-weight: 600;
    color: var(--bar); margin-right: 8px; }
  .ed-jnote { color: var(--text-primary); margin: 4px 0; white-space: pre-wrap;
    overflow-wrap: anywhere; }
  .ed-frozen { color: var(--text-secondary); font-size: .85rem;
    border-top: 1px dashed var(--border); padding-top: 4px; }

  /* What a reading rests on.

     This replaced a confidence bar that drew 100% for a single SEC filing.
     Every colour is a token so both themes are defined; the first version of
     the claim panel used four names that existed in neither and rendered
     light on light. */
  .callev { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
    margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--grid);
    font-size: 12px; color: var(--text-secondary); }
  .ev-badge { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
    font-weight: 700; border-radius: 999px; padding: 2px 8px;
    border: 1px solid var(--border); background: var(--tint-neutral);
    color: var(--text-secondary); }
  .callev.filed .ev-badge { color: var(--status-good); background: var(--tint-quiet); }
  .callev.single-source .ev-badge { color: var(--status-warning-text);
    background: var(--tint-warning); }
  .callev.no-evidence .ev-badge { color: var(--text-muted); }
  .ev-route { color: var(--text-primary); }
  .ev-age { color: var(--text-muted); font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .ev-limit { flex-basis: 100%; color: var(--text-muted); line-height: 1.45; }
  .brief-ev { display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; color: var(--text-secondary); border: 1px solid var(--border);
    border-radius: 999px; padding: 3px 10px; background: var(--tint-neutral); }
  .brief-ev.filed { color: var(--status-good); }
  .brief-ev.single-source { color: var(--status-warning-text); }

  /* The claim register.

     This panel used to be a 42px accuracy figure with its retraction in the
     footnote underneath. Every colour here is a token that is redefined in the
     dark block above, because the first version of this panel used four names
     that were never defined and rendered light-on-light. */
  .claim-lede { font-size: 13px; line-height: 1.55; color: var(--text-secondary);
    margin: 2px 0 var(--s-4); max-width: 76ch; }
  .claim-list { display: flex; flex-direction: column; gap: var(--s-3); }
  .claim-row { display: flex; gap: 11px; align-items: flex-start;
    border: 1px solid var(--border); border-radius: 10px; padding: 11px 13px; }
  .claim-row.withdrawn { border-left: 3px solid var(--status-critical); }
  .claim-row.unproven { border-left: 3px solid var(--status-warning); }
  .claim-row.exploratory { border-left: 3px solid var(--text-muted); }
  .claim-row.supported { border-left: 3px solid var(--status-good); }
  .claim-pill { flex: none; font-size: 10.5px; letter-spacing: .06em;
    text-transform: uppercase; font-weight: 700; border-radius: 999px;
    padding: 3px 8px; border: 1px solid var(--border);
    color: var(--text-secondary); background: var(--tint-neutral); }
  .claim-pill.withdrawn { color: var(--status-critical);
    background: var(--tint-critical); }
  .claim-pill.unproven { color: var(--status-warning-text);
    background: var(--tint-warning); }
  .claim-pill.supported { color: var(--status-good);
    background: var(--tint-quiet); }
  .claim-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .claim-what { font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
  .claim-fig { font-size: 12.5px; color: var(--text-primary);
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .claim-say { font-size: 12.5px; line-height: 1.5; color: var(--text-secondary); }
  .claim-say.none { color: var(--status-warning-text); }
  @media (max-width: 560px) {
    .claim-row { flex-direction: column; gap: 7px; }
    .claim-pill { align-self: flex-start; } }

  /* The record by window. A window still filling is deliberately quieter than
     one that has a figure, so the eye goes to what is real. */
  /* Six fixed windows, so six fixed columns. auto-fit made ten tracks here
     (the spanning label pins the count) and left four empty on the right,
     which reads as a row that failed to load rather than one that is full. */
  .edge-windows { display: grid; gap: var(--s-3);
    grid-template-columns: repeat(6, minmax(0, 1fr));
    border-top: 1px solid var(--grid); padding-top: var(--s-4);
    margin-top: var(--s-4); }
  @media (max-width: 720px) {
    .edge-windows { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  @media (max-width: 380px) {
    .edge-windows { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .ew-cell { display: flex; flex-direction: column; gap: 2px;
    border: 1px solid var(--border); border-radius: 9px; padding: 9px 11px; }
  .ew-cell.waiting { border-style: dashed; }
  .ew-win { font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-muted); font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .ew-val { display: flex; align-items: baseline; gap: 3px; }
  .ew-edge { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; font-family: var(--font-mono);
    color: var(--text-primary); }
  .ew-edge.pos { color: var(--status-good); }
  .ew-edge.neg { color: var(--status-critical); }
  .ew-unit { font-size: 11px; color: var(--text-muted); }
  .ew-wait { font-size: 17px; font-weight: 650; color: var(--text-muted);
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .ew-sub { font-size: 11px; color: var(--text-muted);
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); }

  /* Stale-feed warning. The one banner on this page allowed to be loud: every
     score below it is being presented with normal confidence on old news, so
     the notice has to outrank them. Amber rather than red - the product is
     working, the data is not current, and those are different problems. */
  .stale-banner { border: 1px solid var(--status-warning);
    border-left: 4px solid var(--status-warning); border-radius: 10px;
    padding: 12px 16px; margin: 0 0 var(--s-5); font-size: 13.5px;
    line-height: 1.55; color: var(--text-secondary);
    background: color-mix(in srgb, var(--status-warning) 8%, transparent); }
  .stale-banner strong { color: var(--text-primary); }
  /* The header's own dateline goes amber with it, so the two never disagree. */
  #updated.stale { color: var(--status-critical); font-weight: 600; }

  /* The daily-brief offer. Deliberately quieter than the briefing above it:
     it is an aside at the end of the page, not a banner competing with the
     answer the reader came for. No background fill, no accent bar. */
  .brief-offer { display: flex; flex-wrap: wrap; align-items: center;
    gap: var(--s-3) var(--s-4); justify-content: space-between;
    border-top: 1px solid var(--border); margin-top: var(--s-5);
    padding-top: var(--s-4); }
  .brief-offer .bo-text { flex: 1; min-width: 260px; font-size: 13.5px;
    line-height: 1.55; color: var(--text-secondary); max-width: 62ch; }
  .brief-offer .bo-text strong { color: var(--text-primary); }
  .brief-offer .bo-acts { display: flex; gap: var(--s-3); flex-wrap: wrap; }
  .brief-offer button { background: var(--bar-solid); color: #fff; border: none;
    border-radius: 7px; padding: 8px 15px; font: inherit; font-size: 13px;
    font-weight: 600; cursor: pointer; min-height: 34px; }
  .brief-offer button:hover { filter: brightness(1.08); }
  /* One quiet signature interaction, reused everywhere a filled action button
     already exists: a soft indigo glow on hover, never on idle, so the accent
     reads as "alive when touched" rather than as a decoration sitting on the
     page. transition lives on the base rule below rather than :hover so the
     glow eases in on hover and back out on leave symmetrically. */
  .brief-offer button, .pf-form button, #import-panel button {
    transition: box-shadow .18s var(--ease), filter .18s var(--ease); }
  .brief-offer button:hover, .pf-form button:hover, #import-panel button:hover {
    box-shadow: 0 0 16px 1px var(--bar-glow); }
  .brief-offer button.ghost { background: none; color: var(--text-secondary);
    border: 1px solid var(--grid); }
  .brief-offer button:disabled { opacity: .6; cursor: default; }
  .nw-head { font-size: 14px; font-weight: 620; color: var(--text-primary);
    margin-bottom: 9px; }
  .nw-row { display: grid; grid-template-columns: 46px 1fr; gap: 11px;
    padding: 6px 0; border-top: 1px solid var(--grid); }
  .nw-row:first-of-type { border-top: none; padding-top: 2px; }
  .nw-score { font-weight: 700; font-size: 13.5px; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .nw-txt { font-size: 13px; line-height: 1.5; color: var(--text-secondary); }
  .nw-tk { font-weight: 650; color: var(--text-primary); margin-right: 7px; }
  .nw-meta { display: block; color: var(--text-muted); font-size: 11.5px; margin-top: 1px; }
  @media (max-width: 640px) { .nw-row { grid-template-columns: 40px 1fr; gap: 8px; } }

  /* Evidence for and against, separated. The against side is not styled as an
     error: a signal with nothing arguing against it is rarer and more suspect
     than one with a dissent, so both headings carry the same weight. */
  .ev-head { font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
    font-weight: 650; margin: 16px 0 6px; padding-bottom: 5px;
    border-bottom: 1px solid var(--grid); }
  .ev-head:first-of-type { margin-top: 8px; }
  .ev-for { color: var(--text-secondary); }
  .ev-against { color: var(--text-secondary); }
  .ev-head .mut { font-weight: 400; letter-spacing: 0; text-transform: none; }
  .ev-none { font-size: 12.5px; color: var(--text-muted); padding: 4px 0 2px; }
  .ev-sources { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--grid);
    font-size: 11.5px; color: var(--text-muted); line-height: 1.5; }

  /* Crowding: how much of the book each tracked manager also holds. */
  .crowd-head { font-size: 15px; line-height: 1.5; max-width: 72ch; margin-bottom: 4px; }
  .crowd-row { display: grid; grid-template-columns: 1fr 200px; align-items: center;
    gap: 14px; padding: 8px 2px; border-top: 1px solid var(--grid); }
  .crowd-row:first-of-type { border-top: none; }
  .crowd-fund { font-size: 13.5px; font-weight: 600; }
  .crowd-share { display: flex; align-items: center; gap: 9px; }
  .crowd-track { flex: 1; height: 8px; border-radius: 4px; background: var(--bar-track); }
  .crowd-fill { height: 100%; border-radius: 4px; background: var(--bar); }
  .crowd-pct { width: 42px; text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono);
    font-weight: 650; font-size: 13px; }
  .crowd-limits { margin-top: 14px; font-size: 12px; color: var(--text-secondary); }
  .crowd-limits summary { cursor: pointer; color: var(--text-muted); }
  .crowd-limits ul { margin: 8px 0 0 18px; padding: 0; }
  .crowd-limits li { margin-bottom: 4px; }
  @media (max-width: 640px) { .crowd-row { grid-template-columns: 1fr; } }

  /* What our own ledger says about this holding meeting this theme before.
     Deliberately quiet: it qualifies the score, it does not compete with it. */
  .track { display: block; font-size: 11.5px; line-height: 1.45; margin-top: 4px;
    color: var(--text-secondary); }
  .track .tick { display: inline-block; width: 14px; font-weight: 700; }
  .track.tr-no .tick   { color: var(--text-primary); }
  .track.tr-yes .tick  { color: var(--bull); }
  .track.tr-mixed .tick{ color: var(--status-warning-text); }
  .track.tr-none       { color: var(--text-muted); }
  .track-caveat { font-size: 12.5px; line-height: 1.5; margin: 2px 0 12px;
    padding: 10px 12px; border-radius: 8px;
    border: 1px solid var(--border); background: var(--page); }
  .hidden-flag { font-size: 12.5px; line-height: 1.45; margin: 2px 0 10px; padding: 9px 12px;
    border-radius: 8px; border: 1px solid color-mix(in srgb, var(--bar) 35%, var(--border));
    background: color-mix(in srgb, var(--bar) 8%, var(--surface-1)); }

  /* Macro layer: channel state, propagation chain, per-holding impact */
  .macro-channels { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px; margin-bottom: 14px; }
  .mch { border: 1px solid var(--border); border-radius: 10px; padding: 11px 13px; }
  .mch .cl { font-size: 12px; color: var(--text-muted); }
  .mch .cv { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; font-family: var(--font-mono); margin: 1px 0; }
  .mch .cr { font-size: 12.5px; color: var(--text-secondary); }
  .chain { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0 2px; }
  .chain .step { font-size: 12.5px; border: 1px solid var(--border); border-radius: 7px;
    padding: 3px 9px; background: var(--page); }
  .chain .arrow { color: var(--text-muted); font-size: 12px; }
  .macro-drv { font-size: 12.5px; color: var(--text-secondary); margin-bottom: 10px; }
  .macro-drv b { color: var(--text-primary); font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .curve-line { font-size: 12.5px; color: var(--text-secondary); margin-top: 10px;
    padding-top: 10px; border-top: 1px solid var(--grid); }

  /* Rates: the 10y decomposition. One focal sentence, then the arithmetic. */
  .fi-head { font-size: 17px; line-height: 1.45; font-weight: 550;
    max-width: 62ch; margin-bottom: 16px; }
  .fi-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
  .fi-tile { border: 1px solid var(--border); border-radius: 10px; padding: 11px 13px; }
  .fi-tile .cl { font-size: 12px; color: var(--text-muted); }
  .fi-lvl { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; font-family: var(--font-mono); margin: 2px 0 1px; }
  .fi-chg { font-size: 12.5px; color: var(--text-secondary); font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .fi-buckets { display: flex; flex-wrap: wrap; gap: 8px; }
  .fi-bucket { display: flex; flex-direction: column; gap: 1px; font-size: 12.5px;
    border: 1px solid var(--border); border-radius: 8px; padding: 6px 11px; }
  .fi-b-name { color: var(--text-primary); }
  .fi-line { font-size: 13px; line-height: 1.5; color: var(--text-secondary);
    max-width: 74ch; margin-top: 6px; }

  /* Sector sentiment board */
  .sector-row { display: grid; grid-template-columns: 184px 1fr; align-items: center;
    gap: 12px; padding: 7px 2px; border-top: 1px solid var(--grid); }
  .sector-row:first-child { border-top: none; }
  .sector-label { font-size: 13px; font-weight: 600; }
  .sector-label .beneficiary { font-size: 10px; font-weight: 600; color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 999px; padding: 0 6px; margin-left: 6px; white-space: nowrap; }
  .sector-drv { color: var(--text-muted); font-size: 11px; margin-top: 1px; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

  /* Compass stays readable on narrow screens: labels shrink, bar keeps priority */
  @media (max-width: 560px) {
    .sector-row { grid-template-columns: 128px 1fr; gap: 8px; }
    .sector-label { font-size: 12px; }
    .sector-label .beneficiary { display: none; }
    .sector-drv { display: none; }
    .theme-row { grid-template-columns: 116px 1fr 62px; gap: 8px; }
    .theme-label { font-size: 12px; }
    .compass-axis { grid-template-columns: 116px 1fr 62px; gap: 8px; }
    .theme-net { font-size: 12px; }
    .peer-chip { display: none; }
  }

  /* What-if scenario simulator */
  .scenario-btns { display: flex; flex-wrap: wrap; gap: 6px; }
  .scenario-btns button { background: var(--page); border: 1px solid var(--grid);
    color: var(--text-secondary); border-radius: 8px; padding: 8px 13px; font: inherit;
    font-size: 12.5px; cursor: pointer; min-height: 36px; }
  .scenario-btns button:hover { border-color: var(--text-muted); color: var(--text-primary); }
  .scenario-btns button.active { background: var(--bar-solid); color: #fff; border-color: var(--bar-solid); }
  .sc-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 4px 0 2px; }
  .sc-head .big { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .sc-movers { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
  .sc-mover { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px;
    border: 1px solid var(--border); border-radius: 999px; padding: 4px 11px; }
  .sc-mover .tk { font-weight: 650; }
  .sc-mover .sv { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 650; }
  .more-x { color: var(--text-muted); font-size: 12px; cursor: default; }

  .chip {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11px; font-weight: 650; letter-spacing: 0.03em;
    padding: 2px 8px; border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--text-primary);
    white-space: nowrap;
  }
  .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
  .empty { padding: 28px 16px; text-align: center; color: var(--text-muted); }
  a { color: inherit; }

  .sechead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
  .pf-summary { font-size: 13px; color: var(--text-secondary); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
  .pf-summary .big { font-size: 20px; font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .pf-form { display: flex; gap: 8px; padding: 10px 12px; flex-wrap: wrap; }
  .pf-form input {
    background: var(--page); color: var(--text-primary);
    border: 1px solid var(--grid); border-radius: 7px;
    padding: 7px 10px; font: inherit; font-size: 13px;
  }
  #pf-ticker { width: 190px; text-transform: uppercase; }
  #pf-weight { width: 130px; }
  #pf-label  { flex: 1; min-width: 140px; }
  .pf-form button {
    background: var(--bar-solid); color: #fff; border: none; border-radius: 7px;
    padding: 7px 14px; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  }
  .pf-form button:hover { filter: brightness(1.08); }
  .pf-form button.ghost, #import-panel button.ghost {
    background: none; color: var(--text-secondary); border: 1px solid var(--grid);
  }
  #import-panel button {
    background: var(--bar-solid); color: #fff; border: none; border-radius: 7px;
    padding: 7px 14px; font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  }
  #import-panel button:hover { filter: brightness(1.08); }
  #import-panel code { font-size: 12px; background: var(--page); padding: 1px 5px; border-radius: 4px; }
  .imp-sum { font-size: 13px; margin-bottom: 8px; }
  .imp-warn { color: var(--warn); font-size: 12.5px; margin: 3px 0; }
  .imp-table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-bottom: 10px; }
  .imp-table td { padding: 3px 8px 3px 0; border-bottom: 1px solid var(--grid); }
  .imp-table td.w { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono); color: var(--text-secondary); }
  .rm {
    background: none; border: none; color: var(--text-muted);
    cursor: pointer; font-size: 15px; padding: 2px 6px; border-radius: 5px;
  }
  .rm:hover { color: var(--status-critical); background: color-mix(in srgb, var(--status-critical) 10%, transparent); }
  .uncov { color: var(--text-muted); font-size: 12.5px; font-style: italic; }

  tr.clickable { cursor: pointer; }
  tr.detail td {
    background: color-mix(in srgb, var(--bar) 4%, var(--surface-1));
    padding: 0;
  }
  tr.detail:hover td { background: color-mix(in srgb, var(--bar) 4%, var(--surface-1)); }
  .drivers { padding: 12px 16px 14px; }
  .drv-head { font-size: 12px; font-weight: 650; color: var(--text-secondary);
              text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 8px; }
  .drv { display: grid; grid-template-columns: 40px 1fr; gap: 4px 10px;
         padding: 7px 0; border-top: 1px solid var(--grid); }
  .drv:first-of-type { border-top: none; }
  .drv .meta { grid-column: 2; color: var(--text-muted); font-size: 12px; }
  .drv .hl { grid-column: 2; font-size: 13.5px; }
  /* Why the story counts as this holding's news. Sits under the headline
     because the question it answers is the one the headline provokes. */
  .drv-why { grid-column: 2; font-size: 11.5px; color: var(--text-muted);
    border-left: 2px solid var(--grid); padding-left: 8px; margin-top: 2px; }
  /* The match reason is the supporting claim, not the answer, so it sits
     quieter than the line explaining why the story moves the holding.
     Quieter by SIZE only: opacity:.85 measured 4.2:1 on the dark page and
     3.6:1 on the light one, and the contrast guards read computed colour, so
     a translucent token fails the rule without tripping the test. */
  .drv-why.sub { font-size: 11px; margin-top: 1px; }
  .drv .hl a.artlink { color: inherit; text-decoration: none; }
  .drv .hl a.artlink .ht { color: var(--bar); }
  .drv .hl a.artlink:hover .ht { text-decoration: underline; }
  .drv .hl a.artlink .src { display: inline-flex; align-items: center; gap: 3px; font-size: 11px;
    font-weight: 650; color: var(--bar); white-space: nowrap; margin-left: 8px; vertical-align: middle;
    border: 1px solid color-mix(in srgb, var(--bar) 32%, var(--border)); border-radius: 999px; padding: 1px 8px; }
  .drv .hl a.artlink:hover .src { background: color-mix(in srgb, var(--bar) 12%, transparent);
    border-color: var(--bar); }
  .drv .hl .nolink { color: var(--text-primary); }
  .drv .scoreval { width: auto; text-align: left; padding-top: 1px; }
  .evlink { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--text-muted); }
  .evlink:hover { color: var(--bar); border-bottom-color: var(--bar); }
  .hint-click { color: var(--text-muted); font-size: 12px; margin: 6px 2px 0; }

  /* Standalone navigation links: the way out of a page, not prose.
     WCAG 2.5.8 asks for a 24x24 CSS px pointer target and exempts links sitting
     inline in a sentence - which is why the disclaimer links are left alone.
     These are not in a sentence, and .back/.co-back carried no rule at all, so
     the primary "get me back" affordance on methodology, plans, brand and the
     company page was a 17-22px high strip. */
  .back, .co-back, .navlink {
    display: inline-flex; align-items: center; min-height: 24px;
    padding-block: 2px; }

  .ac-wrap { position: relative; display: inline-flex; flex: 1; min-width: 220px; }
  .ac-wrap input { width: 100%; }
  .ac-list {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
    background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0,0,0,.3); overflow: hidden; max-height: 280px; overflow-y: auto;
  }
  .ac-item { padding: 8px 12px; cursor: pointer; font-size: 13px; display: flex; gap: 8px; align-items: baseline; }
  .ac-item:hover { background: color-mix(in srgb, var(--bar) 10%, transparent); }
  .ac-item .sym { font-weight: 650; min-width: 72px; }
  .ac-item .nm { color: var(--text-secondary); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ac-item .ty { color: var(--text-muted); font-size: 11px; }

  .hist-ranges { display: flex; gap: 5px; margin-bottom: 10px; flex-wrap: wrap; }
  .hist-ranges button {
    background: none; border: 1px solid var(--grid); color: var(--text-secondary);
    border-radius: 6px; padding: 7px 12px; font: inherit; font-size: 12.5px; cursor: pointer;
    min-height: 34px;
  }
  .hist-ranges button:hover { color: var(--text-primary); }
  .hist-ranges button.active { background: var(--bar-solid); color: #fff; border-color: var(--bar-solid); }
  .donut-wrap { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; justify-content: center; }
  .donut-legend { display: grid; grid-template-columns: 12px auto auto auto; gap: 4px 10px; font-size: 12.5px; align-items: center; }
  .donut-legend .lh { color: var(--text-muted); font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; }
  .donut-legend .lh:first-child { grid-column: span 2; }
  .donut-legend .sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
  .donut-legend .lt { color: var(--text-primary); font-weight: 600; }
  .donut-legend .lv { color: var(--text-secondary); font-variant-numeric: tabular-nums; font-family: var(--font-mono); text-align: right; }
  .donut-legend .lr { font-variant-numeric: tabular-nums; font-family: var(--font-mono); text-align: right; font-weight: 650; }
  .donut-seg { transition: stroke-width .12s ease; cursor: pointer; }
  .donut-seg:hover { stroke-width: 30; }
  .chart-tip { position: absolute; z-index: 40; pointer-events: none; background: var(--surface-1);
    border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 12.5px;
    white-space: nowrap; box-shadow: 0 3px 12px rgba(0,0,0,.28); line-height: 1.4; }
  .chart-tip b { font-size: 14px; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .chart-tip .tipsub { color: var(--text-secondary); font-size: 12px; }

  .bell-wrap { position: relative; }
  .bell { background: none; border: 1px solid var(--grid); border-radius: 7px; padding: 4px 9px;
    cursor: pointer; font-size: 15px; line-height: 1; position: relative; }
  .bell:hover { border-color: var(--text-muted); }
  .badge { position: absolute; top: -7px; right: -7px; min-width: 16px; height: 16px; padding: 0 4px;
    background: var(--status-critical); color: #fff; border-radius: 999px; font-size: 10px;
    font-weight: 700; line-height: 16px; text-align: center; }
  .alerts-panel { position: absolute; top: calc(100% + 6px); right: 0; z-index: 50; width: 340px;
    max-width: 88vw; max-height: 400px; overflow-y: auto; background: var(--surface-1);
    border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 26px rgba(0,0,0,.32); }
  .alerts-panel .ah { padding: 10px 14px; border-bottom: 1px solid var(--grid); font-weight: 650; font-size: 13px;
    display: flex; justify-content: space-between; align-items: center; }
  .alerts-panel .ai { padding: 9px 14px; border-bottom: 1px solid var(--grid); font-size: 12.5px; }
  .alerts-panel .ai:last-child { border-bottom: none; }
  .alerts-panel .ai.unseen { background: color-mix(in srgb, var(--bar) 7%, transparent); }
  .alerts-panel .ai .row1 { display: flex; justify-content: space-between; gap: 8px; }
  .alerts-panel .ai .tk { font-weight: 650; }
  .alerts-panel .ai .sc { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 650; }
  .alerts-panel .ai .hl { color: var(--text-secondary); font-size: 12px; margin-top: 2px; }
  .alerts-panel .ai .tm { color: var(--text-muted); font-size: 11px; }
  .alerts-panel .empty2 { padding: 20px 14px; text-align: center; color: var(--text-muted); font-size: 12.5px; }
  .analogs { margin-top: 12px; border-top: 1px solid var(--grid); padding-top: 10px; }
  .analog { display: grid; grid-template-columns: 74px 1fr auto; gap: 2px 10px; padding: 5px 0; font-size: 12.5px; }
  .analog .amt { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 650; text-align: right; }
  /* market returns: a gain is green, a loss is red (finance convention) */
  .pos { color: var(--status-good); }
  .neg { color: var(--status-critical); }

  /* ===================================================================
     DESIGN SYSTEM
     Type scale, rhythm and surface rules. The brief: reduce cognitive
     load. So hierarchy comes from SIZE and SPACE, not from boxes. Cards
     are reserved for things you interact with; read-only intelligence
     sits on the page separated by whitespace and hairlines.
     =================================================================== */
  :root {
    --t-micro: 11px; --t-meta: 12.5px; --t-body: 14.5px; --t-lead: 16px;
    --t-h2: 15px; --t-h1: 19px; --t-hero: 56px; --t-figure: 30px;
    --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 18px; --s-5: 28px;
    --s-6: 44px; --s-7: 68px;
    --ease: cubic-bezier(.22,.61,.36,1);
  }
  @media (max-width: 640px) { :root { --t-hero: 40px; --t-figure: 24px; } }

  /* ---- Briefing: the five-second answer ---- */
  .brief { margin: 0 0 var(--s-6); }
  .brief-eyebrow { display: flex; align-items: baseline; gap: var(--s-3);
    color: var(--text-muted); font-size: var(--t-meta); margin-bottom: var(--s-2); }
  .brief-eyebrow .sep { opacity: .45; }
  .brief-head { display: flex; align-items: flex-start; gap: var(--s-5); flex-wrap: wrap; }
  .brief-hero { display: flex; align-items: baseline; gap: var(--s-3); }
  .brief-hero .figure { font-size: var(--t-hero); font-weight: 700; line-height: .95;
    letter-spacing: -.035em; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
  .brief-hero .delta { font-size: var(--t-lead); font-weight: 650;
    font-variant-numeric: tabular-nums; font-family: var(--font-mono); white-space: nowrap; }
  .brief-hero .unit { color: var(--text-muted); font-size: var(--t-meta); }
  .brief-verdict { font-size: var(--t-lead); line-height: 1.45; max-width: 62ch;
    margin-top: var(--s-3); }
  .brief-verdict strong { font-weight: 650; }
  .brief-conf { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-meta);
    color: var(--text-secondary); border: 1px solid var(--border); border-radius: 999px;
    padding: 2px 10px; white-space: nowrap; }
  .conf-track { width: 34px; height: 4px; border-radius: 3px; background: var(--bar-track);
    overflow: hidden; }
  /* display:block is load-bearing. This is a <span>, and width/height do not
     apply to an inline box - so the fill has been 0px wide since it shipped and
     every "confidence bar" on the page was an empty track. */
  .conf-fill { display: block; height: 100%; background: var(--text-secondary);
    border-radius: 3px; }

  /* Confidence bands. Colour is never the only channel - the percentage and a
     word ("thinly sourced") carry the same meaning - so this reads correctly
     without colour vision, and the amber is only ever a fill or a ring, never
     text on a background it cannot clear. */
  .conf-thin .conf-fill   { background: var(--status-warning); }
  .conf-thin .conf-track  { background: var(--bar-track); }
  .brief-conf.conf-thin   { border-color: var(--status-warning); }
  .conf-mod .conf-fill    { background: var(--text-secondary); }
  .conf-strong .conf-fill { background: var(--status-good); }

  /* Coverage summary above the holdings table. Quiet is the expected state, so
     this is stated calmly - except the no-coverage count, which is the one kind
     of zero a reader must not mistake for calm. */
  .pf-coverage { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline;
    margin: 0 0 var(--s-3); padding: 9px 13px; border-radius: 8px;
    border: 1px solid var(--border); font-size: 13px; line-height: 1.55;
    color: var(--text-secondary); }
  .pf-coverage strong { color: var(--text-primary); }
  .pf-coverage .cov-gap { color: var(--text-secondary);
    border-left: 3px solid var(--status-warning); padding-left: 9px; }
  .pf-coverage .mut { font-size: 12.5px; }

  /* Confirmation that names the company just added, with an undo. */
  .pf-confirm { margin-top: var(--s-3); padding: 9px 13px; border-radius: 8px;
    font-size: 13px; line-height: 1.5; color: var(--text-secondary);
    border: 1px solid var(--border); border-left: 3px solid var(--status-good); }
  .pf-confirm.unknown { border-left-color: var(--status-warning); }
  .pf-confirm strong { color: var(--text-primary); }

  /* The company a symbol resolved to, shown before a book is committed. */
  .imp-name { color: var(--text-primary); }
  .imp-name.unknown { color: var(--text-secondary); font-style: italic;
    border-bottom: 1px dotted var(--status-warning); cursor: help; }

  /* Horizon: how durable the reading is. Sits between the headline and the
     confidence, because "bearish, but priced by Thursday" and "bearish, and
     structural" are different instructions and the score cannot tell them
     apart. The dot is a shape cue, never the only channel - the words carry
     the meaning on their own. */
  .callhz { display: flex; align-items: center; gap: 7px; margin-top: 8px;
    font-size: 11.5px; color: var(--text-secondary); }
  .callhz .hz-dot { width: 7px; height: 7px; border-radius: 50%; flex: none;
    background: var(--text-muted); }
  .hz-now .hz-dot    { background: var(--text-muted); }
  .hz-near .hz-dot   { background: var(--bar); }
  .hz-struct .hz-dot { background: var(--status-serious); }
  .hz-struct { font-weight: 600; color: var(--text-primary); }

  /* Confidence sits inside the named call, under the headline it qualifies. */
  .callconf { display: flex; align-items: center; gap: 7px; margin-top: 9px; }
  .callconf-txt { font-size: 11.5px; color: var(--text-muted); }
  .callconf .conf-track { width: 46px; }

  /* Three-column intelligence strip: what moved / why / exposure */
  .brief-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-5);
    margin-top: var(--s-6); padding-top: var(--s-4); border-top: 1px solid var(--grid); }
  @media (max-width: 860px) { .brief-grid { grid-template-columns: 1fr; gap: var(--s-4); } }
  .bcol h3 { font-size: var(--t-micro); font-weight: 650; letter-spacing: .07em;
    text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--s-3); }
  .bitem { display: flex; align-items: baseline; gap: var(--s-2); padding: 5px 0;
    font-size: var(--t-body); }
  .bitem .tk { font-weight: 650; min-width: 46px; }
  .bitem .v { margin-left: auto; font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-weight: 650;
    white-space: nowrap; }
  .bitem .why { color: var(--text-secondary); font-size: var(--t-meta); }
  .bline { font-size: var(--t-body); color: var(--text-secondary); line-height: 1.5;
    padding: 5px 0; }
  .bline b { color: var(--text-primary); font-weight: 600; }
  .brief-empty { color: var(--text-muted); font-size: var(--t-body); padding: 6px 0; }

  /* ---- Section rhythm: fewer boxes, more air ---- */
  section { margin-bottom: var(--s-7); }
  .sec-title { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap;
    margin-bottom: var(--s-4); }
  .sec-title h2 { font-size: var(--t-h2); font-weight: 650; letter-spacing: -.005em; margin: 0; }
  .sec-title .note { color: var(--text-muted); font-size: var(--t-meta); }
  .sec-title .act { margin-left: auto; display: flex; gap: var(--s-2); align-items: center; }

  /* ---- Loading skeletons ---- */
  .sk { background: var(--bar-track); border-radius: 6px; position: relative; overflow: hidden; }
  .sk::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
    background: linear-gradient(90deg, transparent,
      color-mix(in srgb, var(--text-primary) 6%, transparent), transparent);
    animation: shimmer 1.4s infinite; }
  @keyframes shimmer { 100% { transform: translateX(100%); } }
  .sk-line { height: 12px; margin-bottom: 9px; }
  @media (prefers-reduced-motion: reduce) { .sk::after { animation: none; } }

  /* ---- Command palette: keyboard-first navigation ---- */
  .cmdk-back { position: fixed; inset: 0; z-index: 100; background: rgba(6,8,12,.5);
    backdrop-filter: blur(2px); display: flex; align-items: flex-start;
    justify-content: center; padding-top: 12vh; }
  .cmdk { width: 560px; max-width: 92vw; background: var(--surface-1);
    border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
    box-shadow: 0 20px 60px rgba(0,0,0,.4); animation: cmdin .13s var(--ease); }
  @keyframes cmdin { from { opacity: 0; transform: translateY(-6px) scale(.99); } }
  .cmdk input { width: 100%; border: none; border-bottom: 1px solid var(--grid);
    background: transparent; color: var(--text-primary); font: inherit;
    font-size: var(--t-lead); padding: 15px 18px; outline: none; }
  .cmdk-list { max-height: 320px; overflow-y: auto; padding: 6px; }
  .cmdk-item { display: flex; align-items: center; gap: var(--s-3); padding: 9px 12px;
    border-radius: 8px; cursor: pointer; font-size: var(--t-body); }
  .cmdk-item[aria-selected="true"] { background: color-mix(in srgb, var(--bar) 14%, transparent); }
  .cmdk-item .k { margin-left: auto; color: var(--text-muted); font-size: var(--t-micro); }
  .cmdk-empty { padding: 22px; text-align: center; color: var(--text-muted); font-size: var(--t-body); }
  .kbd { border: 1px solid var(--grid); border-bottom-width: 2px; border-radius: 5px;
    padding: 1px 5px; font-size: var(--t-micro); color: var(--text-secondary);
    font-family: inherit; white-space: nowrap; }

  /* Keyboard shortcuts reference card. Shares .cmdk's chrome (same overlay,
     same escape-to-close) but is a static list, not a search box. */
  .cmdk.shortcuts { padding: 4px 0 8px; }
  .shortcuts-head { font-size: var(--t-body); font-weight: 650; padding: 14px 18px 10px;
    border-bottom: 1px solid var(--grid); }
  .shortcuts-list { padding: 6px 8px; }
  .shortcut-row { display: flex; align-items: center; justify-content: space-between;
    gap: var(--s-4); padding: 8px 10px; font-size: var(--t-body); color: var(--text-secondary); }
  .shortcut-row .kbd { color: var(--text-primary); min-width: 34px; text-align: center; }

  /* ---- Progressive disclosure ---- */
  details.fold { border-top: 1px solid var(--grid); padding-top: var(--s-3); }
  details.fold > summary { cursor: pointer; list-style: none; color: var(--text-secondary);
    font-size: var(--t-body); padding: 4px 0; user-select: none; }
  details.fold > summary::-webkit-details-marker { display: none; }
  details.fold > summary::before { content: "+"; display: inline-block; width: 15px;
    color: var(--text-muted); font-weight: 600; }
  details.fold[open] > summary::before { content: "\2212"; }
  details.fold > summary:hover { color: var(--text-primary); }

  a:focus-visible, button:focus-visible, summary:focus-visible, input:focus-visible,
  select:focus-visible, [tabindex]:focus-visible {
    outline: 2px solid var(--bar); outline-offset: 2px; border-radius: 4px; }


/* ===================================================================
   RELATIONSHIP GRAPH + COMPANY REPORT
   Shared by the dashboard and the per-company intelligence page.
   =================================================================== */
.graph-wrap { overflow-x: auto; padding-bottom: 4px; }
.graph-wrap svg { display: block; height: auto; }
.gn { cursor: default; transition: opacity .14s var(--ease); }
.gn:focus { outline: none; }
.gn:focus rect:first-of-type { stroke: var(--bar); stroke-width: 1.6; }
.gl { transition: stroke-opacity .14s var(--ease); }

/* Company intelligence report */
.co-head { display: flex; align-items: flex-start; gap: var(--s-5); flex-wrap: wrap;
  margin-bottom: var(--s-5); }
.co-id .tk { font-size: 32px; font-weight: 700; letter-spacing: -.02em; line-height: 1.1; font-family: var(--font-mono); }
.co-id .nm { color: var(--text-secondary); font-size: var(--t-body); margin-top: 2px; }
.co-id .meta { color: var(--text-muted); font-size: var(--t-meta); margin-top: 6px; }
.co-score { margin-left: auto; text-align: right; }
.co-score .v { font-size: var(--t-hero); font-weight: 700; line-height: .95;
  letter-spacing: -.035em; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.co-score .l { color: var(--text-muted); font-size: var(--t-meta); margin-top: 4px; }
.co-cols { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-5); }
@media (max-width: 780px) { .co-cols { grid-template-columns: 1fr; } }
.tl { border-left: 2px solid var(--grid); padding-left: var(--s-4); margin-left: 3px; }
.tl-item { position: relative; padding: 8px 0; }
.tl-item::before { content: ""; position: absolute; left: calc(-1 * var(--s-4) - 4px);
  top: 15px; width: 7px; height: 7px; border-radius: 50%; background: var(--text-muted); }
.tl-item.pos::before { background: var(--bull); }
.tl-item.neg::before { background: var(--bear); }
.tl-when { color: var(--text-muted); font-size: var(--t-micro); }
.tl-head { font-size: var(--t-body); line-height: 1.45; margin: 1px 0 2px; }
.tl-meta { color: var(--text-muted); font-size: var(--t-meta); }
.co-back { color: var(--text-muted); font-size: var(--t-meta); display: inline-block;
  margin-bottom: var(--s-4); text-decoration: none; }
.co-back:hover { color: var(--text-primary); }
.exp-row { display: flex; align-items: baseline; gap: var(--s-2); padding: 6px 0;
  border-top: 1px solid var(--grid); font-size: var(--t-body); }
.exp-row:first-child { border-top: none; }
.exp-row .w { margin-left: auto; color: var(--text-muted); font-size: var(--t-meta);
  white-space: nowrap; }
.tag-ben { font-size: var(--t-micro); color: var(--bull); border: 1px solid
  color-mix(in srgb, var(--bull) 35%, var(--border)); border-radius: 999px; padding: 0 7px; }


/* Market regime: the backdrop every other number is read against. */
.regime { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap;
  padding: 10px 0 0; font-size: var(--t-body); }
.regime .rl { font-weight: 650; }
.regime .rg { color: var(--text-secondary); }
.regime .rc { color: var(--text-muted); font-size: var(--t-meta); white-space: nowrap; }
.regime .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.regime-ev { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.regime-ev .ev { font-size: var(--t-micro); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; white-space: nowrap; }
.regime-ev .ev b { font-variant-numeric: tabular-nums; font-family: var(--font-mono); }

  /* Measured exposure, holding by holding. Deliberately plain: the value is
     that the numbers are checkable, not that the panel is decorative. */
  .xc-list { margin-top: var(--s-4); display: flex; flex-direction: column; gap: 6px; }
  .xc-row { display: grid; grid-template-columns: 58px 1fr; gap: 10px;
    align-items: baseline; padding: 5px 0; border-top: 1px solid var(--border); }
  .xc-row:first-child { border-top: none; }
  .xc-tk { font-weight: 650; font-size: 12.5px; color: var(--text-primary); font-family: var(--font-mono); }
  .xc-tags { display: flex; flex-wrap: wrap; gap: 5px; }
  .xc-tag { font-size: 11px; color: var(--text-muted); border: 1px solid var(--border);
    border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
  .xc-tag.pos { color: var(--status-good); border-color: var(--status-good); }
  .xc-tag.neg { color: var(--status-critical); border-color: var(--status-critical); }
  /* The amber that works as a border is 1.7:1 as text in light mode, which
     is why there are two tokens. The guard caught this. */
  .xc-tag.warn { color: var(--status-warning-text); border-color: var(--status-warning); }

  /* The unexplained cell is the one to read, so it is the one that is not
     quiet. Everything else on the row is context for it. */
  .ew-cell.attr-key { border-color: var(--bar); }
  .attr-news { display: block; font-size: 11px; color: var(--text-muted);
    margin-top: 3px; line-height: 1.5; }
  .attr-news a { color: var(--text-secondary); }

/* The book's own sentiment trend, reusing the same chart component already
   built for a single position's history - real /history data, not a new
   visual invented for this spot. Quiet by default: no border, no card, it
   sits under the aggregate it explains rather than competing with it. */
.brief-spark { margin-top: var(--s-3); max-width: 640px; }
.brief-spark-head { font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 4px; }

/* Live-value micro-interactions: a brief tinted sweep on a number that just
   changed under a 60-second poll, symmetric fade in/out, colour-only (no
   layout shift) so nothing reflows while a reader's eye is on the figure. */
@keyframes flashUp   { 0%{ background: color-mix(in srgb, var(--bull) 22%, transparent); }
                        100%{ background: transparent; } }
@keyframes flashDown { 0%{ background: color-mix(in srgb, var(--bear) 22%, transparent); }
                        100%{ background: transparent; } }
.flash-up   { animation: flashUp .9s ease-out; border-radius: 4px; }
.flash-down { animation: flashDown .9s ease-out; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { .flash-up, .flash-down { animation: none; } }

/* ---------------------------------------------------------- diffusion
   Deliberately restrained. The badge is a status colour, not an alarm, and
   the DESCRIPTIVE pill is visually quieter than UNUSUAL so the eye lands on
   the components that actually cleared a baseline. A panel that made every
   component look equally significant would undo the labelling. */
.diff-badge { display:inline-block; color:#fff; font-size:11px;
  font-weight:600; letter-spacing:.03em; padding:2px 8px; border-radius:3px;
  vertical-align:middle; white-space:nowrap; }
.diff-pill { display:inline-block; font-size:10px; font-weight:600;
  letter-spacing:.06em; padding:2px 6px; border-radius:2px; white-space:nowrap; }
.diff-unusual { background:var(--tint-critical); color:var(--status-critical); }
.diff-desc    { background:var(--tint-neutral); color:var(--text-secondary); }
.diff-none    { background:var(--tint-quiet); color:var(--text-muted); }
.diff-head { display:flex; flex-wrap:wrap; gap:8px 16px; align-items:baseline;
  margin-bottom:6px; }
.diff-head h3 { margin:0; }
.diff-meta { font-size:12px; color:var(--muted); }
.diff-table { width:100%; border-collapse:collapse; font-size:13px;
  margin:8px 0 4px; }
.diff-table th { text-align:left; font-size:10px; text-transform:uppercase;
  letter-spacing:.08em; color:var(--muted); padding:6px 8px;
  border-bottom:1px solid var(--border); white-space:nowrap; }
.diff-table td { padding:6px 8px; border-bottom:1px solid var(--border);
  vertical-align:top; }
.diff-table td.num { text-align:right; font-variant-numeric:tabular-nums;
  white-space:nowrap; }
.diff-chain { margin:8px 0; }
.diff-node { display:inline-block; padding:5px 10px; border-radius:4px;
  background:var(--panel); border:1px solid var(--border);
  font-size:13px; }
.diff-origin { font-weight:600; }
.diff-arrow { color:var(--muted); margin:2px 0 2px 14px; font-size:14px; }
.diff-chips { display:flex; flex-wrap:wrap; gap:6px; margin-top:12px; }
.diff-chip { border:1px solid var(--border); background:transparent;
  border-radius:4px; padding:4px 8px; font-size:12px; cursor:pointer;
  display:inline-flex; align-items:center; gap:6px; }
.diff-chip:hover { background:var(--panel); }
/* Missing coverage gets a visible callout rather than silence. */
.diff-unmapped { font-size:13px; padding:8px 10px; border-radius:4px;
  background:var(--tint-warning); border:1px solid var(--tint-warning-edge);
  color:var(--text-primary); margin:8px 0; }
.diff-caveat { font-size:12px; font-style:italic; }
.diff-foot { font-size:12px; margin-top:10px; }
@media (max-width:640px) {
  .diff-table { display:block; overflow-x:auto; }
}

/* Ranking position in the scan chips. The number is the product's claim about
   attention order, so it is shown, not implied by list position alone. */
.diff-rank {
  display: inline-block;
  min-width: 1.25em;
  font-variant-numeric: tabular-nums; font-family: var(--font-mono);
  font-weight: 600;
  opacity: 0.65;
}
.diff-order,
.diff-why {
  margin: 0.4rem 0 0.6rem;
  font-size: 0.85rem;
  line-height: 1.45;
}
.diff-why {
  border-left: 2px solid var(--border);
  padding-left: 0.6rem;
}

/* Measured-validation disclosure. Collapsed by default so the scan stays the
   focus, but always present: a result the reader cannot inspect is a claim. */
.diff-validation {
  margin: 0.75rem 0 1rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.85rem;
}
.diff-validation summary {
  cursor: pointer;
  font-weight: 600;
}
.diff-validation ul {
  margin: 0.3rem 0 0.6rem 1.1rem;
  padding: 0;
}
.diff-validation li { margin: 0.2rem 0; line-height: 1.45; }

/* ---------------------------------------------------------------- YOUR BOOK
   The first screen of the product. Institutional density: a band header, then
   cards that are scannable in one pass - source, evidence grade, how much of
   the book it reaches, the headline, the route, and the positions.

   Colour carries attention state and nothing else, and never alone: each band
   has a heading in words, and every direction is a word and a sign as well as
   a colour. */
.record-link {
  margin: 0 0 var(--s-5); font-size: 12.5px; color: var(--text-muted);
  max-width: 76ch; line-height: 1.5;
}
.record-link a { color: var(--text-secondary); }

#book-section { margin-bottom: var(--s-6); }
.bt-team { font-size: 11px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: var(--s-2); }
.bt-title { display: flex; align-items: baseline; gap: var(--s-3);
  flex-wrap: wrap; margin-bottom: var(--s-4); }
.bt-title h2 { margin: 0; }
.bt-sub { font-size: 12.5px; color: var(--text-muted); }

.bt-band { margin-bottom: var(--s-4); }
.bt-band-head { display: flex; align-items: center; gap: var(--s-2);
  border-top: 2px solid var(--grid); padding-top: var(--s-2);
  margin-bottom: var(--s-3); }
.bt-band-head h3 { margin: 0; font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-secondary); }
.bt-band.att .bt-band-head { border-top-color: var(--status-critical); }
.bt-band.watch .bt-band-head { border-top-color: var(--status-warning); }
.bt-count { font-size: 11.5px; color: var(--text-muted);
  font-variant-numeric: tabular-nums; font-family: var(--font-mono); margin-left: auto; }
.bt-none { margin: 0; font-size: 13px; color: var(--text-muted);
  max-width: 76ch; line-height: 1.55; }

.bt-item { margin-bottom: var(--s-2); }
.bt-item .eventbook { margin: 0 0 var(--s-3); }
.bt-card { position: relative; display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface-1); border: 1px solid var(--border);
  border-left: 3px solid var(--grid); border-radius: var(--radius-md);
  padding: var(--s-3) var(--s-4); box-shadow: var(--shadow-sm);
  transition: box-shadow .16s var(--ease), border-color .16s var(--ease),
    transform .16s var(--ease); }
.bt-card:hover { border-color: var(--bar); transform: translateY(-1px);
  box-shadow: var(--shadow-md), 0 0 0 1px var(--bar-glow); }
.bt-card.att { border-left-color: var(--status-critical); }
.bt-card.watch { border-left-color: var(--status-warning); }
/* The card is a disclosure, and nothing about a plain bordered box says so.
   A chevron is the one glyph every reader already reads as "more below". */
.bt-card::after { content: "\2304"; position: absolute; top: var(--s-3); right: var(--s-3);
  color: var(--text-muted); font-size: 13px; line-height: 1; }
.bt-top { display: flex; align-items: center; gap: var(--s-2);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 4px; padding-right: var(--s-4); }
.bt-src { font-weight: 650; color: var(--text-secondary); }
.bt-grade { border: 1px solid var(--grid); border-radius: 3px;
  padding: 0 5px; color: var(--text-secondary); }
.bt-reach { margin-left: auto; font-variant-numeric: tabular-nums; font-family: var(--font-mono);
  text-transform: none; letter-spacing: 0; }
.bt-head { margin: 0 0 3px; font-size: 15.5px; font-weight: 600;
  line-height: 1.35; color: var(--text-primary); }
/* The route, named rather than described. A short rule so a plain sentence
   ("via Israel") and a channel-and-weight sentence ("Crude Oil (WTI) market
   news, weighted 45%") both read as the same kind of thing: a stated path,
   not prose to parse. */
.bt-route { display: flex; align-items: baseline; gap: 6px; margin: 0 0 var(--s-2);
  font-size: 12px; color: var(--text-secondary); }
.bt-route::before { content: "\2192"; color: var(--text-muted); font-weight: 650; }
.bt-route .rt-text { font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text-secondary); }

/* The pathway, drawn. Real hops from evidence_quality.route_path, never
   invented client-side - a single-hop route (a filing, or an entity with no
   further channel on record) draws as one chip and no dangling arrow. The
   channel node is the one worth reading, so it is the only one that borrows
   the accent; the entity node stays neutral. */
.pathway { display: flex; flex-wrap: wrap; align-items: center; gap: 5px;
  margin: 0 0 var(--s-2); }
.pw-node { display: inline-flex; align-items: baseline; gap: 6px;
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.3;
  border: 1px solid var(--border); border-radius: 6px; padding: 3px 9px;
  background: var(--surface-1); color: var(--text-secondary); }
.pw-node.channel { color: var(--text-primary); border-color: var(--bar);
  background: color-mix(in srgb, var(--bar) 7%, var(--surface-1)); }
.pw-node.filing { color: var(--status-good); }
.pw-arrow { color: var(--text-muted); font-size: 12px; flex: none; }
.pw-wt { font-size: 9.5px; font-weight: 600; color: var(--text-muted); }
.bt-holds { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.bt-hold { display: inline-flex; align-items: baseline; gap: 6px;
  font: inherit; font-size: 12.5px; cursor: pointer;
  background: var(--page); border: 1px solid var(--grid); border-radius: 999px;
  padding: 2px 10px; color: var(--text-primary); }
.bt-hold:hover { border-color: var(--bar); }
.bt-tk { font-weight: 650; font-family: var(--font-mono); }
.bt-wt { color: var(--text-muted); font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.bt-dir { font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.bt-dir.pos { color: var(--bull); }
.bt-dir.neg { color: var(--bear); }
.bt-dir.mut { color: var(--text-muted); }
.bt-split { font-size: 12px; color: var(--status-warning-text); }

.bt-clear-note { margin: 0 0 var(--s-2); font-size: 13px;
  color: var(--text-secondary); max-width: 76ch; line-height: 1.55; }
.bt-clears { display: flex; flex-direction: column; gap: 4px; }
.bt-clear { display: flex; align-items: baseline; gap: var(--s-2);
  width: 100%; text-align: left; font: inherit; font-size: 13px;
  cursor: pointer; background: none; border: none; border-radius: 5px;
  padding: 5px 8px; color: var(--text-secondary); }
.bt-clear:hover { background: var(--surface-1); color: var(--text-primary); }
.bt-clear-src { flex: none; font-size: 10.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted); min-width: 74px; }
.bt-unmapped { margin: var(--s-3) 0 0; font-size: 12.5px;
  color: var(--text-secondary); max-width: 76ch; line-height: 1.55; }

/* ---------------------------------------------------------------------------
   The impact reading and its parts.

   The figure gets the size, the chips get the meaning, the arithmetic gets a
   disclosure. Every colour is a token, so this reads correctly in both themes
   and nothing here defines a colour that exists in only one of them.
   --------------------------------------------------------------------------- */
.imp-hero { display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: var(--s-3) var(--s-4); margin: var(--s-3) 0 var(--s-2); }
.imp-fig { display: flex; flex-direction: column; gap: 1px; }
.imp-label { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-muted); }
.imp-fig .figure { font-size: 30px; font-weight: 650; line-height: 1;
  font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.imp-fig .unit { font-size: 11.5px; color: var(--text-muted); }
.imp-conf { display: flex; flex-direction: column; gap: 1px; padding-bottom: 3px; }
.imp-conf .imp-v { font-size: 17px; font-weight: 650;
  font-variant-numeric: tabular-nums; font-family: var(--font-mono); color: var(--text-primary); }
.imp-conf .mut { font-size: 11.5px; }

.imp-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 0 0 var(--s-2); }
.imp-chip { display: inline-flex; align-items: baseline; gap: 5px;
  border: 1px solid var(--grid); border-radius: 3px; padding: 2px 7px;
  background: var(--surface-1); cursor: help; }
.imp-chip .imp-k { font-size: 9.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted); }
.imp-chip .imp-v { font-size: 12px; font-weight: 650; color: var(--text-primary); }
.imp-note { font-size: 11.5px; color: var(--text-muted); margin-bottom: var(--s-2); }

.imp-work .imp-arith { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; color: var(--text-secondary); background: var(--surface-1);
  border: 1px solid var(--grid); border-radius: 3px;
  padding: 5px 8px; margin: 6px 0 8px; overflow-x: auto; }
.imp-row { display: grid; grid-template-columns: 6.5rem 1fr; gap: 4px 10px;
  padding: 4px 0; border-top: 1px solid var(--grid); font-size: 12.5px; }
.imp-row:first-of-type { border-top: none; }
.imp-row .imp-k { color: var(--text-muted); text-transform: uppercase;
  font-size: 10px; letter-spacing: .05em; padding-top: 2px; }
.imp-row .imp-why { line-height: 1.5; }
.imp-terms { font-size: 11.5px; margin-top: 6px; }

/* Whose sentence is this? The tag answers it before the reader starts reading,
   which is the only place that answer is any use. */
.tk-tag { display: inline-block; font-size: 9px; letter-spacing: .06em;
  text-transform: uppercase; border-radius: 2px; padding: 1px 5px;
  vertical-align: 1px; font-weight: 650; }
.tk-tag.src { background: var(--surface-1); border: 1px solid var(--grid);
  color: var(--text-secondary); }
.tk-tag.ours { background: var(--surface-1); border: 1px dashed var(--grid);
  color: var(--text-muted); }
.tk .tk-text { font-size: 14px; line-height: 1.45; margin: 4px 0 2px; }
.tk .tk-note { font-size: 11.5px; margin-top: 6px; }
.tk-facts { margin-top: 6px; }
.wm-row { display: grid; grid-template-columns: 4.5rem 1fr; gap: 4px 10px;
  padding: 5px 0; border-top: 1px solid var(--grid); font-size: 12.5px; }
.wm-row:first-of-type { border-top: none; }
.wm-text { line-height: 1.5; }

/* A holding we could not see is not a holding the event missed. */
.eb-row.miss.unseen .eb-v { color: var(--status-warning-text); font-style: normal; }

.bt-take { margin: 0 0 4px; font-size: 13px; line-height: 1.45;
  color: var(--text-secondary); }
.bt-take.empty { color: var(--text-muted); font-style: italic; }
.bt-srclink { font-style: normal; font-size: 11.5px; font-weight: 600;
  color: var(--bar); text-decoration: none; white-space: nowrap; }
.bt-srclink:hover { text-decoration: underline; }
.bt-why { margin: 0 0 var(--s-2); font-size: 12.5px; line-height: 1.45;
  color: var(--text-muted); }
.bt-down { color: var(--status-warning-text); }

/* The book-level aggregate, deliberately smaller than the reading it sums.
   It used to be the largest thing on the page and it is the least supported. */
.brief-net { margin: var(--s-3) 0 0; font-size: 12.5px; line-height: 1.6;
  color: var(--text-muted); }
.brief-netfig { font-size: 15px; font-weight: 650;
  font-variant-numeric: tabular-nums; font-family: var(--font-mono); margin: 0 4px; }
.brief-why { margin: var(--s-2) 0; font-size: 13px; line-height: 1.5;
  color: var(--text-secondary); }


/* The sentence that makes the four numbers above mean something. Without it
   the panel was a row of percentages and an instruction to look at one. */
.attr-read { margin: var(--s-2) 0 0; font-size: 12.5px; line-height: 1.55;
  color: var(--text-secondary); max-width: 62ch; }


/* One story driving many positions is one story. Without this line a card
   listing thirteen tickers reads as thirteen separate findings. */
.bt-spread { margin: 0 0 var(--s-2); font-size: 12.5px; line-height: 1.45;
  color: var(--text-muted); }


/* Coverage at the door. A book we cannot read is not a quiet book, and the
   only cheap moment to say so is before it is committed. */
.imp-cov { border: 1px solid var(--grid); border-radius: 4px;
  padding: 10px 12px; margin: var(--s-3) 0; background: var(--surface-1); }
.imp-cov.gap { border-left: 3px solid var(--status-warning); }
.imp-cov.full { border-left: 3px solid var(--bull); }
.imp-cov-fig { font-size: 15px; }
.imp-cov-fig strong { font-size: 20px; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.imp-cov-fig .mut { font-size: 12.5px; }
.imp-cov-say { margin: 5px 0 0; font-size: 12.5px; line-height: 1.55;
  color: var(--text-secondary); max-width: 64ch; }
.imp-cov-list { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px;
  align-items: baseline; }
.imp-cov-tk { font-size: 11.5px; font-weight: 650; border: 1px solid var(--grid);
  border-radius: 3px; padding: 1px 5px; color: var(--text-secondary); }

/* ---------------------------------------------------------------------------
   COLLAPSE: how many independent bets the book actually holds.

   Instrument, not card. A thin rule, a large tabular figure, and a strip that
   is the arithmetic drawn rather than decorated: one tick per holding, grouped
   into the entity blocs they share, each segment sized by the weight on it. No
   gradient, no glass, no shadow - the only ink that is not data is the rule.
   -------------------------------------------------------------------------- */
.collapse { border-top: 2px solid var(--bar); padding-top: var(--s-3);
  margin-bottom: var(--s-5); }
.collapse-figure { display: flex; align-items: center; gap: var(--s-3);
  flex-wrap: wrap; }
.collapse-num { font-family: var(--font-mono); font-size: 46px; line-height: .95;
  font-variant-numeric: tabular-nums; color: var(--bar); letter-spacing: -.03em; }
.collapse-say { display: flex; flex-direction: column; }
.collapse-lede { font-size: 13px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-primary); line-height: 1.2; }
.collapse-vs { font-size: 12.5px; color: var(--text-muted); line-height: 1.3; }
.collapse-range { margin-left: auto; text-align: right; font-size: 12px;
  color: var(--text-muted); font-family: var(--font-mono);
  font-variant-numeric: tabular-nums; }
.collapse-range span { display: block; font-family: var(--font-sans);
  max-width: 26ch; line-height: 1.35; }

.collapse-explain { margin: var(--s-2) 0 0; font-size: 13.5px; line-height: 1.5;
  color: var(--text-secondary); max-width: 70ch; }
.collapse-strip { display: flex; gap: 3px; margin: var(--s-3) 0 var(--s-2); }
.collapse-bloc { min-width: 0; background: var(--bar-track);
  border-top: 3px solid var(--bar); padding: var(--s-2) 6px var(--s-1); }
.collapse-ticks { display: flex; gap: 2px; flex-wrap: wrap; margin-bottom: 5px; }
.collapse-tick { width: 7px; height: 7px; background: var(--bar);
  border-radius: 1px; opacity: .85; }
.collapse-bloc-label { font-size: 11px; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.collapse-hedge { font-style: normal; font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--status-good); }
.collapse-bloc-w { font-family: var(--font-mono); font-size: 11px;
  font-variant-numeric: tabular-nums; color: var(--text-muted); }

/* Coverage is not a footnote. A book we can only half-read gets told so in
   the same block as the number, because the number describes only the half. */
.collapse-cov { margin: var(--s-2) 0 0; font-size: 12.5px; line-height: 1.5;
  color: var(--text-secondary); max-width: 76ch; }
.collapse-cov.thin { border-left: 3px solid var(--status-warning);
  padding-left: var(--s-2); }
.collapse-foot { margin: var(--s-2) 0 0; font-size: 11.5px; line-height: 1.5;
  color: var(--text-muted); max-width: 76ch; }
.collapse-refuse { margin: var(--s-2) 0 0; font-size: 13px; line-height: 1.55;
  color: var(--text-secondary); max-width: 76ch; }
.collapse-none { border-top-color: var(--grid); }

@media (max-width: 640px) {
  .collapse-num { font-size: 34px; }
  .collapse-strip { flex-wrap: wrap; }
  .collapse-bloc { flex: 1 1 42% !important; }
}

/* ---------------------------------------------------------------------------
   KEYSTONE: what the bets figure is resting on.

   A line under COLLAPSE, not a second card. Ten segments rather than a
   continuous bar, because the underlying quantity is a fraction of visible
   concentration and a smooth bar would imply a precision the citation layer
   does not have.
   -------------------------------------------------------------------------- */
.keystone { border-left: 2px solid var(--grid); padding: 0 0 0 var(--s-3);
  margin: 0 0 var(--s-5); }
.keystone p { margin: var(--s-1) 0 0; font-size: 12.5px; line-height: 1.5;
  color: var(--text-secondary); max-width: 84ch; }
.keystone-head { display: flex; align-items: center; gap: var(--s-2);
  flex-wrap: wrap; }
.keystone-lede { font-size: 11px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted); }
.keystone-bar { display: inline-flex; gap: 2px; }
.keystone-seg { width: 12px; height: 6px; background: var(--bar-track);
  border-radius: 1px; }
.keystone-seg.on { background: var(--bar); }
.keystone-pct { font-family: var(--font-mono); font-size: 12px;
  font-variant-numeric: tabular-nums; color: var(--text-primary); }
.keystone-verdict { font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted);
  border: 1px solid var(--border); padding: 1px 6px; border-radius: 2px; }
.keystone-verdict.good { color: var(--status-good);
  border-color: var(--status-good); }
.keystone-verdict.warn { color: var(--status-warning-text);
  border-color: var(--status-warning); }
.keystone-cov { color: var(--text-muted); }
.keystone-foot { font-size: 11.5px !important; color: var(--text-muted) !important; }
.keystone-none { border-left-color: var(--grid); color: var(--text-muted);
  font-size: 12.5px; }

/* ---------------------------------------------------------------------------
   TOPOLOGY: the shape of the book, and what is holding it together.

   States rather than a score, and the regions drawn as regions. The vertical
   rule marks a cut: what sits either side of it stops being connected when
   the bridge is removed.
   -------------------------------------------------------------------------- */
.topo { border-left: 2px solid var(--grid); padding: 0 0 0 var(--s-3);
  margin: 0 0 var(--s-5); }
.topo p { margin: var(--s-1) 0 0; font-size: 12.5px; line-height: 1.5;
  color: var(--text-secondary); max-width: 84ch; }
.topo-head { display: flex; align-items: center; gap: var(--s-2); }
.topo-lede { font-size: 11px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted); }
.topo-tag { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); border: 1px solid var(--border);
  padding: 1px 6px; border-radius: 2px; }
.topo-tag.good { color: var(--status-good); border-color: var(--status-good); }
.topo-tag.warn { color: var(--status-warning-text);
  border-color: var(--status-warning); }

.topo-map { display: flex; align-items: stretch; flex-wrap: wrap; gap: 0;
  margin: var(--s-2) 0 0; }
.topo-region { font-family: var(--font-mono); font-size: 12px;
  background: var(--bar-track); border-top: 2px solid var(--bar);
  padding: 5px 9px; color: var(--text-primary); }
.topo-region i { font-style: normal; color: var(--text-muted); padding: 0 2px; }
.topo-cut { display: inline-flex; align-items: center; padding: 0 7px;
  color: var(--status-warning-text); font-weight: 700; }
.topo-gap { color: var(--text-muted) !important; }
.topo-foot { font-size: 11.5px !important; color: var(--text-muted) !important; }

/* =====================================================================
   INVESTIGATE (/investigate)

   Theme tokens only, no literal colours: the book panel shipped a dark-mode
   failure once by hard-coding hex, and tests/test_book_today.py now forbids it
   there. The same discipline applies here by choice rather than by test.
   ===================================================================== */
.inv-counts { display: flex; flex-wrap: wrap; gap: var(--s-4);
  font-size: .92rem; color: var(--text-secondary); }
.inv-counts b { color: var(--text-primary); font-variant-numeric: tabular-nums; }

.inv-row { border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface-1); box-shadow: var(--shadow-sm);
  padding: 13px 15px; margin-bottom: var(--s-3); }
.inv-row.settled { opacity: .72; }

.inv-rhead, .inv-jhead { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-2); margin-bottom: var(--s-2); }

.inv-tick { font-family: var(--font-mono); font-weight: 600;
  color: var(--text-primary); }
.inv-kind { color: var(--text-secondary); font-size: .92rem; }
.inv-muted { color: var(--text-muted); font-size: .85rem; }

.inv-badge { font-size: .74rem; letter-spacing: .03em; text-transform: uppercase;
  padding: 2px 7px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); color: var(--text-secondary); }
/* Blocking is the one state that limits what the product may claim, so it is
   the one that gets the warning colour. */
.inv-badge.blocking { color: var(--status-warning-text);
  border-color: var(--status-warning); }
.inv-badge.settled { color: var(--status-good); border-color: var(--status-good); }

.inv-why { color: var(--text-primary); margin-bottom: var(--s-1); }
.inv-check { color: var(--text-secondary); font-size: .92rem;
  margin-bottom: var(--s-2); }
.inv-meta { color: var(--text-muted); font-size: .82rem;
  font-family: var(--font-mono); margin-bottom: var(--s-3); }
.inv-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }

.inv-jrow { border-left: 2px solid var(--grid); padding: 9px 0 9px 13px;
  margin-bottom: var(--s-3); }
.inv-status { font-size: .74rem; letter-spacing: .03em;
  font-weight: 600; color: var(--bar); }
.inv-note { color: var(--text-primary); margin: var(--s-1) 0;
  white-space: pre-wrap; overflow-wrap: anywhere; }
/* What the product said when the note was written, visually subordinate to the
   note itself: the judgement is the record, the reading is its context. */
.inv-frozen { color: var(--text-secondary); font-size: .88rem;
  border-top: 1px dashed var(--border); padding-top: var(--s-1); }
