/* TVIQ dashboard - design tokens and layout.
 *
 * The categorical hues are not a taste decision. They were validated with an
 * OKLab / CVD-simulation pass: weakest adjacent pair dE 19.8 against a target
 * of 8, and the first three survive an all-pairs sweep, which is what the
 * scatter and heatmap forms are capped at. Status colours are reserved - they
 * never carry a series - and are separated by lightness as well as hue so they
 * survive greyscale and colour-vision deficiency.
 */

:root {
  /* ---- surfaces and ink (light) ---- */
  --bg:            #F4F6F6;
  --surface:       #FFFFFF;
  --surface-2:     #FAFBFB;
  --surface-sunk:  #EEF1F1;
  --border:        #DFE5E4;
  --border-strong: #C7D2D0;

  --ink:           #111A19;
  --ink-2:         #3C4A48;
  --ink-3:         #667572;
  --ink-faint:     #94A3A0;

  --brand:         #0F766E;
  --brand-ink:     #0B5B55;
  --brand-wash:    #E7F3F1;

  /* ---- categorical, FIXED ORDER, never cycled ---- */
  --c1: #0F766E;  --c2: #B45309;  --c3: #6D28D9;  --c4: #9D174D;
  --c5: #0E7490;  --c6: #A16207;  --c7: #1D4ED8;  --c8: #4D7C0F;
  --c-other: #94A3A0;

  /* ---- sequential (one hue, light -> dark) ---- */
  --s1: #CCFBF1; --s2: #99F6E4; --s3: #5EEAD4; --s4: #2DD4BF;
  --s5: #14B8A6; --s6: #0D9488; --s7: #0F766E; --s8: #115E59;

  /* ---- diverging: loss <- neutral -> gain (grey midpoint, not a hue) ---- */
  --d-neg-3: #9A3412; --d-neg-2: #C2683A; --d-neg-1: #E0A882;
  --d-mid:   #E8E6E3;
  --d-pos-1: #7FB8AE; --d-pos-2: #2F8A7E; --d-pos-3: #0F766E;

  /* ---- status: RESERVED. Always with an icon and a word. ---- */
  --st-ok:        #047857;  --st-ok-wash:       #E6F4EF;
  --st-warn:      #D97706;  --st-warn-wash:     #FDF3E3;
  --st-critical:  #B91C1C;  --st-critical-wash: #FBEAEA;
  --st-nodata:    #94A3B8;  --st-nodata-wash:   #F0F3F5;

  --radius:    10px;
  --radius-sm: 7px;
  --shadow:    0 1px 2px rgba(17,26,25,.05), 0 1px 3px rgba(17,26,25,.04);
  --shadow-lg: 0 4px 16px rgba(17,26,25,.09);

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Consolas, monospace;

  --rail: 232px;
  --header: 56px;
}

:root[data-theme="dark"] {
  --bg:            #0D1211;
  --surface:       #161D1C;
  --surface-2:     #1B2423;
  --surface-sunk:  #111817;
  --border:        #2A3735;
  --border-strong: #3B4B48;

  --ink:           #E8EFED;
  --ink-2:         #B3C2BF;
  --ink-3:         #869894;
  --ink-faint:     #667572;

  --brand:         #2DD4BF;
  --brand-ink:     #5EEAD4;
  --brand-wash:    #133430;

  /* dark gets its OWN steps, validated against the dark surface -
     not an automatic inversion of the light set */
  --c1: #2DD4BF; --c2: #FBBF24; --c3: #A78BFA; --c4: #F472B6;
  --c5: #22D3EE; --c6: #FCD34D; --c7: #60A5FA; --c8: #A3E635;
  --c-other: #667572;

  --s1: #115E59; --s2: #0F766E; --s3: #0D9488; --s4: #14B8A6;
  --s5: #2DD4BF; --s6: #5EEAD4; --s7: #99F6E4; --s8: #CCFBF1;

  --d-neg-3: #F97316; --d-neg-2: #C2683A; --d-neg-1: #8A5136;
  --d-mid:   #3A4442;
  --d-pos-1: #1F5D56; --d-pos-2: #14B8A6; --d-pos-3: #5EEAD4;

  --st-ok:        #34D399; --st-ok-wash:       #10291F;
  --st-warn:      #FBBF24; --st-warn-wash:     #30250D;
  --st-critical:  #F87171; --st-critical-wash: #301515;
  --st-nodata:    #8698A4; --st-nodata-wash:   #1C2427;

  --shadow:    0 1px 2px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.3);
  --shadow-lg: 0 6px 24px rgba(0,0,0,.5);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font-family: var(--font); font-size: 14px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
button { font-family: inherit; }

/* ============================================================ app frame */
.app { display: grid; grid-template-columns: var(--rail) 1fr; min-height: 100vh; }

/* ---- rail ---- */
.rail {
  background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; position: sticky; top: 0;
  height: 100vh; overflow-y: auto;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px; height: var(--header);
  border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.brand-mark {
  width: 26px; height: 26px; border-radius: 7px; flex: 0 0 auto;
  background: linear-gradient(135deg, var(--brand), var(--c5));
  display: grid; place-items: center; color: #fff;
  font-weight: 700; font-size: 12px; letter-spacing: .02em;
}
.brand-name { font-weight: 640; letter-spacing: -.01em; font-size: 14.5px; }
.brand-sub { font-size: 11px; color: var(--ink-3); margin-top: -2px; }

.rail-group { padding: 14px 10px 4px; }
.rail-label {
  font-size: 10.5px; font-weight: 640; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-faint);
  padding: 0 8px 7px;
}
.rail-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 9px; border: 0; background: transparent; cursor: pointer;
  border-radius: var(--radius-sm); color: var(--ink-2); text-align: left;
  font-size: 13px; transition: background .12s, color .12s;
}
.rail-item:hover { background: var(--surface-sunk); color: var(--ink); }
.rail-item.is-active {
  background: var(--brand-wash); color: var(--brand-ink); font-weight: 560;
}
.rail-item .lucide { width: 16px; height: 16px; flex: 0 0 auto; }
.rail-item .no {
  margin-left: auto; font-family: var(--mono); font-size: 10.5px;
  color: var(--ink-faint);
}
.rail-item.is-active .no { color: var(--brand); }
.rail-foot {
  margin-top: auto; padding: 12px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--ink-faint);
}

/* ---- header ---- */
.main { display: flex; flex-direction: column; min-width: 0; }
.header {
  height: var(--header); flex: 0 0 auto;
  background: var(--surface); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 12px; padding: 0 20px;
  position: sticky; top: 0; z-index: 30;
}
.crumb { font-size: 12px; color: var(--ink-3); }
.crumb b { color: var(--ink); font-weight: 560; }
.header-spacer { flex: 1; }

.control { display: inline-flex; align-items: center; gap: 6px; }
.control label {
  font-size: 11px; color: var(--ink-3); font-weight: 560;
  letter-spacing: .02em;
}
.input, .select {
  height: 32px; padding: 0 9px; font-size: 12.5px; font-family: inherit;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  outline: none; transition: border-color .12s, box-shadow .12s;
}
.input:focus, .select:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent);
}
.select { padding-right: 26px; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23667572' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 8px center; }

.btn {
  height: 32px; padding: 0 11px; display: inline-flex; align-items: center;
  gap: 6px; font-size: 12.5px; font-weight: 540; cursor: pointer;
  color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  transition: background .12s, color .12s, border-color .12s;
}
.btn:hover { background: var(--surface-sunk); color: var(--ink); }
.btn .lucide { width: 14px; height: 14px; }
.btn-primary {
  background: var(--brand); border-color: var(--brand); color: #fff;
}
.btn-primary:hover { background: var(--brand-ink); color: #fff; }
.btn-icon { width: 32px; padding: 0; justify-content: center; }

/* ---- page ---- */
.page { padding: 18px 20px 40px; display: flex; flex-direction: column; gap: 14px; }

.page-head { display: flex; align-items: flex-start; gap: 16px; }
.page-title { font-size: 20px; font-weight: 660; letter-spacing: -.02em; margin: 0; }
.page-purpose { font-size: 12.5px; color: var(--ink-3); margin: 3px 0 0; max-width: 78ch; }
.page-meta {
  margin-left: auto; text-align: right; font-size: 11px; color: var(--ink-faint);
  white-space: nowrap;
}
.page-meta b { color: var(--ink-2); font-weight: 560; }

/* ---- banners ---- */
.banner {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 13px;
  border-radius: var(--radius); border: 1px solid; font-size: 12.5px;
}
.banner .lucide { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 1px; }
.banner-title { font-weight: 600; }
.banner-detail { color: var(--ink-2); }
.banner-sources {
  margin-top: 5px; display: flex; flex-wrap: wrap; gap: 5px;
}
.chip-src {
  font-family: var(--mono); font-size: 10.5px; padding: 1px 6px;
  border-radius: 4px; background: var(--surface); border: 1px solid var(--border);
  color: var(--ink-2); max-width: 260px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.banner--critical { background: var(--st-critical-wash); border-color: color-mix(in srgb, var(--st-critical) 32%, transparent); }
.banner--critical .lucide, .banner--critical .banner-title { color: var(--st-critical); }
.banner--warn { background: var(--st-warn-wash); border-color: color-mix(in srgb, var(--st-warn) 34%, transparent); }
.banner--warn .lucide, .banner--warn .banner-title { color: #92600A; }
:root[data-theme="dark"] .banner--warn .lucide,
:root[data-theme="dark"] .banner--warn .banner-title { color: var(--st-warn); }
.banner--nodata { background: var(--st-nodata-wash); border-color: color-mix(in srgb, var(--st-nodata) 34%, transparent); }
.banner--nodata .lucide, .banner--nodata .banner-title { color: var(--ink-3); }
.banner--sample { background: var(--brand-wash); border-color: color-mix(in srgb, var(--brand) 30%, transparent); }
.banner--sample .lucide, .banner--sample .banner-title { color: var(--brand-ink); }

/* ---- KPI row ---- */
.kpis { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px; }
.kpi {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 13px 10px; box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.kpi-label {
  font-size: 11px; font-weight: 580; color: var(--ink-3);
  letter-spacing: .02em; display: flex; align-items: center; gap: 5px;
}
.kpi-value {
  font-size: 22px; font-weight: 670; letter-spacing: -.025em;
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.kpi-value.is-empty { color: var(--ink-faint); font-weight: 500; font-size: 18px; }
.kpi-foot { display: flex; align-items: center; gap: 6px; margin-top: 3px; min-height: 18px; }
.kpi-delta {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11.5px; font-weight: 620; font-variant-numeric: tabular-nums;
  padding: 1px 5px 1px 3px; border-radius: 4px;
}
.kpi-delta .lucide { width: 12px; height: 12px; }
.kpi-delta.up   { color: var(--d-pos-3); background: color-mix(in srgb, var(--d-pos-3) 10%, transparent); }
.kpi-delta.down { color: var(--d-neg-3); background: color-mix(in srgb, var(--d-neg-3) 10%, transparent); }
.kpi-delta.flat { color: var(--ink-3); background: var(--surface-sunk); }
.kpi-cmp { font-size: 10.5px; color: var(--ink-faint); }
.kpi-spark { height: 26px; margin: 4px -4px -2px; }

/* ---- panels ---- */
.grid { display: grid; gap: 12px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.span-2 { grid-column: span 2; }

.panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 14px 9px; border-bottom: 1px solid var(--border);
}
.panel-title { font-size: 13px; font-weight: 620; letter-spacing: -.01em; }
.panel-sub { font-size: 11px; color: var(--ink-faint); }
.panel-tools { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.panel-body { padding: 10px 12px 12px; flex: 1; min-width: 0; }
.panel-body.flush { padding: 0; }

.seg {
  display: inline-flex; background: var(--surface-sunk);
  border-radius: var(--radius-sm); padding: 2px; gap: 2px;
}
.seg button {
  border: 0; background: transparent; cursor: pointer; color: var(--ink-3);
  font-size: 11.5px; font-weight: 560; padding: 4px 9px;
  border-radius: 5px; transition: background .12s, color .12s;
}
.seg button:hover { color: var(--ink); }
.seg button.is-active {
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow);
}

.chart { width: 100%; height: 260px; }
.chart.tall { height: 330px; }
.chart.short { height: 190px; }

/* ---- table ---- */
.table-wrap { overflow: auto; max-height: 560px; }
table.grid-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; }
.grid-table thead th {
  position: sticky; top: 0; z-index: 2; background: var(--surface-2);
  text-align: right; font-weight: 600; font-size: 11px; color: var(--ink-3);
  letter-spacing: .02em; padding: 8px 11px; white-space: nowrap;
  border-bottom: 1px solid var(--border); cursor: pointer; user-select: none;
}
.grid-table thead th:first-child { text-align: left; left: 0; z-index: 3; }
.grid-table thead th:hover { color: var(--ink); }
.grid-table thead th .lucide { width: 11px; height: 11px; vertical-align: -1px; opacity: .55; }
.grid-table tbody td {
  padding: 7px 11px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}
.grid-table tbody td:first-child {
  text-align: left; position: sticky; left: 0; background: var(--surface);
  font-weight: 540; max-width: 300px; overflow: hidden;
  text-overflow: ellipsis;
}
.grid-table tbody tr:hover td { background: var(--surface-2); }
.grid-table tbody tr:hover td:first-child { background: var(--surface-2); }
.num-neg { color: var(--d-neg-3); }
.num-pos { color: var(--d-pos-3); }
.muted { color: var(--ink-faint); }

.pill {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 620; padding: 2px 7px 2px 5px;
  border-radius: 999px; letter-spacing: .01em;
}
.pill .lucide { width: 11px; height: 11px; }
.pill--ok       { color: var(--st-ok);       background: var(--st-ok-wash); }
.pill--warn     { color: #92600A;            background: var(--st-warn-wash); }
:root[data-theme="dark"] .pill--warn { color: var(--st-warn); }
.pill--critical { color: var(--st-critical); background: var(--st-critical-wash); }
.pill--nodata   { color: var(--ink-3);       background: var(--st-nodata-wash); }

/* ---- empty / loading ---- */
.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 34px 20px; color: var(--ink-faint); text-align: center;
}
.empty .lucide { width: 22px; height: 22px; opacity: .6; }
.empty-title { font-size: 13px; font-weight: 580; color: var(--ink-3); }
.empty-detail { font-size: 11.5px; max-width: 46ch; }

.skeleton {
  background: linear-gradient(90deg, var(--surface-sunk) 25%,
              var(--surface-2) 37%, var(--surface-sunk) 63%);
  background-size: 400% 100%; animation: shimmer 1.3s ease-in-out infinite;
  border-radius: 6px;
}
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.spinner {
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--brand) 25%, transparent);
  border-top-color: var(--brand); animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- legend ---- */
.legend { display: flex; flex-wrap: wrap; gap: 10px; padding: 2px 2px 8px; }
.legend-item {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--ink-2);
}
.legend-swatch { width: 9px; height: 9px; border-radius: 2px; flex: 0 0 auto; }

/* ---- responsive ---- */
@media (max-width: 1500px) { .kpis { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 1180px) {
  .app { grid-template-columns: 1fr; }
  .rail { position: fixed; z-index: 60; width: var(--rail);
          transform: translateX(-100%); transition: transform .2s ease; }
  .rail.is-open { transform: none; box-shadow: var(--shadow-lg); }
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .span-2 { grid-column: auto; }
}
@media (max-width: 720px) {
  .kpis { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .page { padding: 14px 12px 32px; }
  .header { padding: 0 12px; gap: 8px; overflow-x: auto; }
}
.rail-toggle { display: none; }
@media (max-width: 1180px) { .rail-toggle { display: inline-flex; } }

/* ---- side toggle (Supply | Demand) -------------------------------------- */
.side-toggle {
  display: grid; grid-template-columns: 1fr 1fr; gap: 3px;
  margin: 12px 10px 4px; padding: 3px;
  background: var(--surface-sunk); border-radius: 9px;
}
.side-toggle button {
  border: 0; background: transparent; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--ink-3); padding: 7px 6px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  transition: background .14s, color .14s, box-shadow .14s;
}
.side-toggle button:hover { color: var(--ink); }
.side-toggle button .lucide { width: 14px; height: 14px; }
.side-toggle button.is-active {
  background: var(--surface); color: var(--brand-ink);
  box-shadow: var(--shadow);
}
:root[data-theme="dark"] .side-toggle button.is-active { color: var(--brand); }
.side-toggle .tcount {
  font-family: var(--mono); font-size: 10px; color: var(--ink-faint);
  font-weight: 500;
}
.side-toggle button.is-active .tcount { color: var(--brand); }

.rail-nav { padding: 6px 10px 4px; display: flex; flex-direction: column; }
.rail-nav .rail-label { margin-top: 10px; }
.rail-nav .rail-label:first-child { margin-top: 2px; }
.rail-empty {
  padding: 14px 10px; font-size: 11.5px; color: var(--ink-faint);
  line-height: 1.45;
}


/* ---- KPI panel: the tiles and their comparison control, as one object ----
 * Free-standing above the page, the control read as a filter for the whole
 * screen. Inside the panel with the tiles it belongs to, the scope is
 * unambiguous: it changes these six numbers and nothing else.
 */
.panel-kpi .panel-head { padding: 10px 14px 9px; }

.kpis--panel {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0;
}
/* Tiles are no longer cards - they are cells of one surface, divided by a
   hairline. Card-inside-card reads as two objects. */
.kpis--panel .kpi {
  border: 0; border-radius: 0; box-shadow: none;
  background: transparent;
  padding: 13px 14px 12px;
  border-right: 1px solid var(--border);
}
.kpis--panel .kpi:last-child { border-right: 0; }

@media (max-width: 1500px) {
  .kpis--panel { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .kpis--panel .kpi:nth-child(3n) { border-right: 0; }
  .kpis--panel .kpi:nth-child(-n+3) { border-bottom: 1px solid var(--border); }
}
@media (max-width: 720px) {
  .kpis--panel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpis--panel .kpi { border-right: 1px solid var(--border);
                      border-bottom: 1px solid var(--border); }
  .kpis--panel .kpi:nth-child(2n) { border-right: 0; }
  .kpis--panel .kpi:nth-last-child(-n+2) { border-bottom: 0; }
  .panel-kpi .panel-head { flex-wrap: wrap; }
  .panel-kpi .panel-tools { margin-left: 0; width: 100%; }
  .panel-kpi .seg { width: 100%; overflow-x: auto; }
}

/* The sparkline sits in one tile only, so without a floor it makes that grid
   row taller than the next and the cells stop lining up. A shared minimum and
   a bottom-anchored spark keep every cell the same height. */
.kpis--panel .kpi { min-height: 118px; }
.kpis--panel .kpi-spark { margin-top: auto; }

/* ---- trend panel controls ---- */
.panel-trend .panel-head { flex-wrap: wrap; row-gap: 7px; }
.panel-trend .panel-tools { gap: 8px; flex-wrap: wrap; }
.panel-trend .seg button { padding: 4px 8px; font-size: 11px; }
.seg-range button { font-weight: 600; }

.chart-loading {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 9px; height: 260px; color: var(--ink-faint);
  text-align: center; padding: 0 20px;
}
@media (max-width: 1180px) {
  .panel-trend .panel-tools { width: 100%; margin-left: 0; }
  .panel-trend .seg { overflow-x: auto; }
}

/* ---- Analysis panel: three views of one measure -------------------------- */
.panel-analysis .panel-head { flex-wrap: wrap; row-gap: 7px; }
.panel-analysis .panel-tools { flex-wrap: wrap; }

.analysis { display: flex; flex-direction: column; }
.analysis-row {
  display: grid; grid-template-columns: 1.15fr 1fr;
  border-bottom: 1px solid var(--border);
}
.analysis-row .sub:first-child { border-right: 1px solid var(--border); }

.sub { display: flex; flex-direction: column; min-width: 0; padding: 0 0 12px; }
.sub-head {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; row-gap: 6px;
  padding: 11px 14px 8px;
}
.sub-title { font-size: 12.5px; font-weight: 620; letter-spacing: -.01em; }
.sub-note { font-size: 11px; color: var(--ink-faint); }
.sub-tools { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.sub .chart { padding: 0 6px; }
.sub .legend { padding: 4px 14px 0; }
.sub .empty { padding: 26px 16px; }

@media (max-width: 1180px) {
  .analysis-row { grid-template-columns: 1fr; }
  .analysis-row .sub:first-child {
    border-right: 0; border-bottom: 1px solid var(--border);
  }
  .sub-tools { margin-left: 0; width: 100%; }
  .sub-tools .seg { overflow-x: auto; }
}

/* ---- table filters ---- */
.table-filters {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.input-search { min-width: 230px; }
.table-filters .sub-note { margin-left: auto; white-space: nowrap; }
.table-more {
  display: flex; justify-content: center;
  padding: 10px; border-top: 1px solid var(--border);
}
@media (max-width: 720px) {
  .table-filters .sub-note { margin-left: 0; width: 100%; }
  .input-search { min-width: 0; flex: 1; }
}

/* ---- reconciliation ---------------------------------------------------- */
/* The coverage bar is the panel's headline: one line showing what share of
   the day can be validated at all. Every segment is also named in the legend
   below it with the same swatch, so the bar never carries meaning on colour
   alone. */
.recon-bar {
  display: flex; height: 6px; width: 100%;
  background: var(--surface-sunk); overflow: hidden;
}
.recon-bar-seg { display: block; height: 100%; }
.recon-bar-seg--ok       { background: var(--st-ok); }
.recon-bar-seg--warn     { background: var(--st-warn); }
.recon-bar-seg--critical { background: var(--st-critical); }

.recon-cov {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-bottom: 1px solid var(--border); background: var(--surface-2);
}
.recon-stat { padding: 12px 14px; border-right: 1px solid var(--border); }
.recon-stat:last-child { border-right: 0; }
.recon-stat-head { display: flex; align-items: center; gap: 6px; }
.recon-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
}
.recon-dot--ok       { background: var(--st-ok); }
.recon-dot--warn     { background: var(--st-warn); }
.recon-dot--critical { background: var(--st-critical); }
.recon-stat-label {
  font-size: 11px; font-weight: 560; color: var(--ink-3);
  letter-spacing: .01em;
}
.recon-stat-value {
  font-size: 19px; font-weight: 620; color: var(--ink);
  margin-top: 4px; font-variant-numeric: tabular-nums;
}
.recon-stat-note { font-size: 11px; color: var(--ink-faint); margin-top: 2px; }

.recon-tabs {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
}
.recon-tabs .sub-note {
  margin-left: auto; max-width: 52ch; text-align: right;
}
.seg-count {
  margin-left: 5px; font-size: 10px; font-weight: 600;
  color: var(--ink-faint); font-variant-numeric: tabular-nums;
}
.seg button.is-active .seg-count { color: var(--ink-3); }

@media (max-width: 860px) {
  .recon-cov { grid-template-columns: 1fr; }
  .recon-stat { border-right: 0; border-bottom: 1px solid var(--border); }
  .recon-tabs .sub-note { margin-left: 0; text-align: left; max-width: none; }
}

/* A folded discrepancy row names the tags it stands for. */
.recon-members {
  display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px;
}
.recon-members .chip-src { font-size: 10.5px; }

/* ---- ranked bars (drop reasons, completion) ---------------------------- */
/* Not ECharts: these labels are sentences, and no chart axis renders
   "UA/device type is missing or OS & bundle/domain conflict with the traffic
   type" legibly. A div also needs no instance to dispose. */
.bars { display: flex; flex-direction: column; gap: 7px; }
.bar-row {
  display: grid; grid-template-columns: minmax(0, 300px) 1fr 132px;
  align-items: center; gap: 12px;
}
.bar-label {
  font-size: 12px; color: var(--ink-2); min-width: 0;
  display: flex; align-items: center; gap: 6px;
}
.bar-label > span:first-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bar-track {
  height: 16px; background: var(--surface-sunk);
  border-radius: 3px; overflow: hidden;
}
.bar-fill { display: block; height: 100%; border-radius: 3px; }
.bar-fill--malformed { background: var(--c2); }
.bar-fill--scope     { background: var(--c5); }
.bar-fill--other     { background: var(--c-other); }
.bar-fill--seq       { background: var(--s6); }
.bar-value {
  font-size: 12px; color: var(--ink); text-align: right;
  font-variant-numeric: tabular-nums;
}
.bar-dot--malformed { background: var(--c2); }
.bar-dot--scope     { background: var(--c5); }
.bar-dot--other     { background: var(--c-other); }

.bar-legend {
  display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 14px;
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.bar-legend-item {
  display: flex; align-items: center; gap: 6px; font-size: 11.5px;
  color: var(--ink-2);
}
.bar-owner {
  font-size: 10.5px; color: var(--ink-faint);
  background: var(--surface-sunk); padding: 1px 6px; border-radius: 3px;
}

/* ---- delivery quality rows --------------------------------------------- */
.qual { display: flex; flex-direction: column; }
.qual-row {
  display: grid; grid-template-columns: 1fr auto auto auto;
  align-items: center; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.qual-row:last-child { border-bottom: 0; }
.qual-label { font-size: 12px; color: var(--ink-2); }
.qual-now {
  font-size: 15px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.qual-was {
  font-size: 11px; color: var(--ink-faint); min-width: 86px;
  text-align: right; font-variant-numeric: tabular-nums;
}
.qual-delta { min-width: 76px; display: flex; justify-content: flex-end; }

@media (max-width: 720px) {
  .bar-row { grid-template-columns: 1fr; gap: 4px; }
  .bar-value { text-align: left; }
  .qual-row { grid-template-columns: 1fr auto; row-gap: 4px; }
}

/* A filtered panel keeps its body inset while the filter bar sits flush. */
.panel-inset { padding: 14px; }

/* ---- IVT composition + detection categories ---------------------------- */
.chart-bar { width: 100%; height: 34px; }
.comp-dot--valid { background: var(--s3); }
.comp-dot--givt  { background: var(--c2); }
.comp-dot--sivt  { background: var(--c4); }
.bar-fill--givt  { background: var(--c2); }
.bar-fill--sivt  { background: var(--c4); }

.sub-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.sub-head > span:first-child {
  font-size: 12px; font-weight: 600; color: var(--ink);
}
.sub-head .sub-note { max-width: 62ch; }
.panel-inset + .panel-inset { border-top: 1px solid var(--border); }

/* A five-point curve does not need a full-height chart. */
.chart.mini { height: 150px; }

.ivt-headline {
  display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.ivt-rate {
  font-size: 26px; font-weight: 650; color: var(--ink);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.ivt-rate-note { font-size: 11.5px; color: var(--ink-3); }

/* ---- bid-path legs ----------------------------------------------------- */
/* Faults share one colour across both legs so "something is broken" reads
   the same on either side of the path; everything else is neutral, because
   a QPS ceiling and a no-bid are not problems. */
.leg-dot--fault     { background: var(--st-critical); }
.leg-dot--capacity  { background: var(--c5); }
.leg-dot--targeting { background: var(--c3); }
.leg-dot--ours      { background: var(--c1); }
.leg-dot--nobid     { background: var(--c-other); }
.leg-dot--auction   { background: var(--c-other); }
.leg-dot--creative  { background: var(--c6); }
.leg-dot--other     { background: var(--c-other); }

.bar-fill--fault     { background: var(--st-critical); }
.bar-fill--capacity  { background: var(--c5); }
.bar-fill--targeting { background: var(--c3); }
.bar-fill--ours      { background: var(--c1); }
.bar-fill--nobid     { background: var(--c-other); }
.bar-fill--auction   { background: var(--c-other); }
.bar-fill--creative  { background: var(--c6); }

.seg button svg { width: 12px; height: 12px; margin-right: 4px; }

/* ---- alerts button + modal --------------------------------------------- */
/* The button is the only thing on the page that still shouts. Its tone is
   the worst level present, and the count sits inside it, so the header says
   "four things, one of them serious" without spending a screen on it. */
.btn-alerts { gap: 7px; }
.alert-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 2px;
  border-radius: 9px; font-size: 11px; font-weight: 650;
  font-variant-numeric: tabular-nums;
  background: var(--surface-sunk); color: var(--ink-2);
}
.btn-alerts.is-critical {
  border-color: var(--st-critical); color: var(--st-critical);
}
.btn-alerts.is-critical .alert-count {
  background: var(--st-critical); color: #fff;
}
.btn-alerts.is-warn { border-color: var(--st-warn); color: var(--st-warn); }
.btn-alerts.is-warn .alert-count { background: var(--st-warn); color: #fff; }
.btn-alerts.is-nodata .alert-count { background: var(--st-nodata-wash); }

.modal-root {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(17, 26, 25, .42);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 64px 20px 32px; overflow-y: auto;
  animation: modal-in .14s ease-out;
}
@keyframes modal-in { from { opacity: 0; } to { opacity: 1; } }
.modal {
  width: min(760px, 100%); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; padding: 15px 16px; border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.modal-title { font-size: 15px; font-weight: 640; color: var(--ink); }
.modal-sub { font-size: 11.5px; color: var(--ink-3); margin-top: 3px; }
.modal-body { padding: 4px 16px 16px; max-height: 72vh; overflow-y: auto; }

.alert-list { display: flex; flex-direction: column; }
.alert-group {
  display: flex; align-items: center; gap: 8px;
  padding: 16px 0 8px; position: sticky; top: 0;
  background: var(--surface);
}
.alert-group-note { font-size: 11px; color: var(--ink-faint); }
.alert-item {
  display: flex; gap: 10px; padding: 11px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); margin-bottom: 8px;
  background: var(--surface-2);
}
.alert-item svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.alert-item--critical { border-left: 3px solid var(--st-critical); }
.alert-item--critical svg { color: var(--st-critical); }
.alert-item--warn { border-left: 3px solid var(--st-warn); }
.alert-item--warn svg { color: var(--st-warn); }
.alert-item--nodata { border-left: 3px solid var(--st-nodata); }
.alert-item--nodata svg { color: var(--st-nodata); }
.alert-title { font-size: 13px; font-weight: 620; color: var(--ink); }
.alert-detail {
  font-size: 12px; color: var(--ink-2); margin-top: 2px; line-height: 1.45;
}

@media (max-width: 720px) {
  .modal-root { padding: 16px 12px; }
  .modal-body { max-height: none; }
}
