/*
 * Styling for the four Ops pages.
 *
 * Hand-written rather than Tailwind utilities, deliberately. Filament 3
 * ships a *precompiled* Tailwind 3 build containing only the classes
 * Filament itself uses: `xl:grid-cols-6`, `lg:grid-cols-4`, `tabular-nums`
 * and friends simply do not exist in it, so writing them in a custom page
 * silently produces no rule at all — which is why every stat tile stacked
 * full-width instead of forming a grid. This app is also on Tailwind 4,
 * one major ahead of Filament, so compiling a custom theme would mean
 * reconciling two Tailwind versions for a handful of layout rules.
 *
 * Colours are taken from Filament's own --primary-* / --gray-* custom
 * properties, so these pages follow the panel's theme (including the amber
 * primary) rather than hardcoding a palette that drifts from it.
 */

.ops-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 768px) {
    .ops-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .ops-grid--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1280px) {
    .ops-grid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* Two equal columns for paired tables; one column until there is room. */
.ops-split {
    display: grid;
    gap: 1.5rem;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 1280px) {
    .ops-split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ops-split--wide { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
}

/* --- Stat tile ---------------------------------------------------------- */

.ops-stat {
    display: block;
    padding: 0.875rem 1rem;
    border-radius: 0.75rem;
    background: rgb(255 255 255);
    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    outline: 1px solid rgb(0 0 0 / 0.05);
    outline-offset: -1px;
    text-decoration: none;
}

.dark .ops-stat {
    background: rgb(var(--gray-900));
    outline-color: rgb(255 255 255 / 0.1);
}

a.ops-stat:hover { outline-color: rgb(var(--primary-500) / 0.5); }

.ops-stat--alert { outline-color: rgb(var(--danger-500, 239 68 68) / 0.6); }

/* An empty queue should recede, not compete with the one that has items. */
.ops-stat--zero { opacity: 0.55; }

.ops-stat__label {
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: rgb(var(--gray-500));
}

.ops-stat__value {
    margin-top: 0.15rem;
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    color: rgb(var(--gray-950));
}

.dark .ops-stat__value { color: #fff; }

.ops-stat__sub {
    margin-top: 0.1rem;
    font-size: 0.75rem;
    color: rgb(var(--gray-500));
}

/* --- Tables ------------------------------------------------------------- */

.ops-scroll { max-height: 24rem; overflow-y: auto; margin: -0.5rem -1rem 0; }

.ops-table { width: 100%; font-size: 0.85rem; border-collapse: collapse; }
.ops-table th,
.ops-table td { padding: 0.45rem 1rem; text-align: left; vertical-align: middle; }

.ops-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: #fff;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: rgb(var(--gray-500));
    border-bottom: 1px solid rgb(var(--gray-200));
    white-space: nowrap;
}

.dark .ops-table thead th {
    background: rgb(var(--gray-900));
    border-bottom-color: rgb(255 255 255 / 0.1);
}

.ops-table tbody tr + tr td { border-top: 1px solid rgb(var(--gray-100)); }
.dark .ops-table tbody tr + tr td { border-top-color: rgb(255 255 255 / 0.05); }

.ops-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.ops-table .muted { color: rgb(var(--gray-500)); }
.ops-table .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.75rem; }

.ops-record {
    font-weight: 500;
    text-decoration: none;
    color: rgb(var(--gray-950));
}

.dark .ops-record { color: #fff; }
.ops-record:hover { color: rgb(var(--primary-600)); }
.dark .ops-record:hover { color: rgb(var(--primary-400)); }

.ops-sub { font-size: 0.72rem; color: rgb(var(--gray-500)); }

.ops-empty {
    padding: 1.5rem 1rem;
    text-align: center;
    color: rgb(var(--gray-500));
}

.ops-count {
    margin: 0.5rem -1rem -0.25rem;
    padding: 0.5rem 1rem 0;
    border-top: 1px solid rgb(var(--gray-200));
    font-size: 0.72rem;
    color: rgb(var(--gray-500));
}

.dark .ops-count { border-top-color: rgb(255 255 255 / 0.1); }

/* --- Health strip -------------------------------------------------------- */

.ops-health {
    display: grid;
    gap: 1rem;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 640px) { .ops-health { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .ops-health { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.ops-check { display: flex; align-items: flex-start; gap: 0.5rem; min-width: 0; }

.ops-dot {
    flex: none;
    width: 0.5rem;
    height: 0.5rem;
    margin-top: 0.45rem;
    border-radius: 9999px;
}

.ops-dot--ok { background: rgb(34 197 94); }
.ops-dot--warn { background: rgb(245 158 11); }
.ops-dot--fail { background: rgb(239 68 68); }
.ops-dot--skip { background: rgb(var(--gray-400)); }

.ops-check__name { font-size: 0.875rem; font-weight: 500; color: rgb(var(--gray-950)); }
.dark .ops-check__name { color: #fff; }
.ops-check__latency { font-size: 0.7rem; color: rgb(var(--gray-500)); }
.ops-check__detail {
    font-size: 0.75rem;
    color: rgb(var(--gray-500));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ops-banner {
    padding: 0.75rem 1rem;
    border-radius: 0.75rem;
    background: rgb(239 68 68 / 0.1);
    outline: 1px solid rgb(239 68 68 / 0.3);
    outline-offset: -1px;
    font-size: 0.875rem;
}

.ops-kv { display: flex; justify-content: space-between; font-size: 0.875rem; padding: 0.15rem 0; }
.ops-kv dt { color: rgb(var(--gray-500)); }
.ops-kv dd { margin: 0; font-variant-numeric: tabular-nums; color: rgb(var(--gray-950)); }
.dark .ops-kv dd { color: #fff; }

/* --- AI usage: sparkline bars and share meters --------------------------- */

.ops-bars {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 6rem;
    padding-top: 0.5rem;
}

.ops-bars__bar {
    flex: 1 1 0;
    min-width: 2px;
    border-radius: 2px 2px 0 0;
    background: rgb(var(--primary-500));
    opacity: 0.85;
}

.ops-bars__bar:hover { opacity: 1; }
.ops-bars__bar--zero { background: rgb(var(--gray-300)); opacity: 0.5; min-height: 2px; }
.dark .ops-bars__bar--zero { background: rgb(255 255 255 / 0.12); }

.ops-axis {
    display: flex;
    justify-content: space-between;
    margin-top: 0.35rem;
    font-size: 0.68rem;
    color: rgb(var(--gray-500));
}

.ops-meter {
    height: 0.35rem;
    border-radius: 9999px;
    background: rgb(var(--gray-200));
    overflow: hidden;
}

.dark .ops-meter { background: rgb(255 255 255 / 0.08); }
.ops-meter__fill { height: 100%; background: rgb(var(--primary-500)); border-radius: 9999px; }

.ops-delta { font-size: 0.72rem; font-weight: 500; }
.ops-delta--up { color: rgb(239 68 68); }
.ops-delta--down { color: rgb(34 197 94); }
.ops-delta--flat { color: rgb(var(--gray-500)); }

.ops-window { display: flex; gap: 0.35rem; flex-wrap: wrap; }
.ops-window a {
    padding: 0.2rem 0.6rem;
    border-radius: 0.5rem;
    font-size: 0.78rem;
    text-decoration: none;
    color: rgb(var(--gray-500));
    outline: 1px solid rgb(var(--gray-300));
    outline-offset: -1px;
}
.dark .ops-window a { outline-color: rgb(255 255 255 / 0.12); }
.ops-window a:hover { color: rgb(var(--primary-600)); }
.ops-window a[aria-current="true"] {
    color: rgb(var(--primary-600));
    outline-color: rgb(var(--primary-500));
    font-weight: 600;
}
.dark .ops-window a[aria-current="true"] { color: rgb(var(--primary-400)); }

/* --- Health: per-check ping button, uptime line and latency sparkline ---- */

.ops-ping {
    padding: 0 .35rem;
    border: 0;
    border-radius: 0.35rem;
    background: rgb(var(--gray-200));
    color: rgb(var(--gray-600));
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
}

.dark .ops-ping { background: rgb(255 255 255 / 0.08); color: rgb(var(--gray-400)); }
.ops-ping:hover { background: rgb(var(--primary-500)); color: #fff; }
.ops-ping[disabled] { opacity: 0.5; cursor: progress; }

.ops-check__history { margin-top: 0.15rem; font-size: 0.68rem; color: rgb(var(--gray-500)); }
.ops-check__history span + span { margin-left: 0.2rem; }

.ops-spark {
    display: flex;
    align-items: flex-end;
    gap: 1px;
    height: 1.1rem;
    margin-top: 0.3rem;
}

.ops-spark__bar {
    flex: 1 1 0;
    min-width: 1px;
    border-radius: 1px;
    background: rgb(var(--primary-500));
    opacity: 0.55;
}

/* --- Dashboard health strip ---------------------------------------------
   A compact one-line-per-system row for the dashboard widget, as distinct
   from the fuller .ops-health grid on the ops page, which also carries
   uptime and a sparkline. */

.ops-strip {
    display: grid;
    gap: .35rem 1.25rem;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 640px) { .ops-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .ops-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.ops-strip__item {
    display: flex;
    align-items: center;
    gap: .45rem;
    min-width: 0;
    font-size: .8rem;
}

.ops-strip__name {
    color: rgb(var(--gray-950));
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dark .ops-strip__name { color: #fff; }

/* Pushed right so the numbers form a column the eye can scan down. */
.ops-strip__value {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-size: .72rem;
    color: rgb(var(--gray-500));
    white-space: nowrap;
}

.ops-strip__notes {
    margin-top: .85rem;
    padding-top: .65rem;
    border-top: 1px solid rgb(var(--gray-200));
    font-size: .75rem;
    color: rgb(var(--gray-500));
}

.dark .ops-strip__notes { border-top-color: rgb(255 255 255 / .1); }
.ops-strip__notes strong { color: rgb(var(--gray-950)); font-weight: 600; }
.dark .ops-strip__notes strong { color: #fff; }

/* The row count, carried by the section heading instead of a stat tile that
   would repeat it. */
.ops-count-badge {
    display: inline-block;
    margin-left: .4rem;
    padding: 0 .4rem;
    border-radius: 9999px;
    background: rgb(var(--gray-200));
    color: rgb(var(--gray-600));
    font-size: .7rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
}

.dark .ops-count-badge { background: rgb(255 255 255 / .09); color: rgb(var(--gray-400)); }

/* A thread that has been running long enough to be worth looking at. */
.ops-slow { color: rgb(245 158 11); font-weight: 600; }

.ops-ping--danger { background: rgb(239 68 68 / .15); color: rgb(239 68 68); }
.ops-ping--danger:hover { background: rgb(239 68 68); color: #fff; }

/* A process list is stale the moment it is drawn; say when it was read. */
.ops-asof {
    margin-right: .5rem;
    font-size: .68rem;
    font-variant-numeric: tabular-nums;
    color: rgb(var(--gray-500));
}

/* --- Trade calibration -------------------------------------------------- */

/*
 * Score colour is a four-stop scale, not a gradient: below 50 is the gate's
 * own failure threshold (TradeStatusCommand), 50–69 is holding, 70–84 is
 * sound, 85+ is where a floor should end up. Reusing the gate's boundary
 * means the colour on the page and the state in the table can never tell
 * two different stories.
 */
.cal-bad   { color: rgb(220 38 38); }
.cal-warn  { color: rgb(217 119 6); }
.cal-ok    { color: rgb(37 99 235); }
.cal-good  { color: rgb(22 163 74); }
.dark .cal-bad  { color: rgb(248 113 113); }
.dark .cal-warn { color: rgb(251 191 36); }
.dark .cal-ok   { color: rgb(96 165 250); }
.dark .cal-good { color: rgb(74 222 128); }

/* Seven dimensions as one compact strip — the shape of a trade at a glance. */
.cal-dims { display: flex; gap: 2px; }

.cal-dim {
    flex: 1 1 0;
    min-width: 2.05rem;
    padding: 0.2rem 0.1rem 0.25rem;
    border-radius: 0.3rem;
    text-align: center;
    background: rgb(var(--gray-100));
    line-height: 1.15;
}

.dark .cal-dim { background: rgb(255 255 255 / 0.05); }

.cal-dim__k {
    display: block;
    font-size: 0.55rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: rgb(var(--gray-500));
}

.cal-dim__v { display: block; font-size: 0.8rem; font-weight: 650; font-variant-numeric: tabular-nums; }

/* The floor is ringed because it is the number the programme tracks. */
.cal-dim--floor { outline: 1.5px solid rgb(var(--primary-500)); outline-offset: -1.5px; background: rgb(var(--primary-50)); }
.dark .cal-dim--floor { background: rgb(var(--primary-500) / 0.14); }

.cal-floor { display: flex; align-items: baseline; gap: 0.3rem; font-variant-numeric: tabular-nums; }
.cal-floor__n { font-size: 1.05rem; font-weight: 700; }
.cal-floor__d { font-size: 0.68rem; color: rgb(var(--gray-500)); text-transform: uppercase; letter-spacing: 0.03em; }

.cal-badge {
    display: inline-block;
    padding: 0.1rem 0.4rem;
    border-radius: 0.35rem;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.cal-badge--REMEDIATION { background: rgb(254 226 226); color: rgb(153 27 27); }
.cal-badge--PROVISIONAL { background: rgb(254 249 195); color: rgb(133 77 14); }
.cal-badge--UNMEASURED  { background: rgb(var(--gray-200)); color: rgb(var(--gray-600)); }
.dark .cal-badge--REMEDIATION { background: rgb(153 27 27 / 0.35); color: rgb(252 165 165); }
.dark .cal-badge--PROVISIONAL { background: rgb(133 77 14 / 0.35); color: rgb(253 224 71); }
.dark .cal-badge--UNMEASURED  { background: rgb(255 255 255 / 0.08); color: rgb(var(--gray-400)); }

/* THIN evidence is a caveat on the score, so it rides next to it, quietly. */
.cal-thin {
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: rgb(217 119 6);
}
.dark .cal-thin { color: rgb(251 191 36); }

/*
 * Score deltas invert the ops-delta convention: there, up is spend and
 * therefore red. Here up is a better score and green, and criticals — where
 * fewer is better — are rendered with their sign already flipped by the
 * caller rather than by a second colour rule.
 */
.cal-delta { font-size: 0.7rem; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cal-delta--good { color: rgb(22 163 74); }
.cal-delta--bad  { color: rgb(220 38 38); }
.cal-delta--flat { color: rgb(var(--gray-400)); }
.dark .cal-delta--good { color: rgb(74 222 128); }
.dark .cal-delta--bad  { color: rgb(248 113 113); }

.cal-spark { display: flex; align-items: flex-end; gap: 1px; height: 1.4rem; }
.cal-spark__bar { width: 3px; background: rgb(var(--primary-400)); border-radius: 1px; min-height: 1px; }
.cal-spark__bar--last { background: rgb(var(--primary-600)); }

.cal-row { cursor: pointer; }
.cal-row:hover { background: rgb(var(--gray-50)); }
.dark .cal-row:hover { background: rgb(255 255 255 / 0.04); }
.cal-row--open { background: rgb(var(--primary-50)); }
.dark .cal-row--open { background: rgb(var(--primary-500) / 0.1); }

.cal-toolbar { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.85rem; }

.cal-input {
    flex: 1 1 15rem;
    min-width: 0;
    padding: 0.4rem 0.65rem;
    border-radius: 0.5rem;
    border: 1px solid rgb(var(--gray-300));
    background: #fff;
    font-size: 0.82rem;
    color: rgb(var(--gray-950));
}

.dark .cal-input { background: rgb(var(--gray-900)); border-color: rgb(255 255 255 / 0.12); color: #fff; }
.cal-input:focus { outline: 2px solid rgb(var(--primary-500)); outline-offset: -1px; border-color: transparent; }

/* Filter chips double as counts, so the filter row also reports the split. */
.cal-chips { display: flex; gap: 0.3rem; flex-wrap: wrap; }

.cal-chip {
    padding: 0.25rem 0.6rem;
    border-radius: 0.5rem;
    border: 0;
    font-size: 0.75rem;
    font-weight: 500;
    cursor: pointer;
    background: transparent;
    color: rgb(var(--gray-500));
    outline: 1px solid rgb(var(--gray-300));
    outline-offset: -1px;
}

.dark .cal-chip { outline-color: rgb(255 255 255 / 0.12); }
.cal-chip:hover { color: rgb(var(--primary-600)); }
.cal-chip[aria-pressed="true"] {
    color: rgb(var(--primary-600));
    outline-color: rgb(var(--primary-500));
    font-weight: 650;
}
.dark .cal-chip[aria-pressed="true"] { color: rgb(var(--primary-400)); }

/* --- Drill-down: findings and scenarios --------------------------------- */

.cal-finding {
    padding: 0.6rem 0.75rem;
    border-radius: 0.55rem;
    background: rgb(var(--gray-50));
    border-left: 3px solid rgb(var(--gray-300));
}

.dark .cal-finding { background: rgb(255 255 255 / 0.04); border-left-color: rgb(255 255 255 / 0.15); }
.cal-finding + .cal-finding { margin-top: 0.5rem; }
.cal-finding--critical { border-left-color: rgb(220 38 38); }
.cal-finding--ambiguity { border-left-color: rgb(217 119 6); }
.cal-finding--missing_line { border-left-color: rgb(37 99 235); }
.cal-finding--line_verdict { border-left-color: rgb(139 92 246); }

.cal-finding__head { display: flex; gap: 0.5rem; align-items: baseline; flex-wrap: wrap; }
.cal-finding__title { font-size: 0.82rem; font-weight: 600; color: rgb(var(--gray-950)); }
.dark .cal-finding__title { color: #fff; }
.cal-finding__tag {
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: rgb(var(--gray-500));
}

/* The judge's own words, labelled so why/fix stay distinguishable. */
.cal-finding__body { margin-top: 0.3rem; font-size: 0.78rem; color: rgb(var(--gray-600)); line-height: 1.45; }
.dark .cal-finding__body { color: rgb(var(--gray-400)); }
.cal-finding__body b { color: rgb(var(--gray-500)); font-weight: 700; font-size: 0.62rem; letter-spacing: 0.04em; text-transform: uppercase; }
.cal-finding__band { font-variant-numeric: tabular-nums; white-space: nowrap; }

.cal-tabs { display: flex; gap: 0.35rem; margin-bottom: 0.85rem; flex-wrap: wrap; }

.cal-runsel {
    max-height: 15rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.cal-runsel__item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.35rem 0.5rem;
    border: 0;
    border-radius: 0.4rem;
    background: transparent;
    cursor: pointer;
    font-size: 0.75rem;
    text-align: left;
    color: rgb(var(--gray-600));
}

.dark .cal-runsel__item { color: rgb(var(--gray-400)); }
.cal-runsel__item:hover { background: rgb(var(--gray-100)); }
.dark .cal-runsel__item:hover { background: rgb(255 255 255 / 0.06); }
.cal-runsel__item[aria-current="true"] { background: rgb(var(--primary-50)); color: rgb(var(--primary-700)); font-weight: 600; }
.dark .cal-runsel__item[aria-current="true"] { background: rgb(var(--primary-500) / 0.15); color: rgb(var(--primary-300)); }
.cal-runsel__when { flex: 1 1 auto; font-variant-numeric: tabular-nums; }

.cal-scenario__req {
    font-size: 0.78rem;
    color: rgb(var(--gray-950));
    display: block;
    max-width: 46rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dark .cal-scenario__req { color: #fff; }

/* Per-class counts on a scenario row: zero recedes, non-zero carries its colour. */
.cal-pill {
    display: inline-block;
    min-width: 1.5rem;
    padding: 0.05rem 0.3rem;
    border-radius: 0.3rem;
    font-size: 0.68rem;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
    text-align: center;
    background: rgb(var(--gray-100));
    color: rgb(var(--gray-500));
}

.dark .cal-pill { background: rgb(255 255 255 / 0.06); }
.cal-pill--zero { opacity: 0.35; }
.cal-pill--critical { background: rgb(254 226 226); color: rgb(153 27 27); }
.dark .cal-pill--critical { background: rgb(153 27 27 / 0.4); color: rgb(252 165 165); }

.cal-live { display: flex; align-items: center; gap: 0.4rem; font-size: 0.72rem; color: rgb(var(--gray-500)); }
.cal-live__dot { width: 6px; height: 6px; border-radius: 9999px; background: rgb(34 197 94); }
.cal-live__dot--off { background: rgb(var(--gray-400)); }

/*
 * The board is this page's primary artifact, not a side panel, so it gets a
 * taller window than the shared 24rem .ops-scroll cap — four visible rows
 * out of sixty-three reads as a broken table rather than a scrollable one.
 */
.cal-scroll { max-height: 44rem; }

/* Tighter cells: twelve columns only fit without a horizontal scroll if
   each one stops claiming a full 1rem of padding either side. */
.cal-table th,
.cal-table td { padding: 0.45rem 0.55rem; }
.cal-table td:first-child, .cal-table th:first-child { padding-left: 1rem; }
.cal-table td:last-child, .cal-table th:last-child { padding-right: 1rem; }

.cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.1rem;
    margin-top: 0.85rem;
    padding-top: 0.7rem;
    border-top: 1px solid rgb(var(--gray-200));
    font-size: 0.72rem;
    color: rgb(var(--gray-500));
}

.dark .cal-legend { border-top-color: rgb(255 255 255 / 0.1); }
.cal-legend b { font-weight: 700; }

/* A run-over-run change that crosses evidence classes is real arithmetic but
   weak evidence, so it is shown and de-emphasised rather than hidden. */
.cal-delta--soft { opacity: 0.45; font-weight: 500; }
.cal-caveat { font-size: 0.62rem; color: rgb(var(--gray-500)); white-space: nowrap; }

/* Sortable column headers. A button rather than a click handler on the th so
   the sort is reachable by keyboard and announced by a screen reader. */
.cal-sort {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    font: inherit;
    color: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
}

.cal-sort:hover { color: rgb(var(--primary-600)); }
.dark .cal-sort:hover { color: rgb(var(--primary-400)); }
.cal-sort[data-active] { color: rgb(var(--primary-600)); }
.dark .cal-sort[data-active] { color: rgb(var(--primary-400)); }
.cal-sort__arrow { font-size: 0.6rem; }
.ops-table th.num .cal-sort { justify-content: flex-end; }

/* A row pinned to a historical run is marked on its left edge, so it reads as
   deliberately out of step with the rest of the board rather than stale. */
.cal-row--pinned > td:first-child { box-shadow: inset 3px 0 0 rgb(var(--primary-500)); }

.cal-pinned-tag {
    margin-top: 0.15rem;
    font-size: 0.62rem;
    font-weight: 650;
    color: rgb(var(--primary-600));
}

.dark .cal-pinned-tag { color: rgb(var(--primary-400)); }

/* --- Legend ------------------------------------------------------------- */

.cal-key { font-size: 0.78rem; }

/*
 * A column flow rather than a grid: the blocks are wildly different heights,
 * and grid rows align to the tallest cell in each row — which left a whole
 * band of whitespace beside the short ones. Columns pack them.
 */
.cal-key__cols {
    font-size: 0.78rem;
    column-gap: 2.25rem;
    margin-top: 1.5rem;
}

@media (min-width: 900px)  { .cal-key__cols { column-count: 2; } }
@media (min-width: 1400px) { .cal-key__cols { column-count: 3; } }

/* Never split a block across a column boundary — half a legend entry at the
   foot of one column is worse than an uneven column. */
.cal-key__group {
    break-inside: avoid;
    page-break-inside: avoid;
    display: inline-block;
    width: 100%;
    margin-bottom: 1.5rem;
}

.cal-key__title {
    margin: 0 0 0.5rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgb(var(--gray-500));
    padding-bottom: 0.35rem;
    border-bottom: 1px solid rgb(var(--gray-200));
}

.dark .cal-key__title { border-bottom-color: rgb(255 255 255 / 0.1); }

.cal-key__lede {
    margin: 0 0 0.6rem;
    color: rgb(var(--gray-500));
    line-height: 1.5;
    max-width: 60ch;
}

/* Term and definition on one line, the term column-aligned so the block
   scans as a list rather than as prose. */
.cal-key__row {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    margin-bottom: 0.4rem;
    line-height: 1.45;
    color: rgb(var(--gray-600));
}

.dark .cal-key__row { color: rgb(var(--gray-400)); }
.cal-key__row b { color: rgb(var(--gray-950)); font-weight: 650; }
.dark .cal-key__row b { color: #fff; }
.cal-key__row code {
    font-size: 0.72rem;
    padding: 0.05rem 0.3rem;
    border-radius: 0.25rem;
    background: rgb(var(--gray-100));
}
.dark .cal-key__row code { background: rgb(255 255 255 / 0.08); }

.cal-key__term {
    flex: 0 0 auto;
    min-width: 6.5rem;
    font-weight: 650;
    color: rgb(var(--gray-950));
}

.dark .cal-key__term { color: #fff; }
.cal-key__term--pinned { color: rgb(var(--primary-600)); box-shadow: inset 3px 0 0 rgb(var(--primary-500)); padding-left: 0.5rem; }
.dark .cal-key__term--pinned { color: rgb(var(--primary-400)); }

.cal-key__swatch { flex: 0 0 3.2rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.cal-key__dim { flex: 0 0 auto; min-width: 2.7rem; }

/* Colour chip standing in for a finding card's left border. */
.cal-key__bar {
    flex: 0 0 auto;
    width: 3px;
    align-self: stretch;
    min-height: 1.1rem;
    border-radius: 2px;
    border-left-width: 3px;
    border-left-style: solid;
}

.cal-key .cal-badge { flex: 0 0 6.5rem; text-align: center; }

/* --- Explanatory prose inside a section (Site Traffic's caveat panel) ----
   Filament's section body has no type styles of its own — it is built for
   tables and stat rows, and a plain <p> inside one renders at the panel's
   base size with no leading and no measure. This is the only place in the
   console that carries running text, so the rules are scoped here rather
   than applied to <p> globally, where they would fight every table cell. */
.ops-prose p {
    font-size: 0.82rem;
    line-height: 1.6;
    color: rgb(var(--gray-600));
    max-width: 68ch;
}
.dark .ops-prose p { color: rgb(var(--gray-400)); }
.ops-prose p + p { margin-top: 0.7rem; }
.ops-prose strong { color: rgb(var(--gray-900)); font-weight: 600; }
.dark .ops-prose strong { color: #fff; }
