/* Quarterly positioning (/positioning).

   The page renders inside `.hm tf` and deliberately reuses the hiring monitor's
   design system: the same tokens, panels, tabs, tables and — importantly — the
   verified shell-leak resets at the top of hiring.css. Duplicating 300 lines to
   rename a scope would fork those fixes and let them drift apart. Only rules
   this report needs that the hiring monitor has no concept of live here. */

/* ── Theme toggle ────────────────────────────────────────────────────────
   hiring.css defines its palette once, under `@media (prefers-color-scheme:
   dark)`. The site shell instead switches on `[data-theme]`, set by the L/D/A
   control. The two disagree the moment a reader overrides their OS: measured
   2026-08-13, OS-light + toggle-dark rendered a dark shell wrapped around a
   light report, and OS-dark + toggle-light the exact inverse.

   These re-declare the same tokens keyed on the toggle. Scoped to `.tf`, so
   /jobs keeps whatever behaviour it has today rather than being changed from
   under it by a fix aimed at this page. The attribute selector outranks the
   bare `.hm` rule in the media query, so it wins in both directions. */
:root[data-theme="dark"] .tf {
  --bg:#10151b; --panel:#171d24; --panel-2:#222a33; --ink:#edf1f5; --muted:#aab4bf;
  --line:#303944; --accent:#78a2ff; --accent-soft:#1e315e; --positive:#66d4ae;
  --positive-soft:#173b31; --negative:#ff8993; --negative-soft:#4a252b;
  --caution:#f4c15c; --caution-soft:#40351d; --shadow:none;
}
:root[data-theme="light"] .tf {
  --bg:#f3f5f7; --panel:#fff; --panel-2:#f8fafb; --ink:#17202a; --muted:#68727e;
  --line:#dce1e6; --accent:#245bd7; --accent-soft:#e9efff; --positive:#0a7656;
  --positive-soft:#e6f5ef; --negative:#b43b45; --negative-soft:#fbecee;
  --caution:#8a5a00; --caution-soft:#fff3d6; --shadow:0 1px 2px rgba(20,32,44,.05);
}

/* ═══ SIGNATURE: the 45-day disclosure shadow ════════════════════════════
   The defining property of a 13F is that it is late by law. Every position on
   this page arrives trailing a statutory delay, and v1 said so in a yellow
   alert box — the least beautiful way to state the most important thing.

   Here the delay is SPATIAL: a quarter-end mark casts a band forward to the
   day-45 deadline, and a dotted tail runs on to today. The reader sees the
   distance rather than reading a number.

   Copper is reserved for this element and nothing else on the page. That is
   the whole boldness budget — everything around it stays on the shell's own
   quiet palette. */
.tf { --shadow-ink:#b4622a; --shadow-band:#b4622a26; --shadow-rule:#b4622a55; }
@media (prefers-color-scheme:dark) {
  :root:where(:not([data-theme="light"])) .tf {
    --shadow-ink:#e08a4e; --shadow-band:#e08a4e2e; --shadow-rule:#e08a4e66; }
}
:root[data-theme="dark"] .tf {
  --shadow-ink:#e08a4e; --shadow-band:#e08a4e2e; --shadow-rule:#e08a4e66; }
:root[data-theme="light"] .tf {
  --shadow-ink:#b4622a; --shadow-band:#b4622a26; --shadow-rule:#b4622a55; }

.tf .shadowrail { margin:14px 0 2px; padding:0; }
.tf .sr-head { display:flex; align-items:baseline; justify-content:space-between;
  gap:16px; margin-bottom:9px; }
.tf .sr-asof { min-width:0; }
.tf .sr-eyebrow { display:block; color:var(--muted); font:700 9.5px/1 var(--mono);
  letter-spacing:.13em; text-transform:uppercase; margin-bottom:5px; }
.tf .sr-date { font-size:25px; font-weight:750; letter-spacing:-.03em;
  line-height:1; color:var(--ink); }
.tf .sr-right { text-align:right; min-width:0; }
.tf .sr-right .sr-date { font-size:15px; color:var(--shadow-ink); }

/* The rail itself. The band is the shadow the quarter-end casts. */
.tf .sr-rail { position:relative; height:34px; }
.tf .sr-line { position:absolute; left:0; right:0; top:16px; height:1px;
  background:var(--line); }
.tf .sr-band { position:absolute; top:11px; height:11px; border-radius:2px;
  background:var(--shadow-band);
  border-left:2px solid var(--shadow-ink);
  border-right:1px dashed var(--shadow-rule); }
.tf .sr-tail { position:absolute; top:16px; height:1px;
  background:repeating-linear-gradient(90deg,
    var(--shadow-rule) 0 3px, transparent 3px 7px); }
.tf .sr-dot { position:absolute; top:11px; width:11px; height:11px;
  margin-left:-5px; border-radius:50%; background:var(--shadow-ink);
  box-shadow:0 0 0 3px var(--panel); }
.tf .sr-now { position:absolute; top:9px; width:2px; height:15px;
  background:var(--ink); opacity:.55; }
.tf .sr-tick { position:absolute; top:26px; color:var(--muted);
  font:600 9px/1 var(--mono); white-space:nowrap; transform:translateX(-50%); }
.tf .sr-tick.start { transform:none; }
.tf .sr-tick.end { transform:translateX(-100%); }
.tf .sr-span { position:absolute; top:-3px; color:var(--shadow-ink);
  font:750 9px/1 var(--mono); letter-spacing:.06em; text-transform:uppercase;
  white-space:nowrap; transform:translateX(-50%); }

/* One sentence, not a paragraph. The rail carries the argument. */
.tf .sr-say { margin:12px 0 0; padding-top:10px; border-top:1px solid var(--line);
  color:var(--muted); font-size:11.5px; line-height:1.5; }
.tf .sr-say b { color:var(--ink); }

/* ── Rank slopegraph ─────────────────────────────────────────────────────
   Two rankings of the same securities — by capital and by breadth — joined by
   ribbons. The point it makes in one glance is that the same names lead both,
   which is a fact about index construction rather than conviction. */
.tf .slope { position:relative; }
.tf .slope svg { display:block; width:100%; height:auto; overflow:visible; }
.tf .slope .rib { fill:none; stroke:var(--s1); stroke-width:1.4; opacity:.32;
  vector-effect:non-scaling-stroke; }
.tf .slope .rib.both { stroke:var(--shadow-ink); opacity:.5; stroke-width:1.8; }
.tf .slope .sl-name { font:600 10px/1 Inter,ui-sans-serif,system-ui,sans-serif;
  fill:var(--ink); }
.tf .slope .sl-val { font:650 9px/1 var(--mono); fill:var(--muted); }
.tf .slope .sl-head { font:750 9px/1 var(--mono); fill:var(--muted);
  letter-spacing:.1em; text-transform:uppercase; }

/* A claim stated once, as a pill, instead of a paragraph. */
.tf .claim { display:inline-flex; align-items:center; gap:7px; margin:0 0 10px;
  padding:6px 12px; border:1px solid var(--line); border-radius:999px;
  background:var(--panel-2); color:var(--ink); font-size:11px; font-weight:650; }
.tf .claim::before { content:""; width:6px; height:6px; border-radius:50%;
  background:var(--shadow-ink); }

/* ── Limitation chips ────────────────────────────────────────────────────
   Caveats stop being a wall of prose and become six labelled boundaries, each
   opening its own full text. Nothing is deleted; it just stops being the
   first thing you must read. */
.tf .chips { display:flex; flex-wrap:wrap; gap:7px; margin:10px 0 0; }
.tf .chipbtn { appearance:none; display:inline-flex; align-items:center; gap:6px;
  padding:5px 11px; border:1px solid var(--line); border-radius:999px;
  background:var(--panel); color:var(--muted); font:650 10.5px/1.2 inherit;
  cursor:pointer; text-align:left; }
.tf .chipbtn::before { content:"–"; display:grid; place-items:center;
  width:13px; height:13px; border-radius:50%; background:var(--panel-2);
  color:var(--shadow-ink); font:800 10px/1 var(--mono); }
.tf .chipbtn[aria-expanded="true"] { border-color:var(--shadow-rule);
  background:var(--shadow-band); color:var(--ink); }
.tf .chipbtn[aria-expanded="true"]::before { content:"×"; }
.tf .chipbody { margin:9px 0 0; padding:11px 13px; border-radius:10px;
  border:1px solid var(--line); background:var(--panel-2);
  color:var(--ink); font-size:11.5px; line-height:1.55; }
.tf .chipbody[hidden] { display:none; }
.tf .chipbody b { display:block; margin-bottom:3px; }

/* ── The as-of banner ────────────────────────────────────────────────────
   The one thing a reader must not miss. A 13F is a snapshot of a past
   quarter-end disclosed up to 45 days later; every number on this page is at
   least that old. It is styled as caution, not decoration, and sits above the
   KPIs rather than in a footnote. */
.tf .asof {
  display:flex; align-items:flex-start; gap:13px; margin-top:12px;
  padding:13px 16px; border:1px solid color-mix(in srgb,var(--caution) 34%,var(--line));
  border-left-width:3px; border-left-color:var(--caution);
  border-radius:var(--radius); background:var(--caution-soft);
}
.tf .asof-mark { flex:0 0 auto; display:grid; place-items:center; width:22px; height:22px;
  border-radius:50%; background:var(--caution); color:var(--caution-soft);
  font-size:13px; font-weight:800; }
.tf .asof-body { min-width:0; }
.tf .asof-title { margin:0; color:var(--caution); font-size:14px; font-weight:750;
  letter-spacing:-.01em; }
.tf .asof-title strong { font-variant-numeric:tabular-nums; }
.tf .asof-note { margin:4px 0 0; color:var(--ink); font-size:11.5px; line-height:1.45; }
.tf .asof-note b { font-variant-numeric:tabular-nums; }

/* The lag, drawn to scale: quarter-end → disclosure → today. Makes "45 days
   stale" a distance rather than a number. */
.tf .lagbar { margin-top:9px; }
.tf .lagbar-track { position:relative; height:6px; border-radius:99px;
  background:color-mix(in srgb,var(--caution) 20%,transparent); overflow:hidden; }
.tf .lagbar-fill { position:absolute; inset:0 auto 0 0; border-radius:inherit;
  background:var(--caution); }
.tf .lagbar-scale { display:flex; justify-content:space-between; gap:8px;
  margin-top:4px; color:var(--muted); font-size:9px; font-variant-numeric:tabular-nums; }

/* ── Chart tokens ────────────────────────────────────────────────────────
   Two categorical slots, validated with the dataviz palette checker against
   both surfaces: worst adjacent pair ΔE 24.7 protan / 33.6 normal (light) and
   26.8 / 31.8 (dark) — the target is >= 8, so these are clear.
   Slot 1 = holdings (what managers did). Slot 2 = price (what the market did).
   Colour follows the ENTITY, so those two never swap. */
.tf {
  --s1:#2a78d6;  --s2:#eb6834;  --s3:#1baf7a;  --s4:#eda100;
  --grid:color-mix(in srgb, var(--ink) 10%, transparent);
  --axis:color-mix(in srgb, var(--ink) 22%, transparent);
}
@media (prefers-color-scheme:dark) {
  :root:where(:not([data-theme="light"])) .tf {
    --s1:#3987e5; --s2:#d95926; --s3:#199e70; --s4:#c98500; }
}
:root[data-theme="dark"] .tf {
  --s1:#3987e5; --s2:#d95926; --s3:#199e70; --s4:#c98500; }
:root[data-theme="light"] .tf {
  --s1:#2a78d6; --s2:#eb6834; --s3:#1baf7a; --s4:#eda100; }

.tf .chart { position:relative; margin-top:6px; }
.tf .chart svg { display:block; width:100%; height:auto; overflow:visible; }
.tf .chart svg text { fill:var(--muted); font-size:10px;
  font-family:Inter,ui-sans-serif,system-ui,sans-serif; }
.tf .gridline { stroke:var(--grid); stroke-width:1; vector-effect:non-scaling-stroke; }
.tf .axisline { stroke:var(--axis); stroke-width:1; vector-effect:non-scaling-stroke; }
/* 2px lines, thin marks — the data is the ink, the frame is recessive. */
.tf .ln { fill:none; stroke-width:2; vector-effect:non-scaling-stroke;
  stroke-linejoin:round; stroke-linecap:round; }
.tf .ln-1 { stroke:var(--s1); }
.tf .ln-2 { stroke:var(--s2); }
.tf .ln-3 { stroke:var(--s3); }
.tf .ln-4 { stroke:var(--s4); }
.tf .dot-1 { fill:var(--s1); }
.tf .dot-2 { fill:var(--s2); }
.tf .dot-3 { fill:var(--s3); }
.tf .dot-4 { fill:var(--s4); }
/* a 2px surface ring so overlapping markers stay countable */
.tf .dot { stroke:var(--panel); stroke-width:2; }
.tf .baseline { stroke:var(--axis); stroke-dasharray:3 3; stroke-width:1;
  vector-effect:non-scaling-stroke; }
.tf .crosshair { stroke:var(--axis); stroke-width:1; vector-effect:non-scaling-stroke; }
.tf .splitmark { stroke:var(--caution); stroke-width:1.5; stroke-dasharray:2 3;
  vector-effect:non-scaling-stroke; }
.tf .dlabel { font-weight:700; font-size:10px; }
.tf .dlabel-1 { fill:var(--s1); }
.tf .dlabel-2 { fill:var(--s2); }
.tf .dlabel-3 { fill:var(--s3); }
.tf .dlabel-4 { fill:var(--s4); }

.tf .legend { display:flex; flex-wrap:wrap; gap:5px 14px; margin:2px 0 0;
  color:var(--muted); font-size:10px; }
.tf .legend b { display:inline-flex; align-items:center; gap:5px;
  font-weight:600; color:var(--ink); }
.tf .legend b::before { content:""; width:11px; height:3px; border-radius:2px; }
.tf .lg-1::before { background:var(--s1); }
.tf .lg-2::before { background:var(--s2); }
.tf .lg-3::before { background:var(--s3); }
.tf .lg-4::before { background:var(--s4); }
.tf .lg-split::before { background:repeating-linear-gradient(90deg,
  var(--caution) 0 2px, transparent 2px 5px); height:2px; }

.tf .tip { position:absolute; z-index:4; padding:7px 9px; border:1px solid var(--line);
  border-radius:8px; background:var(--panel); box-shadow:0 8px 22px rgba(0,0,0,.16);
  color:var(--ink); font-size:10.5px; pointer-events:none; white-space:nowrap; }
.tf .tip[hidden] { display:none; }
.tf .tip i { display:inline-block; width:9px; height:3px; border-radius:2px;
  margin-right:5px; vertical-align:middle; font-style:normal; }
.tf .tip .t1 { background:var(--s1); }
.tf .tip .t2 { background:var(--s2); }
.tf .tip .t3 { background:var(--s3); }
.tf .tip .t4 { background:var(--s4); }
.tf .tip-h { font-weight:750; margin-bottom:3px; }

/* Name picker sits in ONE row above the charts. */
.tf .picker { display:flex; flex-wrap:wrap; align-items:center; gap:6px;
  margin:2px 0 10px; }
.tf .picker label { color:var(--muted); font-size:10px; font-weight:700;
  text-transform:uppercase; letter-spacing:.03em; margin-right:2px; }
.tf .pick { appearance:none; min-height:28px; padding:4px 10px; cursor:pointer;
  border:1px solid var(--line); border-radius:999px; background:var(--panel);
  color:var(--muted); font:700 11px/1 var(--mono); }
.tf .pick[aria-pressed="true"] { background:var(--accent-soft);
  border-color:color-mix(in srgb,var(--accent) 40%,var(--line)); color:var(--accent); }
.tf .chart-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:12px; }
.tf .chart-grid .wide { grid-column:1/-1; }
@media (max-width:900px) { .tf .chart-grid { grid-template-columns:1fr; }
  .tf .chart-grid .wide { grid-column:auto; } }

/* ── Rank rows ────────────────────────────────────────────────────────────
   A leaderboard row: rank, name, proportional bar, figure. Narrower than the
   hiring monitor's mover-row because there is no ticker column — this data has
   no ticker mapping, only CUSIPs and filer-typed names. */
.tf .rank-row { display:grid; grid-template-columns:26px minmax(0,1fr) minmax(54px,.7fr) 74px 60px;
  align-items:center; gap:9px; min-height:30px; padding:2px 0;
  border-top:1px solid var(--line); min-width:0; }
.tf .rank-row:first-of-type { border-top:0; }
.tf .rank-n { color:var(--muted); font:650 10px/1 var(--mono); text-align:right; }
.tf .rank-name { overflow:hidden; min-width:0; font-size:11.5px; font-weight:600;
  text-overflow:ellipsis; white-space:nowrap; }
.tf .rank-name small { display:block; color:var(--muted); font:9px/1.2 var(--mono);
  font-weight:400; }
.tf .rank-val, .tf .rank-sub { text-align:right; font:650 10px/1 var(--mono);
  white-space:nowrap; }
.tf .rank-sub { color:var(--muted); }
.tf .bar.neutral { background:var(--accent); }
.tf .bar.warm { background:var(--caution); }

/* ── Split put/call meter ─────────────────────────────────────────────────
   One bar, two directions. Colour carries STATE (put vs call) and the numbers
   carry the magnitude, so the bar is never the only way to read the row. */
.tf .pc-track { display:flex; height:6px; border-radius:99px; overflow:hidden;
  background:var(--panel-2); }
.tf .pc-put { background:var(--negative); }
.tf .pc-call { background:var(--positive); }

/* ── "Needs the prior quarter" empty state ───────────────────────────────
   Change analysis is impossible with one period captured. The panel says which
   quarter is missing and what will fix it, rather than rendering blank. */
.tf .needs { padding:26px 20px; text-align:center; }
.tf .needs h3 { margin:0 0 6px; font-size:14px; }
.tf .needs p { margin:0 auto; max-width:560px; color:var(--muted); font-size:11.5px;
  line-height:1.5; }
.tf .needs code { padding:1px 5px; border-radius:4px; background:var(--panel-2);
  font:10px/1.4 var(--mono); }

/* ── The aperture: what a 13F can and cannot see ─────────────────────────
   Six paragraphs of "what a 13F does not contain" become six boundaries you
   can take in at once. The tiles are deliberately EQUAL in size: the excluded
   categories have unknown magnitude, and sizing them would invent a
   proportion the data cannot support. */
.tf .aperture { display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:8px; margin-top:4px; }
.tf .ap-core { grid-column:1/-1; padding:15px 16px; border-radius:10px;
  border:1px solid var(--shadow-rule); background:var(--shadow-band); }
.tf .ap-core b { display:block; font-size:13.5px; letter-spacing:-.01em; }
.tf .ap-core span { display:block; margin-top:3px; color:var(--muted);
  font-size:10.5px; }
.tf .ap-x { padding:11px 12px; border-radius:9px; border:1px dashed var(--line);
  background:var(--panel-2); min-width:0; }
.tf .ap-x b { display:block; font-size:11px; font-weight:700; }
.tf .ap-x span { display:block; margin-top:3px; color:var(--muted);
  font-size:9.5px; line-height:1.4; }
.tf .ap-stamp { display:inline-block; margin-bottom:5px; padding:1.5px 6px;
  border-radius:3px; background:var(--panel); border:1px solid var(--line);
  color:var(--muted); font:750 8px/1.4 var(--mono); letter-spacing:.08em;
  text-transform:uppercase; }
@media (max-width:640px) { .tf .aperture { grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* ── Lineage: how raw filings become the reported universe ───────────────
   A pipeline is a flow, so it is drawn as one. Each gate carries the count
   that passed it, which is what the prose was spending sentences on. */
.tf .lineage { display:flex; flex-wrap:wrap; align-items:stretch; gap:6px;
  margin-top:6px; }
.tf .ln-step { flex:1 1 128px; min-width:0; padding:10px 11px; border-radius:9px;
  border:1px solid var(--line); background:var(--panel-2); }
.tf .ln-step b { display:block; font:750 13px/1 var(--mono); letter-spacing:-.02em; }
.tf .ln-step span { display:block; margin-top:4px; color:var(--muted);
  font-size:9.5px; line-height:1.35; }
.tf .ln-arrow { align-self:center; color:var(--muted); font-size:13px; }
.tf .ln-step.drop { border-style:dashed; background:transparent; }
.tf .ln-step.drop b { color:var(--muted); }
@media (max-width:640px) { .tf .ln-arrow { display:none; }
  .tf .ln-step { flex:1 1 100%; } }

/* ── Matched-cohort funnel ───────────────────────────────────────────────
   The methodology paragraph above Changes was doing three jobs at once: which
   managers are compared, what is differenced, and what the result is not.
   Drawn as a funnel, all three are visible before any number is read. */
.tf .funnel { display:flex; flex-wrap:wrap; align-items:center; gap:8px;
  margin:2px 0 4px; }
.tf .fn-arm { display:flex; flex-direction:column; gap:5px; min-width:0; }
.tf .fn-box { padding:8px 11px; border-radius:8px; border:1px solid var(--line);
  background:var(--panel-2); min-width:0; }
.tf .fn-box b { display:block; font:750 13px/1 var(--mono); }
.tf .fn-box span { display:block; margin-top:3px; color:var(--muted);
  font-size:9.5px; }
.tf .fn-op { color:var(--muted); font:700 15px/1 var(--mono); }
.tf .fn-match { padding:11px 14px; border-radius:9px;
  border:1px solid var(--shadow-rule); background:var(--shadow-band); }
.tf .fn-match b { font-size:19px; letter-spacing:-.02em; }
.tf .fn-match span { color:var(--ink); opacity:.75; }
.tf .fn-rule { padding:7px 11px; border-radius:999px; border:1px dashed var(--line);
  color:var(--muted); font:650 10px/1.3 inherit; }
.tf .fn-out { display:flex; flex-wrap:wrap; gap:5px; }
.tf .fn-out span { padding:4px 9px; border-radius:999px; background:var(--panel-2);
  border:1px solid var(--line); font:650 10px/1.3 inherit; }
@media (max-width:640px) { .tf .fn-op { display:none; }
  .tf .funnel > * { flex:1 1 100%; } }

/* ── CUSIP anatomy ───────────────────────────────────────────────────────
   Why option rows are issuers rather than securities, shown rather than
   explained: three CUSIPs stacked with the shared issuer prefix highlighted. */
.tf .anat { display:inline-flex; flex-direction:column; gap:3px; margin:2px 0 10px;
  padding:10px 13px; border-radius:9px; background:var(--panel-2);
  border:1px solid var(--line); }
.tf .anat-row { display:flex; align-items:baseline; gap:10px;
  font:650 11.5px/1.5 var(--mono); }
.tf .anat-row i { font-style:normal; color:var(--muted); font-size:9.5px;
  min-width:38px; }
.tf .anat-pre { color:var(--shadow-ink); font-weight:800;
  border-bottom:2px solid var(--shadow-rule); }
.tf .anat-note { margin-top:5px; color:var(--muted); font-size:9.5px; }

/* ── Mirrored put/call bars ──────────────────────────────────────────────
   One symmetric dollar scale, puts left of the spine and calls right. Not a
   sentiment gauge and deliberately not coloured as one: these are disclosed
   notionals, and a 13F cannot say why a manager holds either leg. */
.tf .mirror { display:grid; grid-template-columns:minmax(96px,1.1fr) 1fr 1fr minmax(58px,auto);
  align-items:center; gap:4px 8px; }
.tf .mir-head { color:var(--muted); font:700 9px/1 var(--mono);
  letter-spacing:.07em; text-transform:uppercase; padding-bottom:4px; }
.tf .mir-head.r { text-align:right; }
.tf .mir-name { overflow:hidden; min-width:0; font-size:11px; font-weight:600;
  text-overflow:ellipsis; white-space:nowrap; }
.tf .mir-l, .tf .mir-r { height:13px; display:flex; }
.tf .mir-l { justify-content:flex-end; border-right:1px solid var(--line); }
.tf .mir-r { justify-content:flex-start; }
.tf .mir-bar { height:100%; border-radius:2px; }
.tf .mir-bar.put { background:var(--s1); border-radius:2px 0 0 2px; }
.tf .mir-bar.call { background:var(--s2); border-radius:0 2px 2px 0; }
.tf .mir-num { text-align:right; font:650 9.5px/1 var(--mono); color:var(--muted);
  white-space:nowrap; }

/* ── Bullet ranking ──────────────────────────────────────────────────────
   A ranked table of dollar figures asks the reader to compare numerals down a
   column. One common zero-based track turns that into looking at lengths. */
.tf .bullets { display:grid; grid-template-columns:20px minmax(120px,1.5fr) 1fr auto;
  align-items:center; gap:5px 10px; }
.tf .bl-rank { color:var(--muted); font:650 9.5px/1 var(--mono); text-align:right; }
.tf .bl-name { overflow:hidden; min-width:0; font-size:11.5px; font-weight:600;
  text-overflow:ellipsis; white-space:nowrap; }
.tf .bl-track { position:relative; height:13px; border-radius:2px;
  background:var(--panel-2); }
.tf .bl-fill { position:absolute; inset:0 auto 0 0; border-radius:2px;
  background:var(--ink); opacity:.72; }
.tf .bl-fill.lead { background:var(--shadow-ink); opacity:1; }
.tf .bl-val { text-align:right; font:650 10px/1 var(--mono); white-space:nowrap; }

/* ── Penetration units ───────────────────────────────────────────────────
   100 cells, one per percent of reporting managers. "Consensus" turns out to
   mean 80 of 100 cells filled for the very widest-held name, which a
   percentage in a table never conveys. */
.tf .pen { display:grid; grid-template-columns:20px minmax(120px,1.2fr) auto auto;
  align-items:center; gap:5px 10px; }
/* 25 x 4, not 50 x 2. At fifty columns each unit rendered about 2px wide and
   the strip read as texture — you could see a proportion but not count it,
   which defeats a unit chart. */
.tf .pen-strip { display:grid; grid-template-columns:repeat(25, 1fr);
  grid-auto-rows:6px; gap:2px; min-width:180px; }
.tf .pen-u { border-radius:1px; background:var(--panel-2); }
.tf .pen-u.on { background:var(--s1); }
.tf .pen-u.part { background:linear-gradient(90deg,var(--s1) 50%,var(--panel-2) 50%); }
.tf .pen-val { text-align:right; font:650 10px/1 var(--mono); white-space:nowrap; }
.tf .pen-val small { display:block; color:var(--muted); font-size:8.5px;
  font-weight:400; }

/* ── Heat strip / heatmap ────────────────────────────────────────────────*/
.tf .heat { display:grid; align-items:center; gap:2px 8px; }
.tf .heat-name { overflow:hidden; min-width:0; font-size:10.5px; font-weight:600;
  text-overflow:ellipsis; white-space:nowrap; }
.tf .heat-cells { display:grid; gap:2px; }
.tf .heat-c { height:17px; border-radius:2px; background:var(--panel-2); }
.tf .heat-hd { color:var(--muted); font:650 8px/1 var(--mono); text-align:center;
  white-space:nowrap; overflow:hidden; }
.tf .heat-key { display:flex; align-items:center; gap:8px; margin-top:9px;
  color:var(--muted); font-size:9.5px; }
.tf .heat-ramp { display:flex; height:9px; border-radius:2px; overflow:hidden;
  width:150px; }
.tf .heat-ramp i { flex:1; }

/* ── Quarter cards: scale and concentration together ─────────────────────
   Replaces two conventional line charts. Each card is one quarter: a bar for
   the size of the disclosed universe, and a 100-square waffle beneath showing
   how that capital was distributed. The two are stacked, not sharing an axis. */
.tf .qcards { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr);
  gap:6px; align-items:end; }
.tf .qc { min-width:0; display:flex; flex-direction:column; gap:5px; }
.tf .qc-barwrap { height:88px; display:flex; align-items:flex-end; }
.tf .qc-bar { width:100%; border-radius:2px 2px 0 0; background:var(--ink);
  opacity:.7; }
.tf .qc.latest .qc-bar { background:var(--shadow-ink); opacity:1; }
.tf .qc-waffle { display:grid; grid-template-columns:repeat(10,1fr);
  grid-auto-rows:1fr; gap:1px; aspect-ratio:1; }
.tf .qc-w { border-radius:.5px; background:var(--panel-2); }
/* Four tonal steps of ONE hue, not four categorical colours — these are
   nested slices of a single quantity, so they are ordered, not distinct. */
.tf { --w1:#1b3a63; --w2:#3a6ea5; --w3:#7aa7d0; --w4:#bcd4e8; }
@media (prefers-color-scheme:dark) {
  :root:where(:not([data-theme="light"])) .tf {
    --w1:#cfe3f7; --w2:#8fb6df; --w3:#5b83ad; --w4:#37536f; }
}
:root[data-theme="dark"] .tf {
  --w1:#cfe3f7; --w2:#8fb6df; --w3:#5b83ad; --w4:#37536f; }
:root[data-theme="light"] .tf {
  --w1:#1b3a63; --w2:#3a6ea5; --w3:#7aa7d0; --w4:#bcd4e8; }
.tf .qc-w.t1 { background:var(--w1); }
.tf .qc-w.t2 { background:var(--w2); }
.tf .qc-w.t3 { background:var(--w3); }
.tf .qc-w.t4 { background:var(--w4); }
.tf .qc-lab { color:var(--muted); font:600 8.5px/1 var(--mono); text-align:center;
  overflow:hidden; white-space:nowrap; }
.tf .qc-val { font:700 9px/1 var(--mono); text-align:center; color:var(--ink); }
.tf .qc-val.dim { color:transparent; }
.tf .wkey { display:flex; flex-wrap:wrap; gap:4px 12px; margin-top:9px;
  color:var(--muted); font-size:9.5px; }
.tf .wkey b { display:inline-flex; align-items:center; gap:5px; font-weight:600;
  color:var(--ink); }
.tf .wkey b::before { content:""; width:9px; height:9px; border-radius:2px; }
.tf .wk1::before { background:var(--w1); }
.tf .wk2::before { background:var(--w2); }
.tf .wk3::before { background:var(--w3); }
.tf .wk4::before { background:var(--w4); }
.tf .wk5::before { background:var(--panel-2); box-shadow:inset 0 0 0 1px var(--line); }
@media (max-width:900px) { .tf .qcards { grid-auto-flow:row;
  grid-template-columns:repeat(7,minmax(0,1fr)); grid-auto-rows:auto; }
  .tf .qc-barwrap { height:52px; } }

/* ── Paired-dot divergence timeline ──────────────────────────────────────
   The headline figure. Per quarter: one mark for disclosed shares, one for
   price, a hairline joining them. The GAP is the whole story, so quarters are
   deliberately NOT connected by trend lines — that would suggest continuous
   movement between four observations a year. */
.tf .pairs { position:relative; }
.tf .pairs svg { display:block; width:100%; height:auto; overflow:visible; }
.tf .pr-join { stroke:var(--axis); stroke-width:1; vector-effect:non-scaling-stroke; }
.tf .pr-share { fill:var(--s1); }
.tf .pr-price { fill:none; stroke:var(--s2); stroke-width:2;
  vector-effect:non-scaling-stroke; }
.tf .pr-note { font:650 9px/1 Inter,ui-sans-serif,system-ui,sans-serif;
  fill:var(--shadow-ink); }
.tf .pr-lead { stroke:var(--shadow-rule); stroke-width:1; stroke-dasharray:2 2;
  vector-effect:non-scaling-stroke; }

/* ── Capital vs headcount ────────────────────────────────────────────────
   The single most load-bearing fact about this dataset: 45 filers of 6,245
   hold 70% of the money. Two bars per band on ONE shared 0–100% scale, so the
   inversion is the shape of the figure rather than a sentence about it. */
.tf .asym { display:grid; grid-template-columns:minmax(74px,auto) 1fr;
  gap:9px 12px; align-items:center; }
.tf .asym-band { font-size:11.5px; font-weight:700; white-space:nowrap; }
.tf .asym-band small { display:block; color:var(--muted); font-weight:400;
  font-size:9.5px; }
.tf .asym-pair { display:grid; gap:3px; min-width:0; }
.tf .asym-row { display:grid; grid-template-columns:52px 1fr 62px;
  align-items:center; gap:8px; }
.tf .asym-lab { color:var(--muted); font:650 8.5px/1 var(--mono);
  letter-spacing:.05em; text-transform:uppercase; text-align:right; }
.tf .asym-track { height:11px; border-radius:2px; background:var(--panel-2); }
.tf .asym-fill { height:100%; border-radius:2px; }
.tf .asym-fill.funds { background:var(--muted); }
.tf .asym-fill.cap { background:var(--shadow-ink); }
.tf .asym-num { font:700 10px/1 var(--mono); white-space:nowrap; }

/* ── Coverage strip ──────────────────────────────────────────────────────*/
.tf .cov-row { display:grid; grid-template-columns:minmax(0,1fr) 70px 78px 84px;
  align-items:center; gap:8px; padding:6px 0; border-top:1px solid var(--line);
  font-size:11px; }
.tf .cov-row.head { border-top:0; color:var(--muted); font-size:9px;
  letter-spacing:.03em; text-transform:uppercase; }
.tf .cov-row .num { text-align:right; font:650 10px/1 var(--mono); }
.tf .cov-current { font-weight:750; color:var(--accent); }

/* Definition rows in the caveats panel. */
.tf .caveat-list { margin:0; padding:0; list-style:none; }
.tf .caveat-list li { padding:9px 0; border-top:1px solid var(--line); font-size:11.5px;
  line-height:1.5; }
.tf .caveat-list li:first-child { border-top:0; }
.tf .caveat-list b { display:block; margin-bottom:2px; }
.tf .caveat-list span { color:var(--muted); }

@media (max-width:640px) {
  .tf .rank-row { grid-template-columns:22px minmax(0,1fr) 68px 56px; }
  .tf .rank-row .bar-track { display:none; }
  .tf .cov-row { grid-template-columns:minmax(0,1fr) 56px 64px; }
  .tf .cov-row .cov-hr { display:none; }
  .tf .asof { flex-direction:column; gap:8px; }
}
