/* Data-driven view styles: regime + swarm. Reuses the design tokens. */
.rv, .cv { padding: 9rem 1.5rem 6rem; }
/* eyebrow, loading and error are promoted to components.css (.rm-eyebrow /
   .rm-loading / .rm-error, grouped with the rv and cv titles, single source). */
.rv__title, .sv__title { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 2.5rem; letter-spacing: -0.01em; line-height: 1.05; margin: 0.5rem 0; }
@media (min-width: 768px) { .rv__title, .sv__title { font-size: 3.25rem; } }
@media (min-width: 1024px) { .rv__title, .sv__title { font-size: 3.75rem; } }
.rv__sub, .sv__sub { color: var(--color-text-muted); font-family: var(--font-sans); font-size: 0.85rem; }

/* regime pills (shared: summary meta + panel headers) */
.regime-pill {
  display: inline-block; padding: 0.15rem 0.6rem; border-radius: var(--radius-pill);
  font-family: var(--font-mono); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em;
  border: 1px solid var(--color-border); width: fit-content;
}
.regime-pill--risk_on { color: var(--color-accent); border-color: rgba(0, 229, 255, 0.4); background: rgba(0, 229, 255, 0.08); }
.regime-pill--neutral { color: var(--color-warm); border-color: rgba(232, 166, 64, 0.4); background: rgba(232, 166, 64, 0.08); }
.regime-pill--risk_off { color: var(--color-warn); border-color: rgba(255, 102, 68, 0.4); background: rgba(255, 102, 68, 0.08); }

/* ── Regime dashboard (rv--dash) ─────────────────────────────────────────── */
.rv--dash { padding: 0 0 5rem; }
/* .rv__eyebrow--accent promoted to components.css (.rm-eyebrow--accent). */

/* hero (OrbitsCanvas background + void gradient fades, from regime/page.tsx) */
.rv__hero {
  position: relative; min-height: 52vh; display: flex; align-items: center; overflow: hidden;
  border-bottom: 1px solid var(--color-border); background: var(--color-void);
}
.rv__hero-art { position: absolute; inset: 0; z-index: 0; background: rgb(5, 5, 8); }
.rv__hero-art canvas { width: 100%; height: 100%; display: block; }
.rv__hero-fade { position: absolute; left: 0; right: 0; z-index: 1; pointer-events: none; }
.rv__hero-fade--top { top: 0; bottom: 0; background: linear-gradient(to bottom, rgba(6, 8, 12, 0.6), transparent 40%, var(--color-void)); }
.rv__hero-fade--bottom { bottom: 0; height: 120px; background: linear-gradient(to top, var(--color-void), transparent); }
.rv__hero-inner { position: relative; z-index: 2; width: 100%; max-width: 80rem; margin-inline: auto; padding: 2.5rem 1.5rem; }
.rv__hero .rv__title {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(2.4rem, 5vw, 3.6rem); letter-spacing: -0.01em; margin: 0.5rem 0 0;
}
.rv__hero .rv__title .text-gradient { font-family: var(--font-display); font-weight: 700; background: none; -webkit-text-fill-color: currentColor; color: inherit; }
.rv__hero-sub { color: var(--color-text-muted); margin: 1rem 0 0; max-width: 42rem; line-height: 1.6; }

/* body + dashboard layout. max-w-7xl (1280px) + px-6 lg:px-8 — the dashboard
   reference is captured at 1440 (lg active) so the content column is 1280−2×2rem
   = 1216px; the history/backtest canvases must render at that width to line up. */
.rv__body { max-width: 1280px; margin: 0 auto; padding: 2.2rem 1.5rem 0; }
@media (min-width: 1024px) { .rv__body { padding-left: 2rem; padding-right: 2rem; } }
.rv__dash { display: flex; flex-direction: column; gap: 1.1rem; }
/* section head/title/as-of promoted to components.css
   (.rm-section-head / .rm-section-title / .rm-asof). */

/* summary cards — grid + card shell + card-eyebrow/val/foot promoted to
   components.css (.rm-cards / .rm-card / .rm-card-eyebrow / .rm-card-val /
   .rm-card-foot). Regime-only card variants stay here. */
.rv__card--regime { background: transparent; }
.rv__card-regime { font-size: 1.9rem; font-weight: 500; margin-top: 0.35rem; }
.rv__posbar { position: relative; height: 6px; background: var(--color-border); border-radius: var(--radius); overflow: hidden; margin-top: 0.85rem; }
.rv__posbar-fill { height: 100%; background: var(--color-accent); border-radius: var(--radius); }
.rv__posbar-tick { position: absolute; top: 0; bottom: 0; width: 1px; left: 50%; background: var(--color-text-dim); }
.rv__posbar-labels { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 10px; color: var(--color-text-dim); margin-top: 0.25rem; }

/* full-history chart card — shell + head + title-group + title + chart +
   chips + legend promoted to components.css (.rm-chartcard / .rm-chartcard-head
   / .rm-chartcard-title-group / .rm-chartcard-title / .rm-chart / .rm-chips /
   .rm-chip / .rm-legend / .rm-legend-item / .rm-legend-swatch). */

/* panel + generic tables */
.rv__panels { display: grid; grid-template-columns: 1fr; gap: 1.25rem; }
.rv__panel-card, .rv__corr-card, .rv__bt-card { border: 1px solid var(--color-border); border-radius: var(--radius); overflow: hidden; }
.rv__panel-card-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; padding: 0.72rem 1rem; border-bottom: 1px solid var(--color-border); background: rgba(16, 20, 28, 0.4); }
.rv__panel-card-title { font-size: 0.9rem; font-weight: 500; margin: 0; }
.rv__panel-card-meta { font-family: var(--font-mono); font-size: 10px; color: var(--color-text-dim); }
/* table shell + cells (.rm-table-scroll / .rm-table / .rm-num / .rm-muted)
   promoted to components.css; regime-only cell styles stay below. */
.rv__ind-cell { display: flex; flex-direction: column; gap: 0.1rem; }
.rv__ind-name {
  font-size: 0.85rem; color: var(--color-text); cursor: help;
  text-decoration: underline; text-decoration-style: dotted;
  text-decoration-color: var(--color-text-dim); text-underline-offset: 4px;
}
.rv__ind-name--plain { text-decoration: none; cursor: default; }
/* name + info-icon + hover tooltip wrapper (source PanelTable "group") */
.rv__ind-tipwrap { position: relative; display: inline; }
.rv__ind-info { margin-left: 0.35rem; display: inline-block; color: var(--color-text-dim); vertical-align: baseline; transition: color 0.15s; }
.rv__ind-info:hover { color: var(--color-accent); }
.rv__ind-info svg { display: inline-block; vertical-align: baseline; }
.rv__tip {
  pointer-events: none; position: absolute; left: 0; top: 100%; z-index: 20;
  margin-top: 0.5rem; width: 18rem; border-radius: var(--radius);
  border: 1px solid var(--color-border); background: var(--color-surface);
  padding: 0.75rem; font-family: var(--font-mono); font-size: 11px; line-height: 1.6;
  color: var(--color-text-muted);
  opacity: 0; transition: opacity 0.15s;
}
.rv__ind-tipwrap:hover .rv__tip { opacity: 1; }
.rv__ind-src { font-family: var(--font-mono); font-size: 10px; color: var(--color-text-dim); margin-top: 0.15rem; }
.rv__ind-src a { color: var(--color-text-dim); text-decoration: none; }
.rv__ind-src a:hover { color: var(--color-accent); }
.rv__spark { width: 90px; }
.rv__spark-svg { display: block; }
.rv__spark-empty { font-family: var(--font-mono); font-size: 10px; color: var(--color-text-dim); }

/* backtest cards */
.rv__bt-weights { display: flex; flex-wrap: wrap; gap: 0.8rem; padding: 0.6rem 1rem; font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.15em; color: var(--color-text-muted); }
.rv__bt-weight { display: flex; align-items: center; gap: 0.4rem; }
.rv__pie-wrap { display: inline-flex; }
.rv__pie { display: block; }
.rv__bt-baseline td { background: rgba(16, 20, 28, 0.35); }
.rv__bt-chart-wrap { padding: 0.75rem 1rem; border-top: 1px solid var(--color-border); }
.rv__bt-chart-label { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.3em; color: var(--color-text-muted); margin-bottom: 0.75rem; }
.rv__bt-chart { height: 320px; }

/* card foot note (.rm-foot) promoted to components.css. */

/* component methodology footer (bucket thresholds) */
.rv__component-foot { padding-top: 0.4rem; border-top: 1px solid var(--color-border); font-family: var(--font-mono); font-size: 11px; line-height: 1.6; color: var(--color-text-dim); }
.rv__component-foot p { margin: 0; }

/* page-level methodology */
.rv__method-wrap { margin-top: 3rem; }
.rv__method-hr { border: 0; border-top: 1px solid var(--color-border); margin: 0 0 3rem; }
.rv__method-wrap .rv__eyebrow { display: block; margin-bottom: 0.75rem; }
.rv__method { display: flex; flex-direction: column; gap: 1.1rem; margin-top: 1.1rem; }
.rv__method-card { background: rgba(16, 20, 28, 0.6); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1.5rem; }
.rv__method-title { font-family: var(--font-mono); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.2em; color: var(--color-accent); margin: 0 0 0.75rem; }
.rv__method-list { color: var(--color-text-muted); font-size: 0.85rem; line-height: 1.6; margin: 0; padding-left: 1.25rem; }
.rv__method-list li { margin-bottom: 0.25rem; }
.rv__method-card p { color: var(--color-text-muted); font-size: 0.85rem; line-height: 1.6; margin: 0; }
.rv__method-note { color: var(--color-text-muted); font-size: 0.85rem; line-height: 1.6; margin: 1rem 0 0; }
.rv__link { color: var(--color-accent); text-decoration: underline; }

/* swarm — each .sv__* selector is declared in EXACTLY ONE block per media
   context (base props for several classes live in the port section below).
   Duplicate same-selector blocks silently override each other and caused the
   #80 regression twice; enforced by scripts/tests/css-duplicate-selectors.test.ts. */
.sv__hero-fade { position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(6,8,12,0.25), rgba(6,8,12,0.72) 70%, var(--color-void)); pointer-events: none; }
.sv__hero .sv__detail-title .text-gradient { font-family: var(--font-display); font-weight: 700; background: none; -webkit-text-fill-color: currentColor; color: inherit; }
.sv__feed-title { margin: 0 0 0.6rem; font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: -0.01em; font-size: 1.8rem; }
.sv__back:hover { color: var(--color-accent); }
/* Backdrop chip: ONE border, a dim label and a bright value. The rule this
   replaces was `.sv__fact-row span`, which also matched the value <span>
   nested inside each chip and drew it a second box whose right edge landed on
   the chip's own — the doubled frame that read as broken. */
.sv__fact { display: inline-flex; align-items: center; gap: 0.45rem;
  border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.34rem 0.6rem; }
.sv__fact em { font-style: normal; color: var(--color-text-dim); }
.sv__fact b { font-weight: 500; color: var(--color-text); letter-spacing: 0.1em; font-variant-numeric: tabular-nums; }
/* Form carries the category, hue carries the value. Across the swarm tree a
   ROUND dot means a reading (stance, verdict, regime) and a SQUARE one means an
   identity (which subject this is). Regime is a reading, so this is a circle
   sized to the stance dots — it shipped square, which quietly filed it with the
   subject marks instead. */
.sv__fact-dot { width: 0.42rem; height: 0.42rem; flex: 0 0 auto; border-radius: 50%; margin-right: -0.12rem; }
.sv__bar { margin: 0.6rem 0 1rem; }
.sv__action-row span { color: var(--color-text); }
.sv__avatar--large { width: 4.5rem; height: 4.5rem; font-size: 1.4rem; flex: 0 0 auto; }
.sv__member-hero { display: flex; gap: 1.25rem; align-items: center; }
.sv__metadata-grid { display: grid; grid-template-columns: 1fr; gap: 0.8rem; }
.sv__metadata-grid div { border-top: 1px solid var(--color-border); padding-top: 0.65rem; }
.sv__metadata-grid span { display: block; color: var(--color-text-dim); font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.14em; }
.sv__metadata-grid b { display: block; margin-top: 0.25rem; color: var(--color-text); font-family: var(--font-mono); font-size: 12px; font-weight: 500; overflow-wrap: anywhere; }
/* Swarm verdict. Replaces the .sv__aggregate box whose largest element was
   "3/5" — turnout, not a finding. The call leads, the proportional bar shows
   the weight behind it, and the procedural numbers (quorum, mean confidence,
   who was absent) drop to a footer where they belong. */
.sv__verdict { margin: 0.6rem 0 0; }
.sv__verdict-call { display: flex; align-items: center; gap: 0.6rem; margin: 0;
  font-family: var(--font-display, var(--font-mono)); font-size: 1.55rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.01em; color: var(--color-text); }
.sv__verdict-call i { width: 0.55rem; height: 0.55rem; flex: 0 0 auto; border-radius: 50%; }
/* A split is a real result, but it is not a call — it reads muted so it can
   never be mistaken for the swarm endorsing a position. */
.sv__verdict-call.is-split { font-size: 1.25rem; color: var(--color-text-muted); }
.sv__verdict-detail { margin: 0.4rem 0 0; color: var(--color-text-muted); font-size: 0.86rem; line-height: 1.6; }
.sv__verdict-bar { display: flex; gap: 2px; height: 6px; margin: 1rem 0 0.75rem; }
.sv__verdict-bar i { display: block; height: 100%; min-width: 2px; }
.sv__stances { display: flex; flex-wrap: wrap; gap: 0.9rem; font-family: var(--font-mono); font-size: 0.74rem; color: var(--color-text-muted); }
.sv__verdict-meta { display: flex; flex-wrap: wrap; gap: 1.75rem; margin: 1.25rem 0 0;
  padding-top: 0.9rem; border-top: 1px solid var(--color-border); }
.sv__verdict-meta div { min-width: 0; }
.sv__verdict-meta dt { font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.16em; color: var(--color-text-dim); }
.sv__verdict-meta dd { margin: 0.3rem 0 0; font-family: var(--font-mono); font-size: 0.78rem; color: var(--color-text-muted); overflow-wrap: anywhere; }

.sv__takes { display: flex; flex-direction: column; gap: 1rem; }
.sv__take { position: relative; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1.25rem; --vfy-inset: 1.25rem; }
.sv__take-head { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-bottom: 0.5rem; padding-right: 1.6rem; }
.sv__member { font-weight: 700; }
.sv__conf { font-family: var(--font-mono); font-size: 0.75rem; color: var(--color-text-muted); }
/* ── Subject encoding + filter ───────────────────────────────────────────────
   Shared by the member profile's track record and the /swarm roster. Both
   lists interleave several subjects by date, so both need the same answer to
   "which subject is this row", and two surfaces must never teach two
   conventions for the same data. Lives here rather than in either page's
   scoped <style> for exactly that reason. */
.mp-filter { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 1rem; }
.mp-chip { display: inline-flex; align-items: center; gap: 0.42rem; min-height: 34px;
  padding: 0.3rem 0.62rem; background: transparent; color: var(--color-text-muted);
  border: 1px solid var(--color-border); border-radius: var(--radius);
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.06em; cursor: pointer;
  transition: color .16s ease, border-color .16s ease, background .16s ease; }
.mp-chip:hover { color: var(--color-text); border-color: var(--color-text-dim); }
/* Selected: a filled plane edged in cyan. Cyan is the house interface line by
   covenant, so it says "this control is active" without competing with the dot,
   which says "which subject" — two jobs, two roles, no ambiguity. The × makes
   it obvious the filter clears by clicking again. */
.mp-chip.is-on { color: var(--color-text); border-color: var(--color-accent); background: var(--color-surface); }
.mp-chip__x { color: var(--color-accent); font-size: 0.78rem; line-height: 1; margin-left: 0.05rem; }
.mp-chip__dot { width: 7px; height: 7px; flex: 0 0 auto; }
.mp-chip__n { font-variant-numeric: tabular-nums; color: var(--color-text-dim); }
.mp-chip.is-on .mp-chip__n { color: var(--color-text-muted); }
.mp-chip:focus-visible { outline: 1px solid var(--color-accent); outline-offset: 2px; }

/* A row carries its subject's hue on the left edge, so which session it belongs
   to is legible before you read a word of it — and it groups a filtered list.
   .sv__session-card sets a 1px border on all sides and repaints all four cyan
   on hover, so the rail is re-asserted there; otherwise pointing at a card
   would silently reassign it to another subject. The padding gives back the
   extra pixel so copy stays aligned with cards that have no rail.

   The selector is doubled (.sv__session-card.mp-take) on purpose:
   .sv__session-card is declared later in this file and its shorthand `border`
   would otherwise win on source order alone. Specificity makes the rail
   independent of where this block sits. */
.sv__session-card.mp-take { border-left: 2px solid var(--mp-subject, var(--color-border));
  padding-left: calc(1.15rem - 1px); }
.sv__session-card.mp-take:hover { border-left-color: var(--mp-subject, var(--color-border)); }
.mp-take__dot { width: 7px; height: 7px; flex: 0 0 auto; align-self: center;
  background: var(--mp-subject, var(--color-border)); }

/* Verification badge. "Verified" is the single most load-bearing word on the
   swarm — it is the difference between a signed record and an assertion —
   and it was shipping as bare text most readers would skim past. Now a mark
   plus a plain-language line on hover or keyboard focus.
   The full sentence also rides on aria-label, so assistive tech gets the
   explanation without depending on a hover-only tooltip. */
.sv__vfy { position: relative; display: inline-flex; align-items: center; gap: 0.34rem;
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em;
  color: var(--color-accent); cursor: help; }
.sv__vfy--bad { color: var(--color-warn); }
/* Archived is not a failure — it is the absence of a claim either way, so it
   takes the muted neutral rather than borrowing the accent (a pass it did not
   earn) or the warn colour (a failure that never happened). */
.sv__vfy--arch { color: var(--color-text-muted); }
.sv__vfy-mark { width: 13px; height: 13px; flex: 0 0 auto; display: block; }
.sv__vfy-tip { position: absolute; right: 0; bottom: calc(100% + 9px); z-index: 30;
  width: max-content; max-width: min(272px, 72vw); padding: 0.55rem 0.65rem;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-top: 1px solid currentColor; border-radius: var(--radius);
  font-family: var(--font-sans, system-ui, sans-serif); font-size: 0.72rem; line-height: 1.5;
  letter-spacing: 0; text-transform: none; color: var(--color-text-muted); text-align: left;
  opacity: 0; visibility: hidden; transform: translateY(3px); pointer-events: none;
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s; }
.sv__vfy:hover .sv__vfy-tip, .sv__vfy:focus-visible .sv__vfy-tip {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.sv__vfy:focus-visible { outline: 1px solid currentColor; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .sv__vfy-tip { transition: none; } }
/* The seal is icon-only and pinned to its card's top-right corner in every
   context. A badge that trails a variable-width stance chip lands at a
   different x on every row, so a reader has to hunt for it; pinned, the marks
   form one column down the right edge and a page of takes scans in a single
   pass. The word it used to carry lives in the tooltip and the aria-label —
   which is why the tooltip was added. --vfy-inset matches the host's padding
   so the mark sits on the card's own content edge; the negative offset is the
   badge's own padding, which grows the pointer target without moving it. */
.sv__vfy--pin { position: absolute; z-index: 2; padding: 0.34rem;
  top: calc(var(--vfy-inset, 1.15rem) - 0.34rem); right: calc(var(--vfy-inset, 1.15rem) - 0.34rem); }
/* Pinned at the top edge, the tip opens DOWNWARD: above, it would cover the
   card before it, or leave the viewport entirely on the first row. The seam
   stays on the tip's top edge, still the side facing the mark. */
.sv__vfy--pin .sv__vfy-tip { top: calc(100% + 7px); bottom: auto; transform: translateY(-3px); }
/* A failure state must not depend on a hover. A bare ✕ reads as decoration
   until you interrogate it, and hover does not exist on touch — so the mark
   meaning "this signature did not check out" says so in words, while the
   ordinary verified case stays a silent glyph. Labelling ONLY the exception is
   what makes it findable: if every row said "verified", the one row that did
   not would be harder to spot, not easier. */
.sv__vfy-label { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.08em; white-space: nowrap; }
/* The pinned badge grows leftward out of the corner when it carries the word,
   so the row under it needs a wider gutter — but only on the cards that fail. */
.sv__take:has(.sv__vfy--bad) .sv__take-head,
.sv__take:has(.sv__vfy--bad) .sv__receipt-status,
.sv__session-card:has(.sv__vfy--bad) .sv__receipt-status,
.sv__take:has(.sv__vfy--arch) .sv__take-head,
.sv__take:has(.sv__vfy--arch) .sv__receipt-status,
.sv__session-card:has(.sv__vfy--arch) .sv__receipt-status { padding-right: 7.5rem; }
/* Gutters reserving the pinned corner, so the row that ends nearest it never
   runs underneath the mark. */
.sv__receipt-status { display: flex; align-items: center; gap: 0.65rem; flex-wrap: wrap; padding-right: 1.6rem; }
.sv__fingerprint { overflow-wrap: anywhere; }
.stance { font-family: var(--font-mono); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.1em; padding: 0.2rem 0.6rem; border-radius: var(--radius); }
.stance--bullish { color: var(--color-accent); background: rgba(0,229,255,0.1); }
.stance--constructive { color: var(--color-green); background: rgba(16,185,129,0.1); }
.stance--neutral { color: var(--color-text-muted); background: rgba(255,255,255,0.05); }
.stance--cautious { color: var(--color-warm); background: rgba(232,166,64,0.1); }
.stance--bearish { color: var(--color-warn); background: rgba(255,102,68,0.1); }

/* swarm port: feed, member detail, session detail */
.cv--feed, .cv--detail { padding: 0; }
.sv__hero { position: relative; min-height: 52vh; display: flex; align-items: center; overflow: hidden; border-bottom: 1px solid var(--color-border); background: var(--color-void); }
.sv__hero::after { content: ""; position: absolute; inset: auto 0 0; height: 110px; background: linear-gradient(to top, var(--color-void), transparent); pointer-events: none; z-index: 1; }
.sv__hero-inner { position: relative; z-index: 2; width: min(100%, 80rem); margin: 0 auto; padding: 2.5rem 1.5rem; }
.sv__hero-field { position: absolute; inset: 0; }
.sv__hero-field canvas { width: 100% !important; height: 100% !important; }
.sv__body { width: min(100%, 80rem); margin: 0 auto; padding: 3rem 1.5rem 5rem; }
.sv__body--narrow { width: min(100%, 54rem); padding-top: 8rem; }
.sv__lede { max-width: 44rem; margin: 0.75rem 0 0; color: var(--color-text-muted); font-size: 1.05rem; line-height: 1.7; }
.sv__lede--compact { font-size: 0.95rem; max-width: 42rem; }
.sv__rail-grid { display: grid; gap: 1.5rem; margin-bottom: 4rem; }
.sv__rail-grid--compact { margin: 0 0 2rem; }
.sv__panel { border: 1px solid var(--color-border); padding: 1.25rem; background: rgba(255,255,255,0.015); }
.sv__panel-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.sv__panel-label { margin: 0; font-family: var(--font-mono); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.16em; color: var(--color-text-muted); }
.sv__back { display: inline-block; margin-bottom: 2rem; }
.sv__panel-link, .sv__back, .sv__memo-link { font-family: var(--font-mono); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-accent); text-decoration: none; }
.sv__panel-link:hover, .sv__back:hover, .sv__memo-link:hover { text-decoration: underline; }
.sv__list { list-style: none; padding: 0; margin: 0; display: grid; gap: 1rem; }
.sv__person-row, .sv__subject-row { display: flex; align-items: flex-start; gap: 0.8rem; min-width: 0; }
.sv__avatar, .sv__subject-mark { width: 2.5rem; height: 2.5rem; flex: 0 0 auto; display: grid; place-items: center; border: 1px solid var(--color-border); font-family: var(--font-mono); font-size: 0.78rem; font-weight: 700; text-decoration: none; }
/* Identity mark: a square plane, not a disc — the covenant is flat planes and
   radius <= 2px. Beam cyan is a LINE, so it seams the top edge rather than
   filling the plane, and the monogram stays neutral: cyan is never a figure. */
.sv__avatar { justify-content: center; border-radius: var(--radius); background: var(--color-surface);
  color: var(--color-text); border-top: 1px solid var(--color-accent); letter-spacing: 0.06em; }
.sv__avatar--xl { width: 5rem; height: 5rem; font-size: 1.35rem; border-top-width: 2px; }
/* Derived identity mark (#560): the SVG fills the plane the monogram used to
   sit inside, so the box keeps its border and cyan top seam and loses only its
   centred letters. The mark's own palette excludes cyan for the reason stated
   above — cyan is a line here, never a figure. */
.sv__avatar--mark { overflow: hidden; padding: 0; }
.sv__avatar--mark > .sv__mark-svg { display: block; width: 100%; height: 100%; }
.sv__subject-mark { border-radius: var(--radius); color: var(--color-green); background: rgba(16,185,129,0.08); }
.sv__row-main { min-width: 0; flex: 1; }
.sv__row-titleline, .sv__session-titleline { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.65rem; min-width: 0; }
.sv__row-title { color: var(--color-text); font-weight: 700; text-decoration: none; }
.sv__row-title:hover, .sv__member-link:hover { color: var(--color-accent); }
.sv__tag { display: inline-flex; align-items: center; border: 1px solid var(--color-border); padding: 0.12rem 0.38rem; font-family: var(--font-mono); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text-dim); }
.sv__row-copy, .sv__session-copy, .sv__body-copy { margin: 0.35rem 0 0; color: var(--color-text-muted); line-height: 1.6; font-size: 0.84rem; }
.sv__mini-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.45rem; }
.sv__mini-tags span { background: rgba(255,255,255,0.04); color: var(--color-text-dim); font-family: var(--font-mono); font-size: 0.58rem; padding: 0.15rem 0.38rem; }
.sv__sessions-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin: 0 0 1rem; }
.sv__session-count, .sv__date, .sv__session-meta { font-family: var(--font-mono); font-size: 0.74rem; color: var(--color-text-dim); }
.sv__session-list { display: grid; gap: 0.75rem; }
.sv__session-list--compact { gap: 0.55rem; }
.sv__session-card { position: relative; display: block; border: 1px solid var(--color-border); padding: 1.15rem; color: inherit; text-decoration: none; transition: border-color 0.16s ease, background 0.16s ease; }
.sv__session-card:hover { border-color: var(--color-accent); background: rgba(0,229,255,0.035); }
.sv__session-top { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.sv__session-title { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: -0.01em; font-size: 1.08rem; color: var(--color-text); }
.sv__session-meta { display: flex; flex-wrap: wrap; gap: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; }
.sv__stance-line { display: flex; flex-wrap: wrap; gap: 0.55rem 0.8rem; margin: 0.65rem 0 0; }
.sv__stance-dotline { display: inline-flex; align-items: center; gap: 0.32rem; font-family: var(--font-mono); font-size: 0.66rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.08em; }
/* .sv__dis-stance was rendering its dot at 0x0: the stance spread added to the
   Disagreements panel reused the badge markup but not the badge class, so it
   never picked up a size. An invisible dot is worse than none, because the
   colour is the only thing distinguishing two members' positions there. */
.sv__stance-dotline i, .sv__stance-chip i, .sv__stance-badge i, .sv__dis-stance i { width: 0.42rem; height: 0.42rem; border-radius: 50%; display: inline-block; }
.sv__profile-head { display: flex; align-items: flex-start; gap: 1.25rem; flex-wrap: wrap; margin: 1.5rem 0 2.5rem; }
.sv__profile-main { flex: 1; min-width: 16rem; }
.sv__detail-head { margin: 1.5rem 0 2.5rem; }
.sv__detail-title { margin: 0.35rem 0 0; font-family: var(--font-display); text-transform: uppercase; font-size: clamp(2.2rem, 5vw, 3.6rem); line-height: 1.08; font-weight: 700; letter-spacing: -0.01em; }
.sv__fact-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.15rem; font-family: var(--font-mono); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text-dim); }
.sv__meta-grid { display: grid; grid-template-columns: max-content 1fr; gap: 0.45rem 1.4rem; margin: 0.9rem 0 0; font-family: var(--font-mono); font-size: 0.78rem; }
.sv__meta-grid dt { color: var(--color-text-muted); }
.sv__meta-grid dd { margin: 0; color: var(--color-text); overflow-wrap: anywhere; }
/* The signer's name was falling through to the browser's default link colours
   — a purple :visited link on the receipt, off the palette entirely. */
.sv__meta-grid dd a { color: var(--color-accent); text-decoration: none; }
.sv__meta-grid dd a:hover { text-decoration: underline; }
.sv__bullet-list { margin: 0.8rem 0 0; padding: 0; list-style: none; display: grid; gap: 0.35rem; }
.sv__bullet-list li { color: var(--color-text-muted); font-size: 0.88rem; }
.sv__bullet-list li::before { content: "· "; color: var(--color-text-dim); }
.sv__discussion { display: grid; grid-template-columns: 1fr; gap: 1rem; margin: 1.5rem 0 2rem; }
/* Market backdrop. One panel, not two: the old "Brief" half held a single
   derived sentence restating the <h1> and a backdrop chip. A note says what
   the section IS — neither old heading did, and a reader had no way to tell
   whether this was the swarm's reading or the input they were handed. */
.sv__backdrop { margin: 1.5rem 0 2rem; }
.sv__panel-note { margin: 0.55rem 0 0; max-width: 46rem; color: var(--color-text-muted); font-size: 0.85rem; line-height: 1.6; }
.sv__backdrop-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem 2.5rem; margin-top: 0.4rem; }
.sv__metric-line { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-top: 0.8rem; font-family: var(--font-mono); color: var(--color-text-muted); }
.sv__metric-line b { color: var(--color-text); font-size: 1.4rem; }
.sv__bar, .sv__panel-bar div { height: 0.45rem; background: rgba(255,255,255,0.06); border: 1px solid var(--color-border); overflow: hidden; }
.sv__bar i, .sv__panel-bar i { display: block; height: 100%; background: var(--color-green); }
/* The regime read in words, above the figures that support it. Set larger than
   the metric line because it IS the answer — the composite, the bar and the
   sparkline are all evidence for this one word. */
.sv__regime-call { display: flex; align-items: center; gap: 0.55rem; margin: 0 0 0.85rem;
                   font-family: var(--font-mono); font-size: 1.05rem; letter-spacing: 0.02em;
                   color: var(--color-text); }
/* Beacon is a POINT in the covenant, never a run of type — so the direction is
   carried by a small square beside the word, not by colouring the word itself. */
.sv__regime-call i { width: 0.5rem; height: 0.5rem; flex: none; }
.sv__sparkline { margin-top: 1rem; height: 4.25rem; }
.sv__sparkline svg { width: 100%; height: 100%; display: block; }
.sv__panel-sub { margin: 1rem 0 0.4rem; font-family: var(--font-mono); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-text-muted); }
/* The dissent line is a finding, not a caption: it keeps the panel-sub scale but
   drops the uppercase tracking so it reads as a sentence. Written as a compound
   selector and placed AFTER .sv__panel-sub deliberately — as a bare .sv__dissent
   earlier in the file it lost the cascade to panel-sub's text-transform and the
   sentence rendered in caps. */
.sv__panel-sub.sv__dissent { text-transform: none; letter-spacing: 0; font-size: 0.7rem;
                             line-height: 1.5; color: var(--color-text-muted); max-width: 34ch; }
.sv__panel-divergence { overflow-x: auto; }
.sv__panel-divergence svg { width: 100%; max-width: 17rem; height: auto; display: block; }
.sv__bucket-bars-svg { overflow-x: auto; }
/* Wider than the old 34rem: the bars figure now carries its own series names
   and a "% of NAV" value column, and squeezed to 34rem the 10.5px bucket labels
   collided with the series column. */
.sv__bucket-bars-svg svg { width: 100%; min-width: 26rem; max-width: 42rem; height: auto; display: block; }
.sv__panel-bars { display: grid; gap: 0.55rem; margin-top: 1rem; }
.sv__panel-bar { display: grid; grid-template-columns: 4.8rem 1fr 2.5rem; gap: 0.65rem; align-items: center; font-family: var(--font-mono); font-size: 0.68rem; color: var(--color-text-muted); }
.sv__panel-bar b { color: var(--color-text); text-align: right; }
.sv__portfolio, .sv__recommendation { border: 1px solid var(--color-border); padding: 1.25rem; background: rgba(255,255,255,0.015); margin-bottom: 2rem; }
.sv__portfolio-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem; margin: 1.5rem 0; align-items: start; }
.sv__donut-list { display: grid; gap: 0.55rem; }
.sv__donut-row { display: grid; grid-template-columns: 2.5rem 1fr auto; gap: 0.6rem; align-items: center; font-family: var(--font-mono); font-size: 0.72rem; color: var(--color-text-muted); }
.sv__donut-row i { width: 2.1rem; height: 2.1rem; border-radius: 50%; background: conic-gradient(var(--c) calc(var(--p) * 1%), rgba(255,255,255,0.06) 0); border: 1px solid var(--color-border); position: relative; }
.sv__donut-row i::after { content: ""; position: absolute; inset: 0.42rem; border-radius: 50%; background: var(--color-void); }
.sv__donut-row span { color: var(--color-text); }
.sv__donut-row b { color: var(--color-text-dim); font-weight: 500; }
.sv__table-wrap { overflow-x: auto; }
.sv__data-table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 0.72rem; }
.sv__data-table th { color: var(--color-text-dim); text-align: left; font-weight: 400; padding: 0.35rem 0.55rem; border-bottom: 1px solid var(--color-border); }
.sv__data-table td { padding: 0.45rem 0.55rem; border-bottom: 1px solid rgba(255,255,255,0.06); color: var(--color-text-muted); text-align: left; }
.sv__data-table td:first-child { color: var(--color-text); }
.sv__num { text-align: right !important; }
/* The bars' key. Each swatch is drawn with the SAME treatment as the bar it
   names — open outline, muted fill, accent fill — so the mapping is visual
   rather than positional. */
.sv__bars-key { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex;
                flex-wrap: wrap; gap: 0.3rem 1.1rem;
                font-family: var(--font-mono); font-size: 0.66rem; }
.sv__bars-key li { display: flex; align-items: center; gap: 0.4rem; }
.sv__bars-key span { color: var(--color-text-muted); }
.sv__bars-key__swatch { width: 0.7rem; height: 0.4rem; flex: none; }
.sv__bars-key__swatch.is-target { border: 1px solid var(--color-text-muted); }
.sv__bars-key__swatch.is-actual { background: var(--color-text-dim); opacity: 0.9; }
.sv__bars-key__swatch.is-recommended { background: var(--color-accent); }
.sv__bars-key li:last-child span { color: var(--color-accent); }
/* The bucket table repeats the bars as numbers. Sits directly under the figure
   it restates, so it reads as one block rather than a second exhibit. */
.sv__bucket-table { margin-top: 0.9rem; }
.sv__bucket-table .sv__data-table { font-variant-numeric: tabular-nums; }
/* Recommended is the column the panel exists to publish — it takes the accent
   the R bar already uses above, so the eye lands in the same place in both. */
.sv__num--rec { color: var(--color-accent) !important; }
.sv__bucket-table td.sv__num--rec { color: var(--color-accent); }
/* The move being asked for. Direction is carried by the ↑/↓ glyph in the text,
   not by colour alone, so it survives a monochrome read; the colours only
   reinforce it. Green = add, sand = trim — never red/green as the sole signal. */
.sv__gap.is-up { color: var(--color-green); }
.sv__gap.is-down { color: var(--color-warm, #e8a640); }
.sv__notables { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--color-border); }
.sv__notables ul { margin: 0.75rem 0 0; padding-left: 1rem; color: var(--color-text-muted); font-size: 0.82rem; line-height: 1.55; }
.sv__stance-chip { display: inline-flex; align-items: center; gap: 0.35rem; }
.sv__rich-rec { display: grid; gap: 1rem; }
.sv__rec-actions { display: grid; gap: 0.5rem; }
.sv__action-row { display: grid; grid-template-columns: 7rem 5rem 1fr; gap: 0.75rem; align-items: start; border-top: 1px solid var(--color-border); padding-top: 0.65rem; font-size: 0.82rem; }
.sv__action-row span, .sv__action-row b { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; }
.sv__action-row b { color: var(--color-text); }
.sv__action-row p { margin: 0; color: var(--color-text-muted); line-height: 1.5; }
/* Cyan seams the top edge instead of washing the whole plane: the covenant
   makes cyan a LINE, never a mass, and a tinted field is a mass. */
.sv__panel--accent { border-color: var(--color-border); border-top-color: var(--color-accent); }
/* The stance chip. nowrap so it cannot break mid-label and pull the view
   column out of alignment on a narrow panel. */
.sv__dis-stance { display: inline-flex; align-items: baseline; gap: 0.35rem; white-space: nowrap; }
.sv__dis-nostance { color: var(--color-text-dim); font-style: italic; }
.sv__dis-read { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.06em;
  color: var(--color-accent) !important; text-transform: none !important; }
.sv__disagreements { display: grid; gap: 1.6rem; margin-top: 1rem; }
.sv__disagreement h3 { margin: 0 0 0.7rem; font-family: var(--font-mono); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text); }
.sv__disagreement ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 0; }
/* Three fixed columns — member, stance, view — so every view in a disagreement
   begins at the same x and the column can be scanned down. They shared two
   columns before, with the stance and view inline in the second, so each row's
   view started wherever that row's stance chip ended.
   Baseline alignment, not centre: the three cells are set at different sizes,
   and centring made the member name ride high against its own view. */
.sv__disagreement li { display: grid; grid-template-columns: 6.5rem 9.5rem 1fr;
  gap: 0.75rem; align-items: baseline; color: var(--color-text-muted);
  font-size: 0.78rem; line-height: 1.55; padding: 0.5rem 0; }
/* A hairline per position rather than gaps alone: with wrapping views the rows
   are unequal heights, and whitespace on its own stopped saying where one
   member's position ended and the next began. */
.sv__disagreement li + li { border-top: 1px solid rgba(255,255,255,0.05); }
.sv__disagreement a { color: var(--color-text); text-decoration: none; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.68rem; }
.sv__disagreement a:hover { color: var(--color-accent); }
/* "Settles when" is the resolution condition, not body copy — set it off from
   the positions above it so it reads as the disagreement's footer. */
.sv__disagreement p { margin: 0.8rem 0 0; padding-top: 0.7rem;
  border-top: 1px solid var(--color-border); color: var(--color-text-dim);
  font-size: 0.78rem; line-height: 1.55; }
.sv__disagreement p em { font-style: normal; font-family: var(--font-mono);
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-text-muted); margin-right: 0.4rem; }
.sv__takes-section { margin-top: 2rem; }
.sv__takes--ported { margin-top: 1rem; gap: 1rem; }
.sv__take--ported { background: transparent; padding: 1.35rem; --vfy-inset: 1.35rem; }
.sv__take-member { display: flex; align-items: center; gap: 0.8rem; }
.sv__member-link { color: var(--color-text); text-decoration: none; font-family: var(--font-sans); font-weight: 700; font-size: 1.15rem; }
.sv__take-lens { margin-top: 0.15rem; font-family: var(--font-mono); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text-dim); }
.sv__stance-badge { display: inline-flex; align-items: center; gap: 0.42rem; border: 1px solid; padding: 0.18rem 0.5rem; font-family: var(--font-mono); font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.1em; }
.sv__take-body { margin: 1rem 0 0; color: var(--color-text); line-height: 1.7; font-size: 0.9rem; }
.sv__take-body p { margin: 0 0 0.9rem; }
.sv__take-body ul { margin: 0.25rem 0 1rem; padding-left: 1.2rem; }
.sv__take-body li { margin: 0.25rem 0; }
.sv__take-body li::marker { color: var(--color-text-dim); }
/* Section heading inside a rendered take ("REGIME", "ALLOCATION", "SUBJECT").
   A label, not a title: mono, small, tracked — so it separates the sections
   without competing with the page's own headings. Global, because take bodies
   render on the member, session, and permalink pages alike. */
.sv__take-h { margin: 1.15rem 0 0.4rem; font-family: var(--font-mono); font-size: 0.64rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: 0.16em; color: var(--color-text-muted); }
.sv__take-h:first-child { margin-top: 0; }
.sv__take-body strong { color: var(--color-text); font-weight: 700; }
.sv__take-body a, .sv__synthesis a { color: var(--color-accent); }
.sv__synthesis { margin-top: 2rem; border-left: 2px solid var(--color-accent); padding-left: 1.4rem; }
.sv__synthesis div { margin: 0.75rem 0 0; color: var(--color-text); font-family: var(--font-sans); line-height: 1.75; font-size: 1.05rem; }
.sv__synthesis p { margin: 0 0 0.75rem; }
@media (max-width: 720px) {
  .sv__body--narrow { padding-top: 6.5rem; }
  .sv__session-top, .sv__take-head { align-items: flex-start; }
  .sv__action-row { grid-template-columns: 1fr; }
  /* Member and stance share the top line, view below across both — three 6.5rem
     columns do not survive a phone, and stacking all three wasted a full line
     on a two-word stance chip. */
  .sv__disagreement li { grid-template-columns: auto 1fr; gap: 0.2rem 0.7rem; }
  .sv__disagreement .sv__dis-view { grid-column: 1 / -1; }
  .sv__panel-bar { grid-template-columns: 4.5rem 1fr; }
  .sv__panel-bar b { display: none; }
}

/* swarm application form (/swarm/apply) */
.sv__form { display: flex; flex-direction: column; gap: 1.25rem; max-width: 32rem; margin-top: 2rem; }
.sv__field { display: flex; flex-direction: column; gap: 0.4rem; }
.sv__input {
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius);
  color: var(--color-text); font-family: var(--font-sans); font-size: 0.9rem; padding: 0.65rem 0.8rem;
}
.sv__input:focus { outline: none; border-color: var(--color-accent); }
.sv__textarea { resize: vertical; min-height: 4rem; font-family: var(--font-sans); }
.sv__submit {
  align-self: flex-start; cursor: pointer; font-family: var(--font-mono); font-size: 0.8rem;
  text-transform: uppercase; letter-spacing: 0.1em; padding: 0.6rem 1.4rem; border-radius: var(--radius);
  color: var(--color-bg); background: var(--color-accent); border: none;
}
.sv__submit:disabled { opacity: 0.5; cursor: default; }
.sv__applied { flex-direction: column; align-items: flex-start; }

/* The application-status checklist that lived here (.sv__steps/.sv__step-dot)
   is gone. It filled its "done" dots with Beam cyan, which put a cyan mass
   behind a figure, and on a finished application all three read identically.
   Its replacement is the numbered, dated .ap-steps in the page's own
   <style> (frontend/public/views/swarm/apply-status.html) — that page was
   the only consumer, so this set had no other callers. */

@media (min-width: 768px) {
  /* .rv__cards base 4-col grid promoted to components.css (.rm-cards). */
  .rv__cards.rv--cols3 { grid-template-columns: repeat(3, 1fr); }
  .rv__cards.rv--cols4 { grid-template-columns: repeat(4, 1fr); }
  .rv__panels { grid-template-columns: repeat(3, 1fr); }
  .rv__panels.rv--cols2 { grid-template-columns: repeat(2, 1fr); }
  .rv__panels.rv--cols3 { grid-template-columns: repeat(3, 1fr); }
  .sv__rail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sv__backdrop-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* .sv__discussion stays single-column at every width. Consensus and
     Disagreements are different KINDS of claim about the session, not a pair to
     compare side by side, and they are wildly unequal in length — two columns
     forced a ragged bottom and implied they carry equal weight. Now that echoed
     prose is suppressed, Consensus is often empty too, which left a lone
     column stranded in half the grid. They read as a sequence. */
  .sv__portfolio-grid { grid-template-columns: 0.75fr 1.25fr; }
  .sv__metadata-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* research signals (/research/*) */
.rs { padding: 9rem 1.5rem 6rem; }
.rs__eyebrow { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.3em; color: var(--color-accent); }
.rs__title { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 2.25rem; letter-spacing: -0.02em; margin: 0.5rem 0; }
.rs__q { color: var(--color-text); font-size: 1.05rem; }
.rs__asof { color: var(--color-text-muted); font-family: var(--font-mono); font-size: 0.8rem; }
.rs__loading { color: var(--color-text-muted); font-family: var(--font-mono); }
.rs__error { color: var(--color-warn); font-family: var(--font-mono); }
.rs__gauges { display: grid; grid-template-columns: 1fr; gap: 1rem; margin: 2rem 0; }
.rs__gauge { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1.25rem; }
.rs__gauge-name { font-size: 0.95rem; }
.rs__gauge-val { font-family: var(--font-mono); font-size: 1.5rem; font-weight: 700; color: var(--color-text); margin: 0.25rem 0; }
.rs__bar { height: 4px; background: var(--color-border); border-radius: var(--radius); overflow: hidden; margin: 0.5rem 0; }
.rs__bar-fill { height: 100%; background: var(--color-green); }
.read { font-family: var(--font-mono); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; padding: 0.2rem 0.55rem; border-radius: var(--radius); }
/* These chips carried a 10%-alpha fill behind a ~143x20 badge: roughly 1,300px2
   of cyan on read--ok and 2,900px2 of warm orange on read--warn. The covenant is
   that cyan is a line and never a mass, and that warm orange is a point capped
   around 12px, so both were breaches — on shared CSS, so on every research page
   that renders a chip. The hue still carries the reading; a hairline carries the
   chip. Fixed here rather than scoped per page so the two research siblings
   cannot drift apart. */
.read--ok { color: var(--color-accent); border: 1px solid var(--color-accent); }
.read--mid { color: var(--color-warm); border: 1px solid var(--color-warm); }
.read--warn { color: var(--color-warn); border: 1px solid var(--color-warn); }
.rs__gauge-pct { font-family: var(--font-mono); font-size: 0.7rem; color: var(--color-text-muted); margin: 0.25rem 0 0.5rem; }
.rs__chart { height: 280px; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1rem; margin-top: 1.5rem; }
.rs__h2 { font-size: 1.25rem; margin: 2.5rem 0 1rem; }
.rs__series-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
.rs__series-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.75rem 1rem 1rem; }
.rs__series-label { font-family: var(--font-mono); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text-dim); margin-bottom: 0.5rem; }
.rs__series-canvas { height: 120px; }
@media (min-width: 768px) { .rs__gauges { grid-template-columns: repeat(2, 1fr); } .rs__series-grid { grid-template-columns: repeat(2, 1fr); } }

/* allocation (/allocation) residue — the page is built almost entirely from the
   shared .rm-* components (see components.css) + the regime hero shell; these
   few page-local rules cover content shapes the shared library doesn't: the
   two-up chart grid, standalone category-legend spacing, section/chart ledes,
   the stacked value-over-quantity numeric cell, the accent total column, table
   header swatches, and the footer link/margin. */
.alloc-charts { display: grid; grid-template-columns: 1fr; gap: 1.5rem; margin-bottom: 2.5rem; }
.alloc-legend { flex-wrap: wrap; gap: 0.75rem 1.25rem; margin-bottom: 1.5rem; }
.alloc-lede { font-size: 0.875rem; color: var(--color-text-muted); margin: 0.75rem 0 0; max-width: 42rem; }
.alloc-chart-sub { font-size: 0.75rem; color: var(--color-text-muted); margin: 0.25rem 0 0; }
.alloc-num span { display: block; }
.alloc-num i { display: block; font-style: normal; font-size: 0.6rem; color: var(--color-text-dim); margin-top: 1px; }
.alloc-total { color: var(--color-green); font-weight: 700; }
.alloc-table th .rm-legend-swatch { margin-right: 0.4rem; }
.alloc-foot { margin-top: 2.5rem; }
.alloc-foot a { color: var(--color-accent); text-decoration: none; }
.alloc-foot a:hover { text-decoration: underline; }
@media (min-width: 768px) { .alloc-charts { grid-template-columns: 1fr 1fr; } }

/* ── Admin task-queue dashboard (/admin) ─────────────────────────────────────
   A password-gated operator view over the Postgres task queue. Reuses the shared
   .rm-table/.rm-eyebrow component classes; these .adm-* rules cover the page
   shell, login card, status tiles/badges, clickable rows, and the per-run <pre>
   log blocks (job_runs.output/error). */
.adm { padding: 9rem 1.5rem 6rem; }
.adm-head { margin-bottom: 2rem; }
.adm-title { font-size: 2.25rem; letter-spacing: -0.02em; margin: 0.5rem 0 0; }
.adm-lede { color: var(--color-text-muted); font-size: 0.9rem; margin: 0.75rem 0 0; max-width: 44rem; line-height: 1.6; }
.adm-lede code { font-family: var(--font-mono); color: var(--color-accent); }
.adm-dim { color: var(--color-text-dim); }
.adm-msg { margin-top: 0.75rem; }

/* Login card */
.adm-login {
  max-width: 30rem; margin: 2rem 0; padding: 1.5rem;
  border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface);
}
.adm-login__title { font-size: 1.1rem; margin: 0 0 0.5rem; }
.adm-login__hint { color: var(--color-text-muted); font-size: 0.8rem; margin: 0 0 1rem; line-height: 1.5; }
.adm-login__form { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.adm-input {
  flex: 1 1 12rem; padding: 0.55rem 0.75rem; font-family: var(--font-mono); font-size: 0.85rem;
  color: var(--color-text); background: var(--color-deep);
  border: 1px solid var(--color-border); border-radius: var(--radius);
}
.adm-input:focus { outline: none; border-color: var(--color-accent); }

/* Buttons */
.adm-btn {
  padding: 0.5rem 1rem; font-family: var(--font-mono); font-size: 0.78rem; cursor: pointer;
  color: var(--color-deep); background: var(--color-accent);
  border: 1px solid var(--color-accent); border-radius: var(--radius);
}
.adm-btn:hover { opacity: 0.9; }
.adm-btn--ghost { color: var(--color-text-muted); background: transparent; border-color: var(--color-border); }
.adm-btn--ghost:hover { color: var(--color-text); border-color: var(--color-text-muted); opacity: 1; }

/* Toolbar */
.adm-toolbar { display: flex; align-items: center; gap: 0.75rem; margin: 0.5rem 0 1.5rem; }
.adm-toolbar__spacer { flex: 1 1 auto; }

/* Status tiles + badges */
.adm-tiles { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 2rem; }
.adm-tile {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 1rem;
  border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface);
}
.adm-tile__count { font-family: var(--font-mono); font-weight: 700; font-size: 1.1rem; }
.adm-badge {
  display: inline-block; padding: 0.1rem 0.5rem; border-radius: var(--radius);
  font-family: var(--font-mono); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px solid var(--color-border);
}
.adm-badge--ok { color: var(--color-accent); border-color: rgba(0, 229, 255, 0.4); background: rgba(0, 229, 255, 0.08); }
.adm-badge--err { color: var(--color-warn); border-color: rgba(255, 102, 68, 0.4); background: rgba(255, 102, 68, 0.08); }
.adm-badge--run { color: var(--color-warm); border-color: rgba(232, 166, 64, 0.4); background: rgba(232, 166, 64, 0.08); }
.adm-badge--idle { color: var(--color-text-muted); }

/* Section headings + tables */
.adm-h2 { font-size: 1rem; font-family: var(--font-mono); color: var(--color-text-muted); margin: 2rem 0 0.75rem; }
.adm-h2--flush { margin-top: 0; }
.adm-table { font-family: var(--font-mono); }
.adm-table .adm-err { max-width: 24rem; white-space: normal; word-break: break-word; color: var(--color-text-muted); }
.adm-row { cursor: pointer; }
.adm-row:hover td { background: var(--color-surface-light); }

/* Job detail + per-run log <pre> blocks */
.adm-detail {
  margin: 1.5rem 0; padding: 1rem 1.25rem;
  border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface);
}
.adm-detail__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.adm-run { margin-top: 1rem; }
.adm-run__meta { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; font-family: var(--font-mono); font-size: 0.75rem; margin-bottom: 0.4rem; }
.adm-log {
  margin: 0.25rem 0 0; padding: 0.75rem 1rem; overflow-x: auto;
  font-family: var(--font-mono); font-size: 0.72rem; line-height: 1.5; white-space: pre;
  color: var(--color-text); background: var(--color-deep);
  border: 1px solid var(--color-border); border-radius: var(--radius);
}
.adm-log--err { color: var(--color-warn); border-color: rgba(255, 102, 68, 0.3); }

/* ── Admin surface (#157 + #155) + swarm operations (#159): section nav,
   alerts, filters, stage timeline, artifact previews, schedule toggle, audit
   log, tabs, mutation forms/modals, and detail grids layered onto the /admin
   shell above. Both features share these same .adm-* primitives (the
   swarm nav/forms/tabs render on their own routes but reuse this one
   rule set) — kept as a SINGLE definition per selector; do not reintroduce a
   second same-selector block here, since a duplicate leaks orphan
   properties into whichever cascades last (see #80/PR#81). */
.adm-nav { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0 0 1.5rem; }
.adm-nav__link {
  padding: 0.4rem 0.9rem; font-family: var(--font-mono); font-size: 0.78rem; cursor: pointer;
  color: var(--color-text-muted); background: transparent; text-decoration: none;
  border: 1px solid var(--color-border); border-radius: var(--radius-pill);
}
.adm-nav__link:hover { color: var(--color-text); }
.adm-nav__link--active { color: var(--color-deep); background: var(--color-accent); border-color: var(--color-accent); }

.adm-alerts { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 2rem; }
.adm-alert {
  display: flex; gap: 0.6rem; align-items: baseline; padding: 0.6rem 0.9rem;
  border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface);
  font-family: var(--font-mono); font-size: 0.8rem;
}
.adm-alert--healthy { border-color: rgba(0, 229, 255, 0.3); }
.adm-alert--stale, .adm-alert--degraded, .adm-alert--running { border-color: rgba(232, 166, 64, 0.4); }
.adm-alert--failed, .adm-alert--dead { border-color: rgba(255, 102, 68, 0.4); }
.adm-alert--not_run { color: var(--color-text-muted); }

.adm-filters { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin: 0.5rem 0 1.25rem; }
.adm-filters select, .adm-filters input { padding: 0.4rem 0.6rem; font-family: var(--font-mono); font-size: 0.78rem;
  color: var(--color-text); background: var(--color-deep); border: 1px solid var(--color-border); border-radius: var(--radius); }
.adm-filters .adm-input { flex: 0 1 10rem; }
/* Single definition (see the header note above) — shared by both the queue/
   research filter forms and the swarm create/edit/confirm forms. */
.adm-field { display: flex; flex-direction: column; gap: 0.3rem; font-family: var(--font-mono); font-size: 0.72rem; color: var(--color-text-muted); }
.adm-pager { display: flex; gap: 0.5rem; margin: 0.75rem 0; }

.adm-stages { display: flex; flex-direction: column; gap: 0.5rem; margin: 0.75rem 0 1.5rem; }
.adm-stage {
  display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: baseline; padding: 0.6rem 0.9rem;
  border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface);
}
.adm-stage__name { font-family: var(--font-mono); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; min-width: 6rem; }

.adm-artifacts { display: flex; flex-direction: column; gap: 0.75rem; }
.adm-artifact__head { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: baseline; font-family: var(--font-mono); font-size: 0.75rem; }

.adm-link { color: var(--color-accent); text-decoration: none; font-family: var(--font-mono); font-size: 0.78rem; }
.adm-link:hover { text-decoration: underline; }

.adm-form { display: flex; flex-direction: column; gap: 0.75rem; max-width: 34rem; margin: 0.5rem 0 1.5rem; padding: 1rem 1.25rem; border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.adm-form__row { display: flex; flex-direction: column; gap: 0.3rem; }
.adm-form__row label { font-family: var(--font-mono); font-size: 0.72rem; color: var(--color-text-muted); }
.adm-form--row { flex-direction: row; flex-wrap: wrap; align-items: flex-end; max-width: none; }
.adm-form textarea {
  padding: 0.55rem 0.75rem; font-family: var(--font-mono); font-size: 0.82rem;
  color: var(--color-text); background: var(--color-deep);
  border: 1px solid var(--color-border); border-radius: var(--radius); resize: vertical; min-height: 4.5rem;
}
.adm-form select { padding: 0.5rem 0.7rem; font-family: var(--font-mono); font-size: 0.82rem;
  color: var(--color-text); background: var(--color-deep); border: 1px solid var(--color-border); border-radius: var(--radius); }
.adm-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.adm-success { color: var(--color-accent); font-family: var(--font-mono); font-size: 0.8rem; margin: 0.25rem 0 0; }
.adm-wallet-row { display: flex; gap: 0.5rem; margin-bottom: 0.4rem; }

.adm-modal { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.6); z-index: 60; }
.adm-modal__panel { max-width: 32rem; width: calc(100% - 2rem); max-height: 80vh; overflow-y: auto; padding: 1.5rem; border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }

.adm-tabs { display: flex; gap: 0.5rem; margin: 0 0 1.25rem; }
.adm-tabs--sub { margin: 0; }
.adm-tab {
  padding: 0.4rem 0.9rem; font-family: var(--font-mono); font-size: 0.78rem; cursor: pointer;
  color: var(--color-text-muted); background: transparent; border: 1px solid var(--color-border); border-radius: var(--radius);
}
.adm-tab--active { color: var(--color-accent); border-color: rgba(0, 229, 255, 0.4); background: rgba(0, 229, 255, 0.08); }

.adm-meta-grid { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1rem; font-size: 0.85rem; }
.adm-meta-grid dt { color: var(--color-text-muted); font-family: var(--font-mono); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; }
.adm-meta-grid dd { margin: 0; }
.adm-bullet-list { list-style: disc; margin: 0 0 1rem; padding-left: 1.25rem; font-size: 0.85rem; }

/* Within-bucket weights. The bucket bars say how much goes to each bucket; this
   says what is inside them. Rows are a name and a number, tabular so the column
   of percentages reads down. No fills: the figure is the point, not a bar. */
.sv__within { margin-top: 1rem; }
.sv__within-bucket { margin-top: 0.75rem; }
.sv__within-name { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em;
                   text-transform: uppercase; color: var(--color-text-dim); margin: 0 0 0.35rem; }
.sv__within-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px;
                   background: var(--color-border); border: 1px solid var(--color-border); }
.sv__within-list li { display: flex; justify-content: space-between; align-items: baseline;
                      gap: 1rem; background: var(--color-surface); padding: 0.4rem 0.65rem;
                      font-size: 0.85rem; color: var(--color-text-muted); }
.sv__within-list b { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
                     color: var(--color-text); font-weight: 600; }
@media (min-width: 640px) { .sv__within-list { grid-template-columns: 1fr 1fr; } }
