/* ============================================================================
   LogoHAL — Statistics dashboard redesign
   ----------------------------------------------------------------------------
   Everything here is scoped under .stats-dashboard so the redesign cannot leak
   into the Gantt, modals, sidebar or any other part of the application.

   Palette (from the approved target mockup):
     blue   #0875F9   section icons, active states, impact panel
     green  #91D83F   optimization results, saturation, "after"
     navy   #102B59   titles and key figures
     gray   #6B7280   secondary text
     bg     #F7FAFD   page wash
     border #E1EAF4   subtle blue-gray rules
   ==========================================================================*/

.stats-dashboard {
    --st-blue: #0875F9;
    --st-blue-soft: #EAF3FE;
    --st-green: #91D83F;
    --st-green-deep: #5E9E14;
    --st-green-soft: #F1F9E4;
    --st-navy: #102B59;
    --st-gray: #6B7280;
    --st-muted: #94A3B8;
    --st-bg: #F7FAFD;
    --st-border: #E1EAF4;
    --st-border-soft: #EEF3F9;
    --st-slate: #64748B;
    --st-slate-soft: #F1F5F9;
    --st-red: #E5484D;
    --st-red-soft: #FEF2F2;
    --st-amber: #E9A319;
    --st-radius: 10px;

    color: var(--st-navy);
    font-size: 14px;
}

/* ── Section shell ─────────────────────────────────────────────────────── */

.stats-section {
    background: #fff;
    border: 1px solid var(--st-border);
    border-radius: var(--st-radius);
    margin-bottom: 18px;
    overflow: hidden;
}

/* The whole heading row toggles the section; it is a real button so keyboard
   users get Enter/Space and screen readers announce the expanded state. */
.stats-section-header {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 16px 20px;
    background: none;
    border: 0;
    text-align: left;
    transition: background-color .15s ease;
}

.stats-section-header:hover { background: #FAFCFE; }
.stats-section-header:focus-visible {
    outline: 2px solid var(--st-blue);
    outline-offset: -2px;
}

/* Major section icons sit in a small tinted light-blue container. */
.stats-section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    border-radius: 10px;
    background: var(--st-blue-soft);
    color: var(--st-blue);
    font-size: 20px;
}

.stats-section-heading { flex: 1 1 auto; min-width: 0; }

.stats-section-title {
    display: block;
    font-size: 16px;
    font-weight: 600;
    color: var(--st-navy);
    line-height: 1.3;
}

.stats-section-subtitle {
    display: block;
    font-size: 12px;
    color: var(--st-gray);
    margin-top: 2px;
}

/* Secondary metadata (week number, optimization timestamp) stays compact and
   quiet so it never competes with the section title. */
.stats-section-meta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--st-gray);
    white-space: nowrap;
    flex: 0 0 auto;
}

.stats-chevron {
    flex: 0 0 auto;
    font-size: 18px;
    color: var(--st-muted);
    transition: transform .2s ease;
}

/* Bootstrap's collapse toggles .show on the body; mirror it on the chevron. */
.stats-section.is-collapsed .stats-chevron { transform: rotate(-90deg); }

.stats-section-body { padding: 4px 20px 20px; }

/* Collapsed bodies must not leave the last row flush against the border. */
.collapse:not(.show) { height: 0; }

/* ── Comparison: three summary panels ──────────────────────────────────── */

.stats-kpi-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 18px;
}

.stats-kpi-card {
    background: #fff;
    border: 1px solid var(--st-border);
    border-radius: 8px;
    overflow: hidden;
}

/* Light tinted header with a colored accent bar instead of a saturated block. */
.stats-kpi-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    border-bottom: 1px solid var(--st-border);
    border-top: 3px solid var(--st-slate);
    background: var(--st-slate-soft);
    color: var(--st-slate);
}

.stats-kpi-head i { font-size: 15px; }

.stats-kpi-card--after .stats-kpi-head {
    border-top-color: var(--st-green);
    background: var(--st-green-soft);
    color: var(--st-green-deep);
}

.stats-kpi-card--impact .stats-kpi-head {
    border-top-color: var(--st-blue);
    background: var(--st-blue-soft);
    color: var(--st-blue);
}

.stats-kpi-card {
    /* The value scales against this card's own width (cqi below), not the
       viewport — the dashboard sits beside a sidebar and inside padding, so
       viewport units would size the type to the wrong box. */
    container-type: inline-size;
}

.stats-kpi-grid {
    display: grid;
    /* Five across while the card can hold them. The narrow case is handled by a
       container query below rather than by letting them collide: a cell holding
       "+8,06 p.p." needs ~64px, so five stop fitting under ~340px of card. */
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 2px;
    padding: 14px 6px;
}

/* Three cards side by side put each card at roughly (viewport - 230px sidebar -
   padding - gaps) / 3, so a 1450px screen already leaves one only ~374px and a
   1200px screen leaves it ~291px — narrow enough that five columns collide. Two
   earlier attempts failed here: shrinking the type far enough to fit left the
   numbers unreadable (10px), and stacking the three cards into their own rows
   tripled the section's height and hid the three-way comparison that is the
   whole point of putting them in a row.

   The fix is to reflow the five metrics inside the card to 3 above + 2 below.
   Each cell then gets ~half again the width it had, at a size that stays
   legible, and the three cards stay side by side so they remain comparable.

   The threshold is set by the widest value in the section, "+8,06 p.p." in the
   impact card: at its 13px size that needs ~68px of type, plus 8px of cell
   padding, so five columns need ~380px of card before they collide. */
@container (max-width: 380px) {
    .stats-kpi-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

    /* Row 2 starts at cells 4 and 5 — they no longer follow a cell on their own
       row, so the divider that separates columns would draw a stray line at the
       card's left edge. Only the first cell of each row loses it. */
    .stats-kpi-cell:nth-child(3n + 1) { border-left: 0; }

    /* More room per cell means the values can stop shrinking so hard. */
    .stats-kpi-cell-value { font-size: clamp(15px, 4.4cqi, 22px); }
    .stats-kpi-card--impact .stats-kpi-cell-value { font-size: clamp(13px, 3.6cqi, 17px); }
}

/* Below ~240px of card, three columns leave under 68px each — exactly what the
   impact card's "+8,06 p.p." needs before it clips. Two columns gives each cell
   room to breathe, and the divider moves to the start of each row. */
@container (max-width: 240px) {
    .stats-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .stats-kpi-cell:nth-child(3n + 1) { border-left: 1px solid var(--st-border-soft); }
    .stats-kpi-cell:nth-child(2n + 1) { border-left: 0; }
}

/* And below ~150px — a phone, where the fixed 230px sidebar has eaten most of
   the viewport — even two columns leave too little. One column gives every
   value the full card width. */
@container (max-width: 150px) {
    .stats-kpi-grid { grid-template-columns: minmax(0, 1fr); }
    .stats-kpi-cell:nth-child(2n + 1) { border-left: 1px solid var(--st-border-soft); }
    .stats-kpi-cell:first-child { border-left: 0; }
}

.stats-kpi-cell {
    text-align: center;
    padding: 4px 4px;
    min-width: 0;
}

.stats-kpi-cell + .stats-kpi-cell { border-left: 1px solid var(--st-border-soft); }

.stats-kpi-cell-value {
    /* Fallback for engines without container query units — they drop the
       clamp() below entirely, so the static size must come first. */
    font-size: 22px;
    /* Fluid against the card width, not the viewport: the dashboard sits beside
       a 230px sidebar and inside padding, so vw units would size the type to
       the wrong box. The values never wrap (white-space:nowrap below), so on a
       narrow card they would spill into the neighbouring cell and two numbers
       read as one ("59,2622,50"). Scaling the face to the container keeps them
       contained; the row-level breakpoint at 1450px handles the range where a
       cell gets too narrow to hold its value at any legible size. */
    font-size: clamp(15px, 3.1cqi, 22px);
    font-weight: 700;
    color: var(--st-navy);
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The impact panel stacks the relative change under the absolute one, so the
   absolute figure stays the dominant read. */
.stats-kpi-cell-value.is-secondary {
    font-size: 12px;
    font-weight: 600;
    margin-top: 1px;
}

/* The impact panel carries two figures per cell (absolute over relative), and
   "+8,06 p.p." is the widest value in the section — so this card sheds size a
   little faster than the others to keep all five cells on one line. */
.stats-kpi-card--impact .stats-kpi-cell-value { font-size: 17px; font-size: clamp(13px, 2.4cqi, 17px); }
.stats-kpi-card--impact .stats-kpi-cell-value.is-secondary { font-size: 12px; }

.stats-kpi-cell-label {
    font-size: 11px;
    color: var(--st-gray);
    margin-top: 5px;
    line-height: 1.25;
    /* Long Spanish labels ("Productividad media") must wrap, not overflow —
       but at a word boundary. `overflow-wrap: anywhere` also breaks INSIDE a
       word, which split "Operaciones" into "Operacio nes" and "Cuadrillas"
       into "Cuadrilla s" while there was still room on the line. `hyphens:
       auto` gives the same overflow protection with real Spanish hyphenation
       points, and lang="es" on <html> is what lets the browser know them. */
    overflow-wrap: break-word;
    hyphens: auto;
}

.stats-kpi-cell.is-positive .stats-kpi-cell-value { color: var(--st-green-deep); }
.stats-kpi-cell.is-negative .stats-kpi-cell-value { color: var(--st-red); }

/* ── Chart cards ───────────────────────────────────────────────────────── */

.stats-chart-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
}

.stats-card {
    background: #fff;
    border: 1px solid var(--st-border);
    border-radius: 8px;
    padding: 14px;
}

.stats-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.stats-card-head i {
    font-size: 16px;
    color: var(--st-blue);
}

.stats-card-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--st-navy);
}

.stats-chart-box { position: relative; min-height: 230px; }

/* ── Section 2: saturation ─────────────────────────────────────────────── */

.stats-section--sat {
    /* The compare tab renders this section inside a half-width column, so the
       space it actually gets is unrelated to the viewport — a media query would
       size the layout off a number that means nothing here. Query the section's
       own width instead. */
    container-type: inline-size;
}

.stats-sat-layout {
    display: grid;
    /* The gauge column is allowed to shrink rather than hold a floor. It used to
       be minmax(280px, 340px), but the arc inside is a fixed 260px, so the floor
       bought nothing except starving the metrics: at a 1200px viewport the gauge
       kept its 340px and left 58px for four metric cards, clipping their labels
       to "C…" and "s pr…". */
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    gap: 24px;
    align-items: center;
}

/* The gauge is a half-doughnut: Chart.js sizes the arc to the smaller of the
   canvas dimensions and draws it in the upper half, so the box needs its own
   definite height — a flexible one made the arc drift into a corner. Only the
   arc gets a fixed height; the caption lives outside it, because sizing the
   whole box for the canvas clipped the caption against the section edge. */
.stats-gauge-box {
    width: 100%;
}

.stats-gauge-unit + .stats-gauge-unit {
    margin-top: 20px;
}

.stats-gauge-arc {
    position: relative;
    /* Scales with its column instead of a hard 260px. Chart.js is configured with
       maintainAspectRatio:false, so it follows the box — and the arc keeps its
       260x140 proportions at full width while shrinking intact when the compare
       tab's half-width column squeezes it. */
    width: 100%;
    max-width: 260px;
    aspect-ratio: 260 / 140;
    margin: 0 auto;
}

.stats-gauge-arc canvas { display: block; }

.stats-gauge-caption-box {
    text-align: center;
    /* Pulls the number up into the hollow of the arc, the way the mockup reads. */
    margin-top: -22px;
}

.stats-gauge-value {
    display: block;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.stats-gauge-caption {
    display: block;
    font-size: 12px;
    color: var(--st-gray);
    margin-top: 2px;
}

.stats-metric-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.stats-metric {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border: 1px solid var(--st-border);
    border-radius: 8px;
    background: #fff;
}

.stats-metric i {
    font-size: 18px;
    color: var(--st-blue);
    flex: 0 0 auto;
}

.stats-metric-value {
    display: block;
    font-size: 24px;
    font-weight: 700;
    color: var(--st-navy);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.stats-metric-label {
    display: block;
    font-size: 11px;
    color: var(--st-gray);
    margin-top: 3px;
    line-height: 1.25;
}

/* ── Section 3: crew rankings ──────────────────────────────────────────── */

.stats-ranking-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.stats-ranking-card {
    border: 1px solid var(--st-border);
    border-radius: 8px;
    padding: 14px;
    background: #fff;
}

.stats-ranking-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
}

.stats-ranking-card-head > i {
    font-size: 16px;
    color: var(--st-blue);
}

.stats-ranking-card--low .stats-ranking-card-head > i { color: var(--st-red); }

.stats-ranking-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.stats-ranking-row {
    display: grid;
    grid-template-columns: 26px minmax(72px, 108px) minmax(0, 1fr) 62px;
    align-items: center;
    gap: 10px;
}

/* Circular rank indicator. The number stays visible so rank is never carried
   by color alone. */
.stats-rank-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    font-size: 11px;
    font-weight: 700;
    color: var(--st-slate);
    background: var(--st-slate-soft);
    border: 1px solid var(--st-border);
    font-variant-numeric: tabular-nums;
}

.stats-rank-badge--top { background: var(--st-green-soft); color: var(--st-green-deep); border-color: #D6EDB3; }

/* The badge repeats its row's saturation band. The rank number stays rendered
   either way, so the tint is redundant reinforcement, never the only cue. */
.stats-rank-badge.is-red { background: var(--st-red-soft); color: var(--st-red); border-color: #FBD5D5; }
.stats-rank-badge.is-low { background: var(--st-red-soft); color: var(--st-red); border-color: #FBD5D5; }
.stats-rank-badge.is-amber { background: #FEF6E4; color: #B97C05; border-color: #F6E3B4; }

.stats-crew-name {
    font-size: 13px;
    color: var(--st-navy);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stats-bar-track {
    position: relative;
    display: block;
    height: 12px;
    border-radius: 6px;
    background: var(--st-slate-soft);
    overflow: hidden;
}

.stats-bar-fill {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 6px;
    background: var(--st-green);
    /* Width is set inline per row from the real saturation value. */
    transition: width .3s ease;
}

.stats-bar-fill.is-amber { background: var(--st-amber); }
.stats-bar-fill.is-red { background: var(--st-red); }
.stats-bar-fill.is-low { background: #F4A7A9; }

.stats-rank-value {
    text-align: right;
    font-size: 13px;
    font-weight: 600;
    color: var(--st-navy);
    font-variant-numeric: tabular-nums;
}

.stats-rank-value.is-critical {
    color: var(--st-red);
    background: var(--st-red-soft);
    border-radius: 4px;
    padding: 2px 6px;
}

.stats-ranking-link {
    margin-left: auto;
    font-size: 12px;
    color: var(--st-blue);
    text-decoration: none;
    background: none;
    border: 0;
    padding: 0;
}

.stats-ranking-link:hover { text-decoration: underline; }
.stats-ranking-link:focus-visible { outline: 2px solid var(--st-blue); outline-offset: 2px; }

/* ── Section 4/5 side by side ──────────────────────────────────────────── */

.stats-split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    align-items: start;
}

.stats-split > .stats-section { margin-bottom: 0; }

/* ── Rules table ───────────────────────────────────────────────────────── */

.stats-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.stats-table thead th {
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    color: var(--st-gray);
    padding: 0 10px 8px;
    border-bottom: 1px solid var(--st-border);
}

.stats-table thead th.is-numeric,
.stats-table tbody td.is-numeric { text-align: right; font-variant-numeric: tabular-nums; }

.stats-table tbody td {
    padding: 9px 10px;
    border-bottom: 1px solid var(--st-border-soft);
    color: var(--st-navy);
    vertical-align: middle;
}

.stats-table tbody tr:last-child td { border-bottom: 0; }

/* Level badges are purely visual — they never change rule behavior. */
.stats-level-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .03em;
}

.stats-level-badge--hard { background: var(--st-red-soft); color: var(--st-red); }
.stats-level-badge--medium { background: #FEF6E7; color: #B4740A; }
.stats-level-badge--soft { background: var(--st-green-soft); color: var(--st-green-deep); }

/* ── Program data ──────────────────────────────────────────────────────── */

.stats-data-list { margin: 0; }

.stats-data-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 2px;
    border-bottom: 1px solid var(--st-border-soft);
}

.stats-data-row:last-child { border-bottom: 0; }

.stats-data-icon {
    flex: 0 0 auto;
    width: 18px;
    font-size: 14px;
    color: var(--st-muted);
    text-align: center;
}

.stats-data-name {
    flex: 1 1 auto;
    font-size: 13px;
    color: var(--st-navy);
    min-width: 0;
}

/* A fixed two-column grid: the number right-aligned in the wide track, the copy
   button in a track that is always reserved. Rows without a button therefore
   keep the same number column, so adding a copy button never shifts the value.
   An explicitly sized track reserves its space even when empty — which is why
   the button can stay display:none rather than being padded in. */
.stats-data-value {
    display: grid;
    grid-template-columns: 1fr 26px;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    width: 108px;
    font-size: 14px;
    font-weight: 600;
    color: var(--st-navy);
    font-variant-numeric: tabular-nums;
}

.stats-data-value > :first-child {
    text-align: right;
    min-width: 0;
}

.stats-copy-btn { justify-self: center; }

.stats-copy-btn {
    background: none;
    border: 1px solid var(--st-border);
    border-radius: 4px;
    color: var(--st-muted);
    font-size: 12px;
    line-height: 1;
    padding: 4px 6px;
    transition: color .15s ease, border-color .15s ease;
}

.stats-copy-btn:hover { color: var(--st-blue); border-color: var(--st-blue); }
.stats-copy-btn:focus-visible { outline: 2px solid var(--st-blue); outline-offset: 1px; }

/* ── Section 6: OT distribution ────────────────────────────────────────── */

.stats-distribution-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
}

.stats-dist-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.stats-dist-row { display: block; }

.stats-dist-row-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 6px;
}

.stats-dist-label {
    font-size: 12px;
    color: var(--st-navy);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stats-dist-value {
    font-size: 12px;
    font-weight: 600;
    color: var(--st-navy);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Restrained categorical palette for the distribution bars. */
.stats-dist-swatch {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 2px;
    margin-right: 7px;
    flex: 0 0 auto;
}

.stats-dist-row-head .stats-dist-label { display: flex; align-items: center; }

.stats-swatch--0 { background: #0875F9; }
.stats-swatch--1 { background: #91D83F; }
.stats-swatch--2 { background: #F2A93B; }
.stats-swatch--3 { background: #F27BB0; }
.stats-swatch--4 { background: #56C7D4; }
.stats-swatch--5 { background: #9B8CF0; }

/* ── Comparison tab ────────────────────────────────────────────────────── */

/* The comparison tab reuses every component above rather than restating them:
   the wizard is a plain section, each side of the split is a stack of sections,
   and the gauge/data/distribution blocks are the same ones the statistics tab
   renders. Only the two-column frame and the side labels are new. */

.comparison-empty {
    text-align: center;
    padding: 40px 24px;
}

.comparison-empty i {
    font-size: 30px;
    color: var(--st-blue);
    margin-bottom: 14px;
    display: block;
}

.comparison-empty h3 {
    font-size: 17px;
    font-weight: 600;
    color: var(--st-navy);
    margin-bottom: 6px;
}

.comparison-empty p {
    font-size: 13px;
    color: var(--st-gray);
    margin-bottom: 20px;
    max-width: 52ch;
    margin-inline: auto;
}

/* A saved optimization is a choice, not a table row: the list is built from the
   same surface and rhythm as the rest of the dashboard. */
.comparison-picker {
    list-style: none;
    margin: 0;
    padding: 0;
    text-align: left;
    max-width: 640px;
    margin-inline: auto;
    border: 1px solid var(--st-border);
    border-radius: 8px;
    overflow: hidden;
}

.comparison-picker-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    width: 100%;
    padding: 12px 16px;
    background: #fff;
    border: 0;
    border-bottom: 1px solid var(--st-border-soft);
    text-align: left;
    cursor: pointer;
    transition: background-color .15s ease;
}

.comparison-picker-item:last-child { border-bottom: 0; }

.comparison-picker-item:hover,
.comparison-picker-item:focus-visible {
    background: var(--st-blue-soft);
    outline: none;
}

.comparison-picker-item:focus-visible {
    box-shadow: inset 0 0 0 2px var(--st-blue);
}

.comparison-picker-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--st-navy);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.comparison-picker-date {
    font-size: 12px;
    color: var(--st-gray);
    white-space: nowrap;
}

/* ── Split view ────────────────────────────────────────────────────────── */

/* Two independent stacks rather than one table split in half: each side keeps
   its own collapsible sections, so collapsing a section on one side leaves the
   other side's sections where they are.

   The grid exists so the two sides line up ROW BY ROW, not just column by
   column. The side wrappers are display:contents, so their sections become
   direct grid items and can be pinned to matching rows: without that, a side
   with three saturation gauges pushes everything below it out of step with the
   other side, and the reader can no longer scan a metric across the gap. */
.comparison-split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

.comparison-side,
.comparison-side > .comparison-content { display: contents; }

#currentOptimizationColumn .comparison-side-head { grid-area: 1 / 1; }
#savedOptimizationColumn .comparison-side-head { grid-area: 1 / 2; }

#currentOptimizationColumn .stats-section--sat { grid-area: 2 / 1; }
#savedOptimizationColumn .stats-section--sat { grid-area: 2 / 2; }

#currentOptimizationColumn .stats-section--data { grid-area: 3 / 1; }
#savedOptimizationColumn .stats-section--data { grid-area: 3 / 2; }

#currentOptimizationColumn .stats-section--crews { grid-area: 4 / 1; }
#savedOptimizationColumn .stats-section--crews { grid-area: 4 / 2; }

#currentOptimizationColumn .stats-section--dist { grid-area: 5 / 1; }
#savedOptimizationColumn .stats-section--dist { grid-area: 5 / 2; }

/* Below the split breakpoint the pinned rows would fight the single column, so
   the sides go back to ordinary document flow. */
@media (max-width: 1100px) {
    .comparison-side,
    .comparison-side > .comparison-content { display: block; }
    #currentOptimizationColumn .comparison-side-head,
    #savedOptimizationColumn .comparison-side-head,
    #currentOptimizationColumn .stats-section,
    #savedOptimizationColumn .stats-section { grid-area: auto; }
}

.comparison-side-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 20px;
    background: #fff;
    border: 1px solid var(--st-border);
    border-radius: var(--st-radius);
}

.comparison-side-head > div { flex: 1 1 auto; min-width: 0; }

.comparison-side-name {
    display: block;
    font-size: 16px;
    font-weight: 600;
    color: var(--st-navy);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.comparison-side-tag {
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .03em;
    color: var(--st-gray);
    margin-bottom: 2px;
}

/* The saved side carries the "before" accent so the reader can tell the two
   apart at a glance without reading the names. */
.comparison-side--saved .comparison-side-head {
    border-color: #D6EDB3;
    background: var(--st-green-soft);
}

.comparison-side--saved .comparison-side-tag { color: var(--st-green-deep); }

.comparison-close {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--st-border);
    border-radius: 6px;
    background: #fff;
    color: var(--st-gray);
    transition: color .15s ease, border-color .15s ease;
}

.comparison-close:hover { color: var(--st-red); border-color: var(--st-red); }

.comparison-close:focus-visible {
    outline: 2px solid var(--st-blue);
    outline-offset: 2px;
}

/* Inside the split the panels are nested one level deeper than on the
   statistics tab, so the sections lose their outer card and read as a stack.
   The grid's gap supplies the spacing, so no margin is needed. */
.comparison-split .stats-section {
    box-shadow: none;
    margin-bottom: 0;
}

/* A crew list runs to hundreds of rows; it scrolls inside its own section
   rather than stretching the whole tab. Both sides get the same ceiling, which
   is what lets two crew tables be compared line by line. */
.comparison-crew-scroll {
    height: 420px;
    overflow-y: auto;
}

/* Loading placeholder for the saved side, which arrives over AJAX. */
.comparison-pending {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 48px 20px;
    font-size: 13px;
    color: var(--st-gray);
}

.comparison-pending .spinner-border {
    width: 1rem;
    height: 1rem;
    border-width: 2px;
}

/* ── Responsive ────────────────────────────────────────────────────────── */

@media (max-width: 1200px) {
    .stats-chart-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The three cards stay side by side all the way down — stacking them into
   separate rows is what pushed this section into three screen-heights of
   scrolling. Instead the grid INSIDE each card reflows (see the container query
   below), which is the comparison this section exists to make: the three cards
   are read against each other, so they have to remain peers on one screen. */

/* The saturation section is asked to fit two things — a gauge and four metric
   cards — inside whatever box it is given. On the compare tab that box is half
   the viewport, so a viewport media query never fires at the width that actually
   breaks it: at a 1400px screen the section is 522px wide while the viewport
   still reports 1400, and the metrics were squeezed to 158px — four cards
   clipped to "C…" and "s pr…".

   Below ~620px there is no arrangement where both halves stay legible, so stack
   them. That width is the gauge's 260px plus the 24px gap plus the two metric
   columns (each an 18px icon, a 12px gap, 32px of padding and room for
   "59,26 %" at 24px). */
@container (max-width: 620px) {
    .stats-sat-layout { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 1100px) {
    .stats-split { grid-template-columns: minmax(0, 1fr); }
    .comparison-split { grid-template-columns: minmax(0, 1fr); }
}

/* Three cards side by side need ~250px each to still read, and the fixed 230px
   sidebar does not shrink with the viewport, so below ~900px the row is down to
   phone width and the cards have to stack. This is phone territory only — the
   laptop range is handled by the 3+2 container query above, which keeps the
   three cards on one screen. */
@media (max-width: 900px) {
    .stats-kpi-row { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
    .stats-ranking-grid { grid-template-columns: minmax(0, 1fr); }
    .stats-distribution-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 640px) {
    .stats-section-header { padding: 14px; gap: 10px; }
    .stats-section-icon { width: 34px; height: 34px; flex-basis: 34px; font-size: 17px; }
    .stats-section-body { padding: 4px 14px 16px; }
    .stats-section-title { font-size: 15px; }

    /* The meta line moves under the title rather than squeezing it. */
    .stats-section-meta { white-space: normal; }

    .stats-chart-grid { grid-template-columns: minmax(0, 1fr); }
    .stats-metric-grid { grid-template-columns: minmax(0, 1fr); }
    /* (.stats-kpi-grid goes two-column at 700px, above this block.) */
    .stats-ranking-row { grid-template-columns: 26px minmax(0, 1fr) 58px; }
    .stats-ranking-row .stats-crew-name { grid-column: 2; }
    .stats-ranking-row .stats-bar-track { grid-column: 2; }
    .stats-ranking-row .stats-rank-value { grid-column: 3; grid-row: 1 / span 2; }
}

/* Respect the user's reduced-motion preference for the bar + chevron motion. */
@media (prefers-reduced-motion: reduce) {
    .stats-dashboard *,
    .stats-dashboard *::before,
    .stats-dashboard *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
    }
}