/* css/connections.css — Connections / Ermittlungstafel
 *
 * Zwei Hausregeln, die hier durchgesetzt werden:
 *
 * 1. KEIN `text-white-50`. Die Klasse ist ein fester Weisston und im Light Mode
 *    unlesbar; chart.css muss sie deshalb an anderer Stelle seitenweise
 *    zurechtbiegen. Hier gibt es stattdessen `--cs-fg-soft`, das pro Theme
 *    aufgeloest wird — dieselbe Wirkung, ohne den Nachbesserungsbedarf.
 *
 * 2. Gruen und Rot sind EXPLIZITE Literale, nie die Theme-Variablen. Ein Chart,
 *    dessen Signalfarben mit dem Theme wandern, sagt in zwei Themes zweierlei.
 *
 * Die Tafel-Gestaltung folgt Documentation/ANOMALY_ENGINE_PLAN.md §10.4:
 * Gruppenzugehoerigkeit ist FLAECHE und niemals Faden; Strichstaerke kodiert
 * Staerke, Deckkraft Konfidenz — nie beides auf dieselbe Groesse.
 */

:root {
    --cs-red:    #ff4455;
    --cs-green:  #16ff6a;
    --cs-amber:  #ff8c00;
    --cs-blue:   #2196F3;
    --cs-cyan:   #00d3f8;
    /* Ownership overlay.
       2026-08-28: the whole line palette was reassigned, so the old note here
       ("a hue no edge kind uses: amber legislators, blue insiders, cyan
       off-exchange") no longer describes anything and would mislead. Current
       assignment: co-movement red, insider DARK GREEN, dark pools PURPLE,
       legislators LIGHT RED / BLUE by party, owner LIGHT BLUE, money-flow
       arrows LIGHT GREEN. The two same-hue pairs and why they are safe are
       argued in analysis_connections.js next to C_INSIDER.
       Kept as variables because several rules read them. */
    --cs-owner:  #8fd6ff;
    --cs-flow:   #7dff9e;   /* money-flow arrows: light green */
    /* The owner LABEL is a lighter relative of the owner LINE, never the same
       value: it has to be legible against those lines, not to match them.
       Both halves are theme-dependent because the halo is the board's own
       background - a dark halo on the light board would outline every name in
       black. Light-mode default here, dark overrides below. */
    --cs-owner-label: #0d5c86;
    --cs-owner-halo:  rgba(255, 255, 255, 0.92);
    --cs-grey:   #9aa4b0;

    /* Theme-abhaengig — Vorgabe ist Light, Dark ueberschreibt unten. */
    --cs-fg:        #212529;
    --cs-fg-soft:   #212529;   /* see the dark-mode note: no dimmed prose */
    --cs-line:      rgba(0, 0, 0, 0.14);
    --cs-panel:     rgba(0, 0, 0, 0.035);
    --cs-node-fill: #e9eef5;
    --cs-hull:      rgba(255, 68, 85, 0.05);
    --cs-hull-line: rgba(255, 68, 85, 0.18);
    --cs-board-bg:  radial-gradient(circle at 30% 20%, #f2f6fb, #e7edf4 72%);
}

html[data-bs-theme="dark"] {
    --cs-owner-label: #dff2ff;
    --cs-owner-halo:  rgba(3, 8, 16, 0.88);
    --cs-fg:        #ffffff;
    /* Was rgba(255,255,255,0.72). Every explanatory line on this page is
       something the reader is meant to READ, not a caption to skim past -
       dimming it to 72 % made the prose the hardest part of the page to use.
       Soft is now the same white; the hierarchy is carried by SIZE and weight,
       which survive a low-contrast screen and a bright room. */
    --cs-fg-soft:   #ffffff;
    --cs-line:      rgba(255, 255, 255, 0.16);
    --cs-panel:     rgba(255, 255, 255, 0.05);
    --cs-node-fill: #1f2733;
    --cs-hull:      rgba(255, 68, 85, 0.05);
    --cs-hull-line: rgba(255, 68, 85, 0.16);
    --cs-board-bg:  radial-gradient(circle at 30% 20%, #12181f, #0d1117 72%);
}

/* ---------------------------------------------------------------- Grundtext */
body[data-page="connections"] .cs-sub {
    color: var(--cs-fg-soft);
    font-size: 0.86rem;
    line-height: 1.5;
}

body[data-page="connections"] .cs-h {
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--cs-fg-soft);
    margin: 1rem 0 0.35rem;
}

body[data-page="connections"] .cs-lead {
    max-width: 96ch;
    color: var(--cs-fg);
}

body[data-page="connections"] .cs-warn { color: var(--cs-amber); font-size: 0.82rem; }
body[data-page="connections"] .cs-up   { color: var(--cs-green); }
body[data-page="connections"] .cs-down { color: var(--cs-red); }

/* ------------------------------------------------------------------------
 * LIGHT MODE — gemessen, nicht vermutet.
 *
 * `theme-light.css` setzt
 *     html[data-bs-theme="light"] section.bg-success p, … { color:#212529 }
 * und gewinnt damit gegen `body[data-page="connections"] .cs-sub`:
 * Spezifitaet (0,2,3) gegen (0,2,1) — es ist NICHT die Kaskadenreihenfolge,
 * sondern die dritte Elementstufe im Selektor.
 *
 * Gemessen im Browser: cs-sub, cs-warn, cs-up, cs-down, cs-h, cs-lead und
 * cs-bif-side kamen ALLE als rgb(33,37,41) heraus. Bei cs-up/cs-down ist das
 * ein echter Defekt: Kauf und Verkauf haetten dieselbe Farbe.
 *
 * Ein erster Versuch mit (0,3,2) reichte NICHT: `theme-light.css` enthaelt
 *     html[data-bs-theme="light"] thead th { color:#212529 !important }
 * und gegen ein `!important` hilft keine Spezifitaet. Deshalb hier ebenfalls
 * `!important` — dieselbe Antwort, die `chart.css` an anderer Stelle fuer
 * genau dieses Problem schon gibt.
 *
 * ZWEITE FALLE, und sie war hausgemacht: eine generische Regel fuer
 * `.cs-table td` hat (0,3,3) und schlug damit die semantische `.cs-down` mit
 * (0,3,2) — meine eigene Regel ueberschrieb meine eigene. Die semantischen
 * Farben stehen jetzt ZULETZT und decken die td-Form mit ab.
 *
 * Gruen/Rot sind hier BEWUSST andere Literale als im Dark Mode: #16ff6a auf
 * Weiss ist nicht lesbar. Die Werte folgen den im Haus bereits definierten
 * --color_bull_trend / --color_bear_trend, bleiben aber explizite Literale
 * statt Theme-Variablen.
 * ---------------------------------------------------------------------- */
html[data-bs-theme="light"] body[data-page="connections"] .cs-sub,
html[data-bs-theme="light"] body[data-page="connections"] .cs-h,
html[data-bs-theme="light"] body[data-page="connections"] .cs-bif-side,
html[data-bs-theme="light"] body[data-page="connections"] .cs-kv td:first-child,
html[data-bs-theme="light"] body[data-page="connections"] .cs-table th,
html[data-bs-theme="light"] body[data-page="connections"] thead th,
html[data-bs-theme="light"] body[data-page="connections"] .cs-legend {
    color: var(--cs-fg-soft) !important;
}

html[data-bs-theme="light"] body[data-page="connections"] .cs-lead,
html[data-bs-theme="light"] body[data-page="connections"] .cs-disclaimer,
html[data-bs-theme="light"] body[data-page="connections"] .cs-verdict,
html[data-bs-theme="light"] body[data-page="connections"] .cs-kv td,
html[data-bs-theme="light"] body[data-page="connections"] .cs-table td:not(.cs-sector-cell) {
    color: var(--cs-fg) !important;
}
/* Why the :not(): this selector is (0,4,2) with !important and the sector
   classes in chart.css are (0,1,0) with !important, so in Light Mode the page
   rule wins and paints dark text onto a saturated sector background - white on
   Technology's dark blue would have become unreadable dark-on-dark. Excluding
   the cell is one token; re-declaring twelve colours here would be a fifth copy
   of the palette. Same failure shape as the .cs-table td / .cs-down clash. */

/* ZULETZT: die semantischen Farben. Sie tragen Bedeutung — im Light Mode
   liefen Kauf und Verkauf sonst beide in demselben Dunkelgrau. */
html[data-bs-theme="light"] body[data-page="connections"] .cs-warn,
html[data-bs-theme="light"] body[data-page="connections"] td.cs-warn { color: #b35c00 !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-up,
html[data-bs-theme="light"] body[data-page="connections"] td.cs-up   { color: #0a8a3a !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-down,
html[data-bs-theme="light"] body[data-page="connections"] td.cs-down { color: #cc2936 !important; }

/* --------------------------------------------------------------- Disclaimer */
body[data-page="connections"] .cs-disclaimer {
    border-left: 3px solid var(--cs-red);
    background: var(--cs-panel);
    padding: 0.75rem 1rem;
    border-radius: 0 6px 6px 0;
    color: var(--cs-fg);
    max-width: 100ch;
}

body[data-page="connections"] .cs-verdict {
    border-left: 3px solid var(--cs-blue);
    background: var(--cs-panel);
    padding: 0.6rem 0.9rem;
    border-radius: 0 6px 6px 0;
    color: var(--cs-fg);
    font-size: 0.9rem;
}

/* -------------------------------------------------------------------- Tafel */
body[data-page="connections"] .cs-board-wrap {
    display: grid;
    grid-template-columns: 1fr 320px;
    gap: 0;
    border: 1px solid var(--cs-line);
    border-radius: 8px;
    overflow: hidden;
}

@media (max-width: 991.98px) {
    body[data-page="connections"] .cs-board-wrap { grid-template-columns: 1fr; }
    body[data-page="connections"] .cs-side { border-left: 0; border-top: 1px solid var(--cs-line); }
}

body[data-page="connections"] .cs-board { background: var(--cs-board-bg); min-width: 0; }
body[data-page="connections"] .cs-svg { display: block; width: 100%; height: auto; }

body[data-page="connections"] .cs-hull {
    fill: var(--cs-hull);
    stroke: var(--cs-hull-line);
}

body[data-page="connections"] .cs-node circle { fill: var(--cs-node-fill); cursor: pointer; }
body[data-page="connections"] .cs-node text {
    font-size: 9.5px;
    fill: var(--cs-fg);
    pointer-events: none;
}
body[data-page="connections"] .cs-node:focus-visible circle {
    stroke: var(--cs-cyan);
    stroke-width: 2.5;
}
body[data-page="connections"] .cs-edge { cursor: pointer; }
body[data-page="connections"] .cs-dim { opacity: 0.12; }

body[data-page="connections"] .cs-side {
    border-left: 1px solid var(--cs-line);
    padding: 0.9rem 1rem;
    min-height: 40vh;
    color: var(--cs-fg);
}

body[data-page="connections"] .cs-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    font-size: 0.78rem;
    color: var(--cs-fg-soft);
    padding: 0.5rem 0.25rem;
}
body[data-page="connections"] .cs-legend i {
    display: inline-block;
    width: 26px;
    height: 0;
    border-top: 2px solid;
    vertical-align: middle;
    margin-right: 5px;
}

/* ------------------------------------------------------------- Key/Value */
body[data-page="connections"] .cs-kv { width: 100%; font-size: 0.82rem; }
body[data-page="connections"] .cs-kv td { padding: 2px 0; vertical-align: top; color: var(--cs-fg); }
body[data-page="connections"] .cs-kv td:first-child {
    color: var(--cs-fg-soft);
    padding-right: 10px;
    white-space: nowrap;
    width: 44%;
}

/* --------------------------------------------------------------- Tabellen */
body[data-page="connections"] .cs-table { font-size: 0.84rem; color: var(--cs-fg); }
body[data-page="connections"] .cs-table th {
    color: var(--cs-fg-soft);
    font-weight: 600;
    border-bottom: 1px solid var(--cs-line);
    white-space: nowrap;
}
body[data-page="connections"] .cs-table td { border-color: var(--cs-line); }
body[data-page="connections"] .cs-table tr.cs-sig td { background: rgba(255, 68, 85, 0.08); }

body[data-page="connections"] .cs-badge {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 0.7rem;
    font-weight: 600;
    color: #fff !important;
}
body[data-page="connections"] .cs-badge-red   { background: var(--cs-red); }
body[data-page="connections"] .cs-badge-green { background: #0a8a3a; }
body[data-page="connections"] .cs-badge-a     { background: var(--cs-blue); }
body[data-page="connections"] .cs-badge-b     { background: var(--cs-amber); }

body[data-page="connections"] .cs-bar {
    display: inline-block;
    width: 100%;
    height: 6px;
    background: var(--cs-panel);
    border-radius: 3px;
    overflow: hidden;
}
body[data-page="connections"] .cs-bar > span {
    display: block;
    height: 100%;
    background: var(--cs-red);
}

/* ----------------------------------------------------------- Bifurkation */
body[data-page="connections"] .cs-bif {
    border: 1px solid var(--cs-line);
    border-radius: 6px;
    padding: 0.55rem 0.75rem;
    margin-bottom: 0.5rem;
    background: var(--cs-panel);
}
body[data-page="connections"] .cs-bif-head { margin-bottom: 0.3rem; color: var(--cs-fg); }
body[data-page="connections"] .cs-bif-side {
    font-size: 0.78rem;
    color: var(--cs-fg-soft);
    margin-bottom: 0.15rem;
    word-break: break-word;
}

/* -------------------------------------------------------------- Panelbox */
body[data-page="connections"] .cs-panel {
    border: 1px solid var(--cs-line);
    border-radius: 8px;
    padding: 1rem;
    height: 100%;
}

body[data-page="connections"] .cs-error {
    display: none;
    border: 1px solid var(--cs-red);
    background: rgba(255, 68, 85, 0.08);
    color: var(--cs-fg);
    padding: 0.75rem 1rem;
    border-radius: 6px;
}

/* Breite Inhalte scrollen in ihrem eigenen Kasten, der Body nie horizontal. */
body[data-page="connections"] .table-responsive { overflow-x: auto; }

/* ==========================================================================
 * ADDITIONS 2026-08-26
 * ========================================================================== */

/* Board selector -------------------------------------------------------- */
body[data-page="connections"] .cs-select {
    max-width: 480px;
    background: var(--cs-panel);
    color: var(--cs-fg);
    border-color: var(--cs-line);
}

/* Callout — used where a number needs a sentence next to it so it is not
   read as something it is not. */
body[data-page="connections"] .cs-callout {
    border-left: 3px solid var(--cs-blue);
    background: var(--cs-panel);
    padding: 0.7rem 1rem;
    border-radius: 0 6px 6px 0;
    color: var(--cs-fg);
    font-size: 0.86rem;
    line-height: 1.55;
    max-width: 108ch;
}
html[data-bs-theme="light"] body[data-page="connections"] .cs-callout { color: var(--cs-fg) !important; }

/* Sortable headers ------------------------------------------------------ */
body[data-page="connections"] th.cs-sortable { cursor: pointer; user-select: none; }
body[data-page="connections"] th.cs-sortable::after {
    content: "\2195";                 /* neutral up/down arrow */
    opacity: 0.35;
    margin-left: 0.35em;
    font-size: 0.85em;
}
body[data-page="connections"] th.cs-asc::after  { content: "\2191"; opacity: 1; }
body[data-page="connections"] th.cs-desc::after { content: "\2193"; opacity: 1; }
body[data-page="connections"] th.cs-sortable:focus-visible { outline: 2px solid var(--cs-cyan); }

/* Clickable rows + the focus highlight table_focus_nav sets -------------- */
body[data-page="connections"] tr.cs-clickable { cursor: pointer; }
body[data-page="connections"] tr.cs-clickable:hover td { background: var(--cs-panel); }
body[data-page="connections"] tr.cs-row-sel > td {
    background: rgba(0, 211, 248, 0.14);
    box-shadow: inset 2px 0 0 var(--cs-cyan);
}
body[data-page="connections"] .cs-barcell { width: 34%; min-width: 90px; }

/* Ticker chips ---------------------------------------------------------- */
body[data-page="connections"] .cs-chip {
    display: inline-block;
    padding: 1px 7px;
    margin: 1px 2px 1px 0;
    font-size: 0.76rem;
    line-height: 1.5;
    border-radius: 4px;
    border: 1px solid var(--cs-line);
    background: var(--cs-panel);
    color: var(--cs-fg);
    cursor: pointer;
}
body[data-page="connections"] .cs-chip:hover {
    border-color: var(--cs-cyan);
    color: var(--cs-cyan);
}
html[data-bs-theme="light"] body[data-page="connections"] .cs-chip:not(.cs-indchip) { color: var(--cs-fg) !important; }

/* Bifurcation axis ------------------------------------------------------
   Two camps placed on one axis at their mean residual, the gap shaded
   between them. Two comma lists made the reader do this arithmetic. */
body[data-page="connections"] .cs-axis {
    position: relative;
    height: 26px;
    margin: 0.35rem 0 0.1rem;
    background: linear-gradient(to right,
        rgba(255, 68, 85, 0.10), rgba(255, 255, 255, 0.02) 50%, rgba(22, 255, 106, 0.10));
    border: 1px solid var(--cs-line);
    border-radius: 4px;
}
body[data-page="connections"] .cs-axis-zero {
    position: absolute; left: 50%; top: 0; bottom: 0;
    width: 1px; background: var(--cs-line);
}
body[data-page="connections"] .cs-axis-span {
    position: absolute; top: 10px; height: 6px;
    background: rgba(0, 211, 248, 0.30);
    border-radius: 3px;
}
body[data-page="connections"] .cs-dot {
    position: absolute; top: 6px;
    width: 14px; height: 14px; margin-left: -7px;
    border-radius: 50%;
    border: 2px solid var(--cs-node-fill);
}
body[data-page="connections"] .cs-dot-a { background: var(--cs-blue); }
body[data-page="connections"] .cs-dot-b { background: var(--cs-amber); }
body[data-page="connections"] .cs-axis-scale {
    display: flex; justify-content: space-between;
    font-size: 0.7rem; color: var(--cs-fg-soft);
    margin-bottom: 0.35rem;
}
html[data-bs-theme="light"] body[data-page="connections"] .cs-axis-scale { color: var(--cs-fg-soft) !important; }

/* The chart block host — give the TV widget room on wide screens. */
body[data-page="connections"] #cs-tv-chart-host { min-height: 120px; }

/* ---- Regime table + pane explanations under the chart (2026-08-26) ----
 * The long pane descriptions used to live in the chart legend, where they
 * pushed the colour swatches off screen. They belong under the chart: the
 * reader looks there AFTER seeing it, not before.
 */
/* ONE column. As an auto-fit grid this block sat beside the regime table and
   both were squeezed into ~40 characters a line - three columns of prose next
   to a table is more layout than either can carry. Explanatory text reads down
   a single measured column; the width cap is what makes it readable, not the
   number of columns. */
body[data-page="connections"] .cs-panes {
    display: block;
    max-width: 88ch;
}
body[data-page="connections"] .cs-panes > div + div { margin-top: 1.1rem; }
body[data-page="connections"] .cs-panes h4 { margin-bottom: 0.3rem; }

/* Swatch in the regime table — the colour link back to the candles. */
body[data-page="connections"] .cs-swatch {
    display: inline-block;
    width: 12px; height: 12px;
    border-radius: 3px;
    margin-right: 7px;
    vertical-align: -1px;
}
body[data-page="connections"] tr.cs-baserow td {
    border-top: 2px solid var(--cs-line);
    color: var(--cs-fg-soft);
}
html[data-bs-theme="light"] body[data-page="connections"] tr.cs-baserow td {
    color: var(--cs-fg-soft) !important;
}

/* ==========================================================================
 * BOARD HOVER — overlay, cluster highlight, colour logic (2026-08-26)
 * ========================================================================== */

/* Three levels of emphasis, not two. `cs-dim` is outside the cluster,
   `cs-near` is inside it but not directly linked, plain is self + direct.
   Collapsing the middle would lose the difference between "linked to this"
   and "in the same group as this", which is the whole point of the hover. */
body[data-page="connections"] .cs-near { opacity: 0.42; }
body[data-page="connections"] .cs-node.cs-pinned circle {
    stroke: var(--cs-cyan);
    stroke-width: 2.5;
}
body[data-page="connections"] .cs-node,
body[data-page="connections"] .cs-edge { transition: opacity 0.12s linear; }

body[data-page="connections"] .cs-board-wrap { position: relative; }

/* The overlay sits ABOVE the node, positioned in screen pixels — the board
   scales to its container, so a viewBox coordinate is not a pixel. */
:root { --cs-tip-bg: rgba(255, 255, 255, 0.97); }
html[data-bs-theme="dark"] { --cs-tip-bg: rgba(22, 27, 34, 0.97); }


body[data-page="connections"] .cs-cluster-info {
    font-size: 0.82rem;
    color: var(--cs-cyan);
    min-height: 1.2em;
}

/* The narrow colour vocabulary of the info panel:
   green/red = a direction is implied, amber = elevated but directionless,
   muted = nothing to see. Most rows stay muted, which is what makes the
   coloured ones carry weight. */
body[data-page="connections"] .cs-hot   { color: var(--cs-amber); }
body[data-page="connections"] .cs-warnc { color: var(--cs-blue); }
body[data-page="connections"] .cs-muted { color: var(--cs-fg-soft); }
html[data-bs-theme="light"] body[data-page="connections"] .cs-hot   { color: #b35c00 !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-warnc { color: #12608f !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-muted { color: var(--cs-fg-soft) !important; }

/* ==========================================================================
 * COMPACTING THE PAGE (2026-08-26)
 * ========================================================================== */

/* Collapsible sections. <details> rather than a JS toggle: it works before the
   page script runs, it is keyboard-operable for free, and browser find-in-page
   opens it. */
body[data-page="connections"] .cs-fold > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
}
body[data-page="connections"] .cs-fold > summary::-webkit-details-marker { display: none; }
body[data-page="connections"] .cs-fold > summary::before {
    content: "\25B8";                       /* right-pointing triangle */
    color: var(--cs-fg-soft);
    transition: transform 0.15s ease;
    font-size: 0.9em;
}
body[data-page="connections"] .cs-fold[open] > summary::before { transform: rotate(90deg); }
body[data-page="connections"] .cs-fold-hint {
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--cs-fg-soft);
}
body[data-page="connections"] .cs-fold-body { padding-top: 0.75rem; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-fold-hint { color: var(--cs-fg-soft) !important; }

/* Scroll boxes: the full list is present, it simply does not own the page.
   A truncated list would hide the very rows that show the reader the middle of
   the distribution. */
body[data-page="connections"] .cs-scroll {
    max-height: 26rem;
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid var(--cs-line);
    border-radius: 6px;
}
body[data-page="connections"] .cs-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--cs-scroll-head);
}
:root { --cs-scroll-head: #f2f5f9; }
html[data-bs-theme="dark"] { --cs-scroll-head: #171c22; }
body[data-page="connections"] .cs-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
body[data-page="connections"] .cs-scroll::-webkit-scrollbar-thumb {
    background: var(--cs-line); border-radius: 5px;
}

/* Camp badge on the split axis — carries the camp's own ramp colour. */
body[data-page="connections"] .cs-camp {
    display: inline-block;
    padding: 1px 8px;
    margin-right: 6px;
    border-radius: 10px;
    font-size: 0.7rem;
    font-weight: 600;
    color: #06121a !important;
}

/* ------------------------------------------------------------------ sector
   Industry and sector names carry the site's rotation colour. The palette
   itself lives in css/chart.css as .spn-sector-* over --color_rotation_*;
   nothing here redefines a colour, these rules only decide the SHAPE the
   colour takes on this page - a filled table cell, or a small tag.
   A fifth copy of the hex values is the one that would drift. */
.cs-table td.cs-sector-cell {
    font-weight: 600;
    white-space: nowrap;
    border-right: 1px solid rgba(0, 0, 0, .25);
}
/* No sector match (an industry the map does not cover): stay neutral rather
   than borrow a neighbouring colour and assert something untrue. */
.cs-table td.cs-sector-cell:not([class*="spn-sector-"]) {
    background: transparent;
}
.cs-sector-tag {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .2px;
    vertical-align: middle;
}
.cs-sector-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 7px;
    vertical-align: baseline;
    /* The .spn-sector-* rules set `background`, which is what this needs. */
}

/* Dropdown ---------------------------------------------------------------
   The closed field is the site's standard turquoise button (.spn-theme-select
   in chart.css, whose own comment already says "Standard Tuerkis, Text weiss")
   - reused rather than re-declared, so it stays in step with every other
   dropdown on the site.

   The OPEN list is the part chart.css paints near-black, which rendered here as
   grey-on-white in some browsers and was barely readable. These rules give it
   the same turquoise the field has. Note the limits of the platform: Chrome on
   Windows draws the option list natively and honours only background/colour,
   so the highlight bar stays the OS one - which is why the group headings are
   given weight and a lighter tint instead of relying on the highlight to
   separate them. */
body[data-page="connections"] #csBoardSelect option {
    background-color: var(--bs-primary);
    color: #fff;
    padding: 3px 6px;
}
body[data-page="connections"] #csBoardSelect optgroup {
    background-color: var(--bs-primary);
    color: #fff;
    font-weight: 800;
    font-style: normal;
}
/* The sector heading itself: same family, one step lighter, so the eye finds
   the group boundaries in a list of 128 industries. */
body[data-page="connections"] #csBoardSelect optgroup:not(:first-child) {
    border-top: 1px solid rgba(255, 255, 255, .35);
}
body[data-page="connections"] #csBoardSelect option:checked {
    background: #fff;
    color: var(--bs-primary);
    font-weight: 700;
}
/* The ticker field sits beside the dropdown and is a button in disguise -
   readonly, opens the shared symbol-search modal on click. It gets the same
   turquoise so the pair reads as one control. */
body[data-page="connections"] #csBoardTickerSearch::placeholder {
    color: rgba(255, 255, 255, .75);
    opacity: 1;
}

/* Level toggle ----------------------------------------------------------- */
body[data-page="connections"] .cs-levelbtn {
    background: transparent;
    color: var(--cs-fg);
    border: 1px solid var(--bs-primary);
    font-weight: 700;
    padding: 2px 14px;
}
body[data-page="connections"] .cs-levelbtn.active {
    background: var(--bs-primary);
    color: #fff;
}

/* Split chart ------------------------------------------------------------ */
body[data-page="connections"] .cs-bif-head {
    cursor: pointer;
    user-select: none;
}
/* An affordance, not decoration: without it nothing says the heading opens
   the chart, and a click target that looks inert does not get clicked. */
body[data-page="connections"] .cs-bif-head::before {
    content: "\25B8";
    display: inline-block;
    margin-right: 6px;
    opacity: .6;
    transition: transform .12s ease;
}
body[data-page="connections"] .cs-bif-open > .cs-bif-head::before {
    transform: rotate(90deg);
}
body[data-page="connections"] .cs-bif-head:hover { color: var(--bs-primary); }
body[data-page="connections"] .cs-bif-chart:not(:empty) {
    margin: 10px 0 4px;
    padding: 6px 4px 2px;
    border: 1px solid var(--cs-line);
    border-radius: 6px;
    background: var(--cs-panel);
}

/* Sector text colour, decided by measured luminance in analysis_connections.js.
   Specificity (0,3,1) with !important, so it outranks the .spn-sector-* rules
   in chart.css (0,1,0 !important) whose `var(--color_white)` becomes #333 in
   Light Mode - correct for text on a light page, wrong on a cell that keeps a
   saturated background in both themes. */
body[data-page="connections"] .cs-fg-light,
body[data-page="connections"] .cs-fg-light * { color: #fff !important; }
body[data-page="connections"] .cs-fg-dark,
body[data-page="connections"] .cs-fg-dark  * { color: #111 !important; }

/* Dashboard -------------------------------------------------------------- */
body[data-page="connections"] .cs-dash-grid {
    display: grid;
    grid-template-columns: minmax(240px, 320px) 1fr;
    gap: 20px;
    align-items: start;
}
body[data-page="connections"] .cs-dash-gauge {
    text-align: center;
    padding: 10px 8px 6px;
    border: 1px solid var(--cs-line);
    border-radius: 8px;
    background: var(--cs-panel);
}
body[data-page="connections"] .cs-gauge-label {
    font-weight: 800;
    font-size: 1.02rem;
    margin-top: -6px;
    letter-spacing: .2px;
}
body[data-page="connections"] .cs-gauge-note {
    font-size: .78rem;
    opacity: 1;
    margin-top: 4px;
    line-height: 1.35;
}
/* auto-fit, not a fixed count: the tile row is built from whatever is
   available that day, so a missing feed shortens the row instead of leaving
   a hole where a card should be. */
body[data-page="connections"] .cs-dash-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 12px;
}
body[data-page="connections"] .cs-tile {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: 10px 12px;
    border: 1px solid var(--cs-line);
    border-radius: 8px;
    background: var(--cs-panel);
    transition: border-color .12s ease, transform .12s ease;
}
body[data-page="connections"] .cs-tile:hover {
    border-color: var(--bs-primary);
    transform: translateY(-1px);
}
body[data-page="connections"] .cs-tile-label {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .6px;
    opacity: 1;
}
body[data-page="connections"] .cs-tile-value {
    font-size: 1.55rem;
    font-weight: 800;
    line-height: 1.15;
    margin: 2px 0 3px;
}
body[data-page="connections"] .cs-dash-of {
    font-size: .95rem;
    font-weight: 600;
    opacity: .85;
}
body[data-page="connections"] .cs-tile-note {
    font-size: .78rem;
    opacity: 1;
    line-height: 1.35;
}
/* Below the two-column breakpoint the dial goes above the tiles rather than
   being squeezed into a column too narrow to read its zone labels. */
@media (max-width: 860px) {
    body[data-page="connections"] .cs-dash-grid { grid-template-columns: 1fr; }
}

/* Two dials: they are a PAIR and must be the same size, so they share a track
   rather than each taking whatever the grid gives them. Below 1200px the tiles
   drop under the dials; below 860px the dials stack too. */
body[data-page="connections"] .cs-dash-grid {
    grid-template-columns: repeat(2, minmax(230px, 300px)) 1fr;
}
@media (max-width: 1200px) {
    body[data-page="connections"] .cs-dash-grid {
        grid-template-columns: repeat(2, minmax(230px, 1fr));
    }
    body[data-page="connections"] .cs-dash-tiles { grid-column: 1 / -1; }
}
@media (max-width: 860px) {
    body[data-page="connections"] .cs-dash-grid { grid-template-columns: 1fr; }
}

/* Collapsible board explainer. Same <details> mechanism as the other folds,
   but the summary sits inline above the toolbar rather than acting as a
   section heading, so it gets its own tighter treatment. */
body[data-page="connections"] .cs-fold-tight > summary {
    list-style: none;
    cursor: pointer;
    padding: 4px 0;
    display: flex;
    align-items: baseline;
    gap: 10px;
}
body[data-page="connections"] .cs-fold-tight > summary::-webkit-details-marker { display: none; }
body[data-page="connections"] .cs-fold-tight > summary::before {
    content: "\25B8";
    display: inline-block;
    opacity: .75;
    transition: transform .12s ease;
}
body[data-page="connections"] .cs-fold-tight[open] > summary::before { transform: rotate(90deg); }
body[data-page="connections"] .cs-fold-title {
    font-weight: 700;
    color: var(--bs-primary);
}
body[data-page="connections"] .cs-fold-tight .cs-fold-body { padding-top: 4px; }

/* Horizon toggle. Same shape as the Industry/Sector switch so the two read as
   the same kind of control; Overlay is set apart because it is not a fourth
   horizon but a combination of the other three. */
body[data-page="connections"] .cs-hzbtn {
    background: transparent;
    color: var(--cs-fg);
    border: 1px solid var(--bs-primary);
    font-weight: 700;
    padding: 2px 12px;
    white-space: nowrap;
}
body[data-page="connections"] .cs-hzbtn.active {
    background: var(--bs-primary);
    color: #fff;
}
body[data-page="connections"] .cs-hzbtn-ov { border-color: #ffd24d; }
body[data-page="connections"] .cs-hzbtn-ov.active {
    background: #ffd24d;
    color: #111;
}

/* Group nodes on the industry / sector map. Bigger than a ticker node and
   filled with the sector colour, so the map reads as a sector picture with the
   cross-sector links drawn over it. */
body[data-page="connections"] .cs-gnode text {
    font-size: 11px;
    font-weight: 700;
}
body[data-page="connections"] .cs-gnode circle {
    filter: none;
}
/* A chip standing for a whole group: wider than a ticker chip, and it must not
   wrap mid-name. */
body[data-page="connections"] .cs-gchip {
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 3px;
}

/* The rail: the industries this board's companies reach, in a column beside
   the board rather than a ring around it. A ring cost 36 % of the drawing
   because the board is height-limited, not width-limited. */
body[data-page="connections"] .cs-rail-line {
    stroke: var(--cs-line);
    stroke-width: 1;
}
body[data-page="connections"] .cs-rail-head {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .4px;
    fill: var(--cs-fg);
    opacity: .75;
    pointer-events: none;
}
body[data-page="connections"] .cs-sat-sub {
    font-size: 9px;
    fill: var(--cs-fg);
    opacity: .68;
    pointer-events: none;
}

/* Satellites: the industries this board's members reach outside their own. */
body[data-page="connections"] .cs-sat { cursor: pointer; }
body[data-page="connections"] .cs-sat-label {
    font-size: 10px;
    font-weight: 700;
    fill: var(--cs-fg);
    pointer-events: none;
}
body[data-page="connections"] .cs-sat-n {
    font-weight: 800;
    fill: var(--bs-primary);
}
body[data-page="connections"] .cs-sat:hover line { stroke-opacity: 1; }
body[data-page="connections"] .cs-sat:hover circle { stroke: #fff; stroke-width: 2; }

/* The map's centre: one bubble per connected industry. */
body[data-page="connections"] .cs-bub { cursor: pointer; }
body[data-page="connections"] .cs-bub-n {
    font-size: 10px;
    font-weight: 800;
    fill: #fff;
    paint-order: stroke;
    stroke: rgba(0, 0, 0, .55);
    stroke-width: 2.5px;
    pointer-events: none;
}
body[data-page="connections"] .cs-bub-label,
body[data-page="connections"] .cs-bub-hub {
    font-size: 10.5px;
    font-weight: 700;
    fill: var(--cs-fg);
    /* The centre sits on top of the chords, so its labels need their own
       backing or they read as part of the mesh behind them. */
    paint-order: stroke;
    stroke: var(--cs-bg, #0b0f14);
    stroke-width: 3px;
    pointer-events: none;
}
body[data-page="connections"] .cs-bub-hub { font-size: 12px; font-weight: 800; }
body[data-page="connections"] .cs-bub:hover circle { stroke: #fff; stroke-width: 2.5; }
body[data-page="connections"] .cs-bub:hover line { stroke-opacity: 1; }
/* While the centre is open the chords behind it step back - they are the
   group-level statement and the centre is the finer one. */
body[data-page="connections"] .cs-centre ~ .cs-edge,
body[data-page="connections"] svg:has(.cs-centre) path.cs-edge { stroke-opacity: .18; }

/* The rail's fallback: the same industries as cards, for viewports where a
   320px column inside the drawing would be unreadable. */
body[data-page="connections"] .cs-raillist-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 8px;
}
body[data-page="connections"] .cs-railcard {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "tag n" "g g" "a a";
    gap: 2px 8px;
    text-align: left;
    padding: 7px 10px;
    border: 1px solid var(--cs-line);
    border-radius: 7px;
    background: var(--cs-panel);
    color: var(--cs-fg);
    cursor: pointer;
}
body[data-page="connections"] .cs-railcard:hover { border-color: var(--bs-primary); }
body[data-page="connections"] .cs-railcard .cs-sector-tag { grid-area: tag; justify-self: start; }
body[data-page="connections"] .cs-railcard-n {
    grid-area: n;
    justify-self: end;
    font-weight: 800;
    font-size: 1.05rem;
    color: var(--bs-primary);
}
body[data-page="connections"] .cs-railcard-g { grid-area: g; font-weight: 700; font-size: .86rem; }
body[data-page="connections"] .cs-railcard-a { grid-area: a; font-size: .76rem; opacity: .8; }

/* The company at the centre of its own ring. */
body[data-page="connections"] .cs-bub-sub {
    font-size: 9.5px;
    fill: var(--cs-fg);
    opacity: .78;
    paint-order: stroke;
    stroke: var(--cs-bg, #0b0f14);
    stroke-width: 3px;
    pointer-events: none;
}
/* Grab cursor only when there is something to pan; wireZoom sets it while a
   drag is in flight. */
/* touch-action is set from JS per zoom state (pan-y when fitted so a swipe
   still scrolls the page past the board, none once zoomed so one finger pans).
   The CSS only provides the starting value. */
body[data-page="connections"] #csBoard svg { touch-action: pan-y; }

/* Where it goes next: today's state, the direction it leans, and every
   destination against its own base rate. */
body[data-page="connections"] .cs-tr {
    display: grid;
    grid-template-columns: minmax(150px, 190px) minmax(190px, 230px) 1fr;
    gap: 18px;
    align-items: start;
}
body[data-page="connections"] .cs-tr-from { text-align: center; }
body[data-page="connections"] .cs-tr-fromlab {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .6px;
    margin-bottom: 6px;
}
body[data-page="connections"] .cs-tr-chip {
    display: inline-block;
    padding: 8px 14px;
    border-radius: 8px;
    font-weight: 800;
    color: #111;
    line-height: 1.25;
}
body[data-page="connections"] .cs-tr-arrows {
    display: flex;
    flex-direction: column;
    gap: 14px;
    justify-content: center;
}
body[data-page="connections"] .cs-tr-arrow {
    display: grid;
    grid-template-columns: 46px auto 1fr;
    grid-template-areas: "svg p lab" ". base base";
    align-items: center;
    gap: 0 8px;
}
body[data-page="connections"] .cs-tr-arrow svg { grid-area: svg; }
body[data-page="connections"] .cs-tr-p { grid-area: p; font-weight: 800; font-size: 1.05rem; }
body[data-page="connections"] .cs-tr-lab { grid-area: lab; font-weight: 700; font-size: .84rem; }
body[data-page="connections"] .cs-tr-base { grid-area: base; font-size: .76rem; opacity: .85; }
/* 3 x 3: a row per intensity, a column per direction - the same shape as the
   regime table, so the two read as one system. */
body[data-page="connections"] .cs-tr-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}
body[data-page="connections"] .cs-tr-cell {
    border: 1px solid var(--cs-line);
    border-radius: 7px;
    padding: 7px 9px;
    background: var(--cs-panel);
}
body[data-page="connections"] .cs-tr-self { border-color: var(--bs-primary); }
body[data-page="connections"] .cs-tr-cell-head {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .78rem;
    font-weight: 700;
    line-height: 1.2;
    min-height: 2.3em;
}
body[data-page="connections"] .cs-tr-bar {
    position: relative;
    height: 8px;
    margin: 6px 0 4px;
    background: rgba(128, 128, 128, .18);
    border-radius: 4px;
}
body[data-page="connections"] .cs-tr-fill {
    position: absolute; left: 0; top: 0; bottom: 0;
    border-radius: 4px;
}
/* The base rate as a hollow marker ON the bar: the only thing worth seeing is
   how far the fill is from it. */
body[data-page="connections"] .cs-tr-basemark {
    position: absolute; top: -3px; bottom: -3px;
    width: 2px;
    background: var(--cs-fg);
    opacity: .85;
}
body[data-page="connections"] .cs-tr-nums {
    display: flex;
    align-items: baseline;
    gap: 7px;
    font-size: .78rem;
    flex-wrap: wrap;
}
@media (max-width: 1100px) {
    body[data-page="connections"] .cs-tr { grid-template-columns: 1fr; }
    body[data-page="connections"] .cs-tr-arrows { flex-direction: row; flex-wrap: wrap; }
}

/* Sparkline cells in the merged industry table. */
body[data-page="connections"] .cs-sparkcell {
    width: 66px;
    padding-left: 2px !important;
    padding-right: 2px !important;
}
body[data-page="connections"] .cs-spark { display: block; opacity: .9; }

/* The cork-board illustration above the dashboard. Two columns on a wide
   screen so the picture and the paragraph that explains it are read together;
   stacked below that, because a 300px-wide comic is not a comic. */
/* The full container width, not a capped column: the dashboard above it uses
   all 1800px, and stopping this band at 1180 left a third of the row empty
   while the picture stayed small. */
body[data-page="connections"] .cs-hero-fig {
    display: grid;
    /* The IMAGE takes the slack, not the text. Sizing the text column as 1fr
       left ~150px of the row unused, because the prose stops at its measure
       whatever the column offers. Reversing it - text at its natural width,
       picture fills the rest - spends the whole row on the only thing that
       gets better with more of it. */
    grid-template-columns: 1fr minmax(340px, 74ch);
    gap: 26px;
    align-items: start;
    margin-inline: 0;
}
body[data-page="connections"] .cs-hero-img {
    width: 100%;
    height: auto;
    border-radius: 10px;
    border: 1px solid var(--cs-line);
    display: block;
}
/* Prose still gets a measure. Full-width text is not the same as a full-width
   LAYOUT - a 900px line is unreadable however much room there is - so the
   band spans everything and the paragraphs inside it stop at 74 characters. */
body[data-page="connections"] .cs-hero-text { max-width: 74ch; }
body[data-page="connections"] .cs-hero-text .cs-lead { font-size: 1.02rem; }
@media (max-width: 900px) {
    body[data-page="connections"] .cs-hero-fig { grid-template-columns: 1fr; }
}

/* Divergence filters + the sector split band. */
body[data-page="connections"] .cs-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
}
body[data-page="connections"] .cs-secsplit {
    display: grid;
    gap: 6px;
}
body[data-page="connections"] .cs-secsplit-row {
    display: grid;
    grid-template-columns: 150px 1fr 52px auto;
    align-items: center;
    gap: 10px;
}
/* A weak split is shown, not hidden - "this sector did NOT come apart" is a
   result. It is dimmed so the eye does not read it as one that did. */
body[data-page="connections"] .cs-secsplit-weak { opacity: .55; }
body[data-page="connections"] .cs-secsplit-bar {
    height: 9px;
    background: rgba(128, 128, 128, .18);
    border-radius: 5px;
    overflow: hidden;
}
body[data-page="connections"] .cs-secsplit-fill { display: block; height: 100%; border-radius: 5px; }
body[data-page="connections"] .cs-secsplit-num { text-align: right; font-size: .86rem; }
@media (max-width: 760px) {
    body[data-page="connections"] .cs-secsplit-row { grid-template-columns: 1fr; gap: 2px; }
}

/* A folded prose passage. Same mechanism as the other folds, but it opens
   under its own heading rather than acting as one, so it is quieter. */
body[data-page="connections"] .cs-fold-prose > summary { padding: 2px 0 6px; }
body[data-page="connections"] .cs-fold-prose .cs-fold-title {
    font-weight: 600;
    font-size: .88rem;
    color: var(--bs-primary);
}
/* Inside a fold the blocks ARE the passage, so they read as one column with
   ordinary paragraph spacing instead of each carrying its own margin. */
body[data-page="connections"] .cs-fold-prose .cs-fold-body > * { max-width: 96ch; }
body[data-page="connections"] .cs-fold-prose .cs-fold-body > * + * { margin-top: .8rem; }

/* The cluster's names inside its dashboard tile. */
body[data-page="connections"] .cs-clustnames {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 7px;
}
body[data-page="connections"] .cs-clustchip {
    font-size: .72rem;
    padding: 1px 6px;
    /* The tile is a link; the chip is a button inside it. Its own cursor and
       hover make clear that it does something different. */
    position: relative;
    z-index: 2;
}

/* The industries that stood out, inside their dashboard tile.
 *
 * Sector-coloured, the same colours the table below and the rotation table
 * use, so a reader who knows one knows this. The background comes from
 * .spn-sector-* (which carries !important) and the text colour from the
 * cs-fg-light / cs-fg-dark class sectorFg() picks by MEASURING that
 * background - never a hex value written here, which would be a fifth copy of
 * the palette and the first to rot.
 *
 * Hover is a ring rather than a colour change: the colour IS the sector, and
 * changing it on hover would say the sector changed.
 */
body[data-page="connections"] .cs-indchip {
    font-size: .72rem;
    font-weight: 600;
    padding: 2px 7px;
    border-color: transparent;
    /* The tile is a link; the chip is a button inside it. */
    position: relative;
    z-index: 2;
}
body[data-page="connections"] .cs-indchip:hover,
body[data-page="connections"] .cs-indchip:focus-visible {
    border-color: transparent;
    box-shadow: 0 0 0 2px var(--cs-cyan);
    outline: none;
}

/* ------------------------------------------------------------ board controls
 * The always-visible gesture line. Reads as a caption, not as a toolbar: it
 * describes what the board does, it is not a place to click.
 */
.cs-controls {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1.1rem;
    font-size: .78rem;
    color: var(--cs-sub, #9aa4b0);
    line-height: 1.7;
}
.cs-controls kbd {
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 4px;
    padding: .04rem .34rem;
    font-size: .74rem;
    color: inherit;
    margin-right: .2rem;
}

/* ----------------------------------------------------------- searched name
 * Flat signal red, used for nothing else on the board: every other colour
 * here carries a meaning from the data, and this one means "you asked for
 * this one". The halo is a soft target, the pin is the mark.
 */
.cs-searchpin-body { fill: #ff2d46; stroke: rgba(0, 0, 0, .55); stroke-width: 1.2; }
.cs-searchpin-eye  { fill: #1a1d21; }
.cs-searchpin-halo {
    fill: none;
    stroke: #ff2d46;
    stroke-width: 1.8;
    opacity: .85;
    animation: cs-pin-pulse 1.9s ease-in-out infinite;
}
@keyframes cs-pin-pulse {
    0%, 100% { opacity: .85; }
    50%      { opacity: .28; }
}
@media (prefers-reduced-motion: reduce) {
    .cs-searchpin-halo { animation: none; }
}

/* A long press on a node is OUR gesture (isolate the cluster). Without this
 * the platform claims it first: iOS shows the text/link callout and Android
 * starts a selection, so the press ends in a menu instead of a picture. */
.cs-node, .cs-sat, .cs-bub {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}


/* ============================================================ side by side
 * The page's own chart. Sized by resolveChartHeight in chart_builder, the same
 * single authority every other chart on the site uses, so it cannot drift into
 * a fifth opinion about how tall a chart should be.
 */
.cs-compare {
    width: 100%;
    min-height: 300px;
    border: 1px solid var(--cs-line, rgba(255, 255, 255, .12));
    border-radius: 6px;
    overflow: hidden;
}
.cs-cmp-chips { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.cs-cmp-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .12rem .3rem .12rem .45rem;
    border: 1px solid var(--cs-line, rgba(255, 255, 255, .18));
    border-radius: 999px;
    font-size: .8rem;
    cursor: pointer;
    user-select: none;
}
/* The focused chip is the one the Analysis Chart button opens, and the one
 * drawn with a thicker line. Saying so twice - here and in the line width -
 * is deliberate: the button acts on a name the reader has to be able to see. */
.cs-cmp-chip.cs-cmp-focus {
    border-color: var(--cs-cyan, #00d3f8);
    box-shadow: 0 0 0 1px var(--cs-cyan, #00d3f8) inset;
}
.cs-cmp-chip i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.cs-cmp-x {
    background: none;
    border: 0;
    color: inherit;
    opacity: .5;
    line-height: 1;
    padding: 0 .2rem;
    font-size: 1rem;
    cursor: pointer;
}
.cs-cmp-x:hover { opacity: 1; }
.cs-cmp-vals { display: flex; flex-wrap: wrap; gap: .2rem 1.1rem; font-size: .84rem; }
.cs-cmp-vals i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; margin-right: .3rem; }
/* Analysis Chart button — the site-wide yellow, NOT --cs-amber. The amber is
   this page's "legislator" colour and carries meaning in the graph legend, so
   wearing it here read as a third marker class. #ffc107 is the same yellow
   .mivcn-analysis-btn (js/chart_mobile_nav.js) and the static Analysis Chart
   buttons on analysis_insider / analysis_darkpools use. 2026-08-27 */
.cs-analysisbtn {
    background-color: #ffc107;
    border-color: #ffc107;
    color: #000;
    border: 0;
    font-weight: 600;
    white-space: nowrap;
}
.cs-analysisbtn:hover { background-color: #e0a800; border-color: #e0a800; color: #000; }


/* ── Ownership overlay (13F) ─────────────────────────────────────────────
   Owner nodes are drawn as diamonds, not circles: a holder is a different
   KIND of thing from a company, and shape says so at a glance where a fourth
   circle colour would just look like another company. */
.cs-onode polygon { fill: rgba(143,214,255,0.90); stroke: rgba(0,0,0,0.55); stroke-width: 1; }
/* THE LABEL AND THE THING IT SITS ON WERE THE SAME COLOUR.
   The institution names were already #bfe8ff, and unreadable anyway: an owner
   diamond sits in the middle of its own links, so a light-blue 9px name was
   drawn over dozens of light-blue lines of nearly the same lightness. Making
   it brighter alone cannot fix that - the contrast that is missing is against
   the LINES, not against the background.
   So the name gets a halo of the board's own background, drawn behind the
   glyphs by paint-order. That is what separates it from the thicket, and it is
   the same trick that keeps a map label legible over a road. */
.cs-onode text {
    fill: var(--cs-owner-label);
    font-size: 10px;
    font-weight: 600;
    pointer-events: none;
    paint-order: stroke fill;
    stroke: var(--cs-owner-halo);
    stroke-width: 2.6px;
    stroke-linejoin: round;
}
.cs-onode { cursor: pointer; }
.cs-onode:hover polygon { fill: #c9ecff; }
.cs-onode.cs-dim { opacity: 0.25; }
/* Raised 2026-08-28 from 0.45/1.1. An owner line is the most specific claim on
   the board - THIS institution holds both of these - and it was the faintest
   thing drawn, against price lines reaching opacity 1.0 and width 3.8. The
   dimmed state comes up with it: at 0.12 a de-selected owner was invisible
   rather than backgrounded, so clicking a name appeared to delete the layer. */
.cs-oedge { stroke: var(--cs-owner); stroke-opacity: 0.78; stroke-width: 1.7; fill: none; }
.cs-oedge.cs-dim { stroke-opacity: 0.2; }
.cs-ownbadge { display:inline-block; padding:1px 6px; border-radius:3px;
               background: rgba(143,214,255,0.16); color: var(--cs-owner);
               font-size:0.72rem; font-weight:600; }

/* A significant industry with no board behind it: same colour, no promise of
   a click. */
body[data-page="connections"] .cs-indchip-flat {
    cursor: default;
    opacity: .8;
}
body[data-page="connections"] .cs-indchip-flat:hover { box-shadow: none; }

/* ------------------------------------------------------------ toolbar rows
 * One row per question, each with a fixed-width label.
 *
 * The label column is a fixed width rather than intrinsic, so the four rows
 * of controls start on the same x. With intrinsic widths "View" and
 * "Connections" differ by about 70px and the button groups staircase down the
 * left edge, which reads as four unrelated toolbars rather than one.
 */
body[data-page="connections"] .cs-toolrows {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
body[data-page="connections"] .cs-toolrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem .5rem;
}
body[data-page="connections"] .cs-toolrow-label {
    flex: 0 0 auto;
    width: 92px;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .6px;
    color: var(--cs-sub, #9aa4b0);
}
@media (max-width: 700px) {
    /* Below this the label would eat a third of the line. It becomes a
       heading for the row instead of a column beside it. */
    body[data-page="connections"] .cs-toolrow { gap: .3rem; }
    body[data-page="connections"] .cs-toolrow-label { width: 100%; }
}

/* The ticker box and its clear button, which sits INSIDE the field's right
   edge rather than beside it - a separate button in the row would read as
   another control instead of as part of this one. */
body[data-page="connections"] .cs-tickerbox {
    position: relative;
    display: inline-flex;
    align-items: center;
}
body[data-page="connections"] .cs-tickerclear {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    padding: 0;
    line-height: 1;
    font-size: 1rem;
    border: 0;
    border-radius: 3px;
    background: transparent;
    color: var(--cs-sub, #9aa4b0);
    cursor: pointer;
}
body[data-page="connections"] .cs-tickerclear:hover {
    color: var(--cs-fg);
    background: rgba(127, 127, 127, .22);
}

/* Connection-type toggles.
 *
 * Each carries a specimen of the line it switches - the same colour and dash
 * pattern the board draws - so the control and the legend are one thing. A
 * word alone ("Dark pools") makes the reader match a name to a colour they
 * have to find in a separate legend row first.
 *
 * OFF is drawn as struck-through and faded rather than merely un-highlighted:
 * with five toggles a reader needs to see at a glance which links are missing
 * from the picture, and "not highlighted" is what an inactive button in every
 * other group on this page already means. */
body[data-page="connections"] .cs-kindbtn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
body[data-page="connections"] .cs-kindbtn .cs-kindswatch {
    display: inline-block;
    width: 16px;
    height: 0;
    border-top-width: 2.5px;
    border-top-style: solid;
    flex: 0 0 auto;
}
body[data-page="connections"] .cs-kindbtn.cs-kind-off {
    opacity: .5;
    text-decoration: line-through;
}
body[data-page="connections"] .cs-kindbtn.cs-kind-off .cs-kindswatch { opacity: .35; }

/* Money-flow arrows: an institution's largest sale on this board pointing at
   its largest purchase. Drawn in one colour that no other layer uses, so a
   flow is never mistaken for a correlation. */
body[data-page="connections"] .cs-flow {
    stroke: var(--cs-flow);
    fill: none;
    /* Raised 2026-08-28 from .75. A flow arrow is the only DIRECTED line on the
       page and there are never many of them, so it can afford to be the
       brightest thing in the ownership palette without crowding anything. */
    stroke-opacity: .95;
}
body[data-page="connections"] .cs-flow.cs-dim { stroke-opacity: .2; }

/* ------------------------------------------------------- column colour tags
 * 2026-08-28. The two long "What this measures" passages were walls of prose in
 * which the reader had to find which sentence described which column. A tag
 * carrying the COLUMN'S OWN COLOUR turns that lookup into a glance.
 *
 * The colours are not chosen here - they are read off what the table already
 * draws, so the tag and the cell agree:
 *   Anomaly          direction ramp, amber at the neutral middle
 *   How crowded      crowding ramp, red at the top of the scale
 *   Order inside it  reshuffle ramp, green at "broadly unchanged"
 *   Could be a fluke the cell itself is uncoloured; cyan stands for it, and
 *                    the red "Stands out" badge is named in the text instead.
 *
 * !important on the colour is REQUIRED, not defensive: these tags sit inside
 * `.text-white` sections and Bootstrap's colour utilities carry !important, so
 * without it the background applies and the foreground does not - which reads
 * as "my class is wrong" rather than "something outranks it". Same trap the
 * margin-debt tags hit.
 */
body[data-page="connections"] .cs-coltag {
    display: inline-block;
    padding: 0 6px;
    border-radius: 3px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    line-height: 1.5;
}
body[data-page="connections"] .cs-coltag-anom  { background: rgba(255,140,0,0.16);  color: var(--cs-amber) !important; }
body[data-page="connections"] .cs-coltag-crowd { background: rgba(255,68,85,0.16);  color: var(--cs-red)   !important; }
body[data-page="connections"] .cs-coltag-order { background: rgba(22,255,106,0.14); color: var(--cs-green) !important; }
body[data-page="connections"] .cs-coltag-fluke { background: rgba(0,211,248,0.16);  color: var(--cs-cyan)  !important; }
body[data-page="connections"] .cs-coltag-above { background: rgba(255,68,85,0.22);  color: #ffb3ba         !important; }

/* Light mode: the dark-mode hues are unreadable on white - same reasoning as
   the .cs-up / .cs-down literals above, and the same values. */
html[data-bs-theme="light"] body[data-page="connections"] .cs-coltag-anom  { color: #b35c00 !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-coltag-crowd { color: #cc2936 !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-coltag-order { color: #0a8a3a !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-coltag-fluke { color: #0b7285 !important; }
html[data-bs-theme="light"] body[data-page="connections"] .cs-coltag-above { color: #cc2936 !important; }

/* A neutral KEY-TERM tag, in the page's own accent rather than a new hue.
   Used in the group-splits passage, where the three terms being marked
   (sectors, industries, separation) are not a severity scale and must not
   borrow one of the four column colours - those already mean something. */
body[data-page="connections"] .cs-coltag-term {
    background: rgba(13,202,240,0.14);
    color: var(--cs-cyan) !important;
}
html[data-bs-theme="light"] body[data-page="connections"] .cs-coltag-term { color: #0b7285 !important; }

/* "+3,461" beside an owner diamond: how many positions this holder runs that
   are NOT on this board. Small and dimmed - it is context for the diamond, not
   a second label competing with the institution's name. */
/* The badge rides on the label's colour pair, one step down in weight so the
   NAME is still the thing the eye lands on. */
body[data-page="connections"] .cs-onode-out {
    font-weight: 500;
    fill: var(--cs-owner);
    font-size: 8px;
    opacity: 0.75;
    pointer-events: none;
}
