/* AROS tile composition — rules 4, 11, 12 of docs/aros-design-language.md.
   Card = bar + body + bar; zones anchored so a row of tiles aligns on one line.
   The markup in index.html (.aros-kpi / .aros-panel) exists only for these rules. */

/* ── KPI row ──────────────────────────────────────────────────────────────── */

.aros-kpirow {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-3, 12px);
  align-items: stretch;
}

/* Rule 11: equal height + space-between is what puts every label, every value
   and every rail on one line across the row. Without both, tiles centre their
   content and nothing aligns. */
.aros-kpi {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  min-height: 132px;
  padding: 14px 16px;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-md, 10px);
  box-shadow: none;
}

.aros-kpi-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2, 8px);
  min-height: 14px;
}

.aros-kpi-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted, #6B6A65);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.aros-kpi-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--color-text-subtle, #96948D);
  white-space: nowrap;
  flex: none;
}

.aros-kpi-mid { display: flex; align-items: baseline; gap: 2px; }

.aros-kpi-value {
  font-size: clamp(24px, 2.1vw, 34px);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.05;
  color: var(--color-text, #24231F);
  font-variant-numeric: tabular-nums;
}

/* Rule 2: the unit is demoted, never the same weight as the number. */
.aros-kpi-unit {
  font-size: .52em;
  font-weight: 500;
  color: var(--color-text-muted, #6B6A65);
  letter-spacing: 0;
  align-self: baseline;
}
.aros-kpi-mid .aros-kpi-unit { font-size: clamp(13px, 1.1vw, 17px); }

.aros-kpi-rail {
  display: flex;
  align-items: center;
  gap: var(--space-2, 8px);
  min-height: 14px;
}

.aros-kpi-track {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--color-surface-sunken, #EBEAE4);
  overflow: hidden;
}

.aros-kpi-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--color-text, #24231F);
}
.aros-kpi-fill[data-tone="warn"]   { background: var(--color-status-warning, #C68A2E); }
.aros-kpi-fill[data-tone="breach"] { background: var(--color-status-critical, #C0453B); }
.aros-kpi-fill[data-tone="ok"]     { background: var(--color-status-good, #3E7A56); }

.aros-kpi-cap {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--color-text-subtle, #96948D);
  white-space: nowrap;
  flex: none;
}

/* An empty rail must still occupy its line, or the tile above it grows and the
   row stops aligning. */
.aros-kpi-rail:empty::before { content: ''; display: block; height: 4px; }

/* ── KPI card anatomy (the five primary tiles) ─────────────────────────────────
   Three planes: padded type stack, a full-bleed sparkline band, a comparison
   strip. The secondary tiles keep the plain rail anatomy above, which is why
   every rule here is scoped to .aros-kpi--card. */

.aros-kpi--card {
  gap: 0;
  padding: 0;
  overflow: hidden;
  justify-content: flex-start;
}

.aros-kpi-pad {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 13px 15px 10px;
}

.aros-kpi--card .aros-kpi-mid { align-items: baseline; }

/* Reserved even when empty: a metric with no running period must not sit 20px
   higher than its neighbours (rule 11). */
.aros-kpi-estrow {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 17px;
}
.aros-kpi-estrow .aros-kpi-cap { margin-left: auto; }

/* Rule 8: a projection is dashed and pill-shaped, and never looks like an actual.
   Tinted by whether the run-rate tracks above or below the last complete period —
   the direction is the semantic part, not the estimate itself. */
.aros-kpi-est {
  display: inline-flex;
  align-items: center;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: 2px 7px;
  border: 1px dashed currentColor;
  border-radius: var(--radius-pill, 999px);
  white-space: nowrap;
  flex: none;
}
.aros-kpi-est:empty { display: none; }

/* "EST AUG 26 ₹1.38CR" ran together as one string — which period and which figure
   are two different things. A hairline rule separates them; a literal "|" would be
   another glyph in a pill that is already dense. */
.aros-kpi-est-k { flex: none; }
.aros-kpi-est-v {
  margin-left: 6px;
  padding-left: 6px;
  border-left: 1px solid color-mix(in srgb, currentColor 45%, transparent);
  letter-spacing: .02em;
}
.aros-kpi-est[data-tone="up"]   { color: var(--color-status-good-text, #0A7D0A);     background: var(--color-status-good-surface, #E7F2E7); }
.aros-kpi-est[data-tone="warn"] { color: var(--color-status-warning-text, #8A5A00);  background: var(--color-status-warning-surface, #FBF0DC); }
.aros-kpi-est[data-tone="down"] { color: var(--color-status-critical-text, #C0272B); background: var(--color-status-critical-surface, #FBEAEA); }
.aros-kpi-est[data-tone="flat"] { color: var(--color-text-muted, #6B6A65);           background: var(--color-surface-alt, #F2F1ED); }

/* The band is its own plane — hairline above, flush to both edges, no padding. */
.aros-kpi-band {
  position: relative;
  margin-top: auto;
  border-top: 1px solid var(--color-border, #E4E3DE);
  line-height: 0;
}
.aros-kpi-band > svg { display: block; width: 100%; height: auto; }

/* Deep blue: the viz blue at its darkest step, so the strip answers the sparkline
   above it without becoming a series colour. White clears 10.52:1 and the 74%
   basis line 7.8:1 — computed, not eyeballed. */
.aros-kpi-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding: 6px 10px 7px;
  background: var(--aros-kpi-strip, #16406F);
}
.aros-kpi-strip:empty { display: none; }

.aros-kpi-fig {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 0;
  border-left: 1px solid rgba(255,255,255,.22);
}
.aros-kpi-fig:first-child { border-left: 0; }

.aros-kpi-figk {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #FFFFFF;
}

.aros-kpi-figv {
  display: flex;
  align-items: center;
  gap: 3px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #FFFFFF;
  font-variant-numeric: tabular-nums;
}
/* Same trap as the trend cards: `.chart-body svg` in the legacy sheet is (0,1,1)
   and would size this arrow by percentage. Scope, don't escalate. */
.aros-kpi-strip .aros-kpi-arrow { flex: none; display: block; width: 8px; height: 8px; }

/* The denominator sits under its own column, the same anatomy as the trend cards.
   It is the short form ("VS JUN 26") because a column is only ~66px wide at tile
   size — the full "JUL 26 / JUN 26" belongs on the wider cards. */
.aros-kpi-figb {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 8px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255,255,255,.74);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ── Panels ───────────────────────────────────────────────────────────────── */

/* Rule 11/12: a fixed row height is what makes a row of panels read as one row.
   Panels used to size to their own content — a 37-outlet list came out 996px and
   its neighbour 456px, so every row was ragged and one long list dragged a whole
   row to triple height. Rows are now a constant; charts fill it (see
   getChartDimensions) and long lists scroll inside it (.aros-scroll). */
/* grid-template-rows sizes the FIRST row only; every implicit row after it takes
   grid-auto-rows. That is what lets the hero panel be taller than the rest without
   giving up the uniform row height that makes a row read as a row — the full-width
   revenue trend looked squat at the standard 400px. */
.aros-panels {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  /* Row 2 holds the trend cards: bar + 2×(name / number / spark / 3-line strip).
     At 470px each card's sparkline came out 49px, which is a hairline rather than
     a trend — 530px puts it near 80px without breaking the uniform-row read. */
  grid-template-rows: var(--aros-row-hero, 520px) var(--aros-row-tall, 530px);
  grid-auto-rows: var(--aros-row-h, 400px);
  gap: var(--space-4, 16px);
  align-items: stretch;
}
/* Define every span, not just the ones in use today — an undefined span falls
   back to auto-placement, which silently collapses the panel to one column. */
.aros-span-1  { grid-column: span 1; }
.aros-span-2  { grid-column: span 2; }
.aros-span-3  { grid-column: span 3; }
.aros-span-4  { grid-column: span 4; }
.aros-span-5  { grid-column: span 5; }
.aros-span-6  { grid-column: span 6; }
.aros-span-7  { grid-column: span 7; }
.aros-span-8  { grid-column: span 8; }
.aros-span-9  { grid-column: span 9; }
.aros-span-10 { grid-column: span 10; }
.aros-span-11 { grid-column: span 11; }
.aros-span-12 { grid-column: span 12; }

/* Rule 4: a card is bar + body + bar. overflow:hidden is what makes the bars
   full-bleed against the rounded corners instead of leaving a pale gutter. */
.aros-panel {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-lg, 14px);
  box-shadow: none;
}

/* THE BAR IS OWNED HERE, END TO END — structure, type, controls and the dark
   variant. signature.css's generic bar block is scoped `:not(.aros-panel)` and
   cannot reach this node. Anything the bar needs goes in this section; adding a
   second owner is what clipped all nine bars off the card and hid every title.
   `margin: 0` is load-bearing: components.css `.chart-header` sets a bottom
   margin and the legacy card pulled the bar out with a negative one. */
/* Sand on every bar. Rebinding the three --aros-sig-bar-* vars HERE re-skins the
   primary block below too (it reads them for background, title, pills and the flip
   button), so one declaration covers both bar kinds with no duplicated rules.
   Scoped to the bar, not the panel: `.aros-segpill.is-active` also reads
   --aros-sig-bar-bg and those pills live in a panel BODY — rebinding on the panel
   would inherit down and paint the active pill sand-on-sand.
   #241F1A on #E6D8C7 measures 11.67:1; the muted step lands at ~7.5:1. */
.aros-panelbar {
  --aros-sig-bar-bg: #E6D8C7;
  --aros-sig-bar-fg: #241F1A;
  --aros-sig-bar-fg-muted: rgba(36,31,26,.66);
  --aros-sig-bar-line: rgba(36,31,26,.20);

  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  min-height: 34px;
  margin: 0;
  padding: 0 14px;
  background: var(--aros-sig-bar-bg);
  border-bottom: 1px solid var(--aros-sig-bar-line);
  border-radius: 0;
}

.aros-panelbar .chart-title,
.aros-panelbar h2 {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  min-width: 0;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text, #24231F);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Rule 6: the title icon is chrome, never a series hue. */
.aros-panelbar .chart-title svg {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--color-text-subtle, #96948D);
  opacity: 1;
}

.aros-panelbar .chart-desc {
  margin: 0;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.aros-panelbar-ctl { display: flex; align-items: center; gap: var(--space-2, 8px); flex: none; }

/* Controls on a light bar: the legend/toggle loses its own surface — the bar
   already is the nested surface (rule 3). */
.aros-panelbar .chart-group-toggle,
.aros-panelbar .oos-pill-row {
  flex: none;
  gap: 4px;
  padding: 0;
  border: 0;
  background: transparent;
}

.aros-panelbar .group-pill {
  padding: 2px 8px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  background: transparent;
  border-color: transparent;
  color: var(--color-text-muted, #6B6A65);
}
.aros-panelbar .group-pill.active {
  background: var(--color-surface, #fff);
  border-color: var(--color-border, #E4E3DE);
  color: var(--color-text, #24231F);
}

.aros-panelbar .flip-btn {
  background: transparent;
  border: 1px solid var(--color-border, #E4E3DE);
  color: var(--color-text-muted, #6B6A65);
}

/* Rule 5 no longer discriminates by colour — every bar is sand now, at the owner's
   request, so `--primary` only differs in the pill treatment inherited from the vars
   above. Keeping the block because it is what applies them. */
.aros-panel--primary > .aros-panelbar {
  background: var(--aros-sig-bar-bg, #1B1F26);
  border-bottom-color: var(--aros-sig-bar-bg, #1B1F26);
}
.aros-panel--primary > .aros-panelbar .chart-title,
.aros-panel--primary > .aros-panelbar h2 { color: var(--aros-sig-bar-fg, rgba(255,255,255,.94)); }
.aros-panel--primary > .aros-panelbar .chart-title svg,
.aros-panel--primary > .aros-panelbar .chart-desc { color: var(--aros-sig-bar-fg-muted, rgba(255,255,255,.62)); }
.aros-panel--primary > .aros-panelbar .group-pill {
  color: var(--aros-sig-bar-fg-muted, rgba(255,255,255,.62));
  border-color: transparent;
  background: transparent;
}
.aros-panel--primary > .aros-panelbar .group-pill.active {
  background: var(--aros-sig-bar-fg, rgba(255,255,255,.94));
  border-color: transparent;
  color: var(--aros-sig-bar-bg, #1B1F26);
}
.aros-panel--primary > .aros-panelbar .flip-btn {
  background: transparent;
  border-color: var(--aros-sig-bar-line, rgba(255,255,255,.16));
  color: var(--aros-sig-bar-fg-muted, rgba(255,255,255,.62));
}

/* min-height:0 is what lets the body actually shrink to the row and hand its
   leftover height to the chart; without it a flex child refuses to go below its
   content height and the fixed row is overrun. */
.aros-panel-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
  padding: 14px;
}

.aros-panel-body > .chart-body { flex: 1; min-height: 0; }

/* The svg fits the box it is in, whatever height that box ended up. Charts are
   sized in JS at render time, but the footer strip and the outlet pill row lay
   out AFTER the data arrives — they took ~28px and ~73px back off the body, and
   the already-drawn svg overflowed by exactly that. styles.css sets
   `height: auto`, which keeps the drawn height; with a viewBox and
   preserveAspectRatio already in place, 100% simply scales it to fit instead. */
.aros-panel-body > .chart-body:not(.aros-scroll) > svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* A scrolling body is the exception: its svg keeps its drawn height and the card
   scrolls to it. Scaling it to fit turned 37 outlet rows into an illegible
   thumbnail — the whole reason the card scrolls is that the list is taller. */
.aros-panel-body > .chart-body.aros-scroll > svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Sand, matching the bar — a card is then one closed object: sand top, content,
   sand bottom. The ink is the bar's muted step rather than the page's subtle grey,
   which measured ~2.9:1 on this ground and failed AA for small type. */
.aros-panelfoot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  padding: 8px 14px;
  background: #E6D8C7;
  border-top: 1px solid rgba(36,31,26,.20);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .04em;
  color: rgba(36,31,26,.72);
}
/* Reserved, not removed. Charts are sized in JS the moment their data lands, but
   the footer only un-hides afterwards (setPanelFoot) — so it took ~29px back off
   an already-drawn svg. The svg keeps a viewBox and preserveAspectRatio, so the
   mismatch did not clip it, it LETTERBOXED it: the plot shrank to fit the shorter
   box and sat centred with ~150px of dead space either side of a full-width card.
   Holding the space from the start means the drawn size is the final size. */
.aros-panelfoot[hidden] { visibility: hidden; }
.aros-foot-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aros-foot-r { flex: none; }

/* ── Waffle: one whole, counted (rules 6, 10, 11, 12) ─────────────────────────
   1 cell = 1% of takings. Grid left, key right, basis caption pinned to the
   bottom of the key column so the panel's own footer strip stays free. */

/* Centred, not stretched: the grid is square by construction, so it can never
   fill an arbitrary card height. Distributing the slack above and below reads as
   deliberate, where pinning it to the top left a ~110px void under the grid. */
/* Keys to the RIGHT of the grid, which is what the unused width was for. The grid
   is capped at 260px rather than the original 210px — that cap is what made the
   cells 19px — leaving ~180px for the key column, enough for the longest label
   ("SWIGGY DINE OUT") plus its figure without truncation. */
.aros-waffle {
  display: flex;
  flex-direction: row;
  align-items: center;
  /* Centre the pair, so leftover width is split either side instead of pooling to
     the right of the key column. */
  justify-content: center;
  gap: var(--space-4, 16px);
  height: 100%;
  min-height: 0;
}

/* Square cells, by request. That squareness is what bounds the grid: 10 rows of
   squares are exactly as tall as the grid is wide, so a full-width grid in a 440px
   panel would be 440px tall and push the keys out of the card. Hence the 300px cap
   and the unused width to its right — the cost of keeping cells square. */
.aros-waffle-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 3px;
  flex: none;
  align-content: start;
  width: min(60%, 260px);
  max-height: 100%;
}

.aros-waffle-cell {
  aspect-ratio: 1;
  border-radius: 2px;
  cursor: pointer;
}

/* Sized by its content, not flex:1 — a greedy key column would eat the leftover
   width and there would be nothing left to centre. */
.aros-waffle-side {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3, 12px);
  flex: 0 1 auto;
  min-width: 0;
  max-width: 200px;
}

/* A ruled list, not a loose stack: one hairline per row anchors the swatch, the
   name and the figure on three fixed x-positions (rule 11), and the figures are
   tabular so the decimal points line up down the column. */
.aros-waffle-keys { display: flex; flex-direction: column; }

.aros-waffle-key {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 4px;
  margin: 0 -4px;
  border-radius: var(--radius-sm, 5px);
  border-top: 1px solid var(--color-border, #E4E3DE);
  cursor: default;
}
.aros-waffle-key:first-child { border-top: 0; }
.aros-waffle-key:hover { background: var(--color-surface-alt, #F2F1ED); }

.aros-waffle-sw {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 2px;
}

.aros-waffle-k {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-muted, #6B6A65);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.aros-waffle-v {
  margin-left: auto;
  flex: none;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--color-text, #24231F);
  font-variant-numeric: tabular-nums;
}

/* Rule 9: the basis of the figure sits next to it. */
.aros-waffle-note {
  padding-top: var(--space-2, 8px);
  border-top: 1px solid var(--color-border, #E4E3DE);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--color-text-subtle, #96948D);
}

/* Rule 1 + 6: a best/peak annotation on a chart is a label, and it is marked by
   ink rather than by a second hue. */
.aros-chart-mark {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .08em;
  fill: var(--aros-sig-bar-bg, #1B1F26);
}

/* ── Trend cards: paged small multiples (rules 2, 4, 7, 8, 9, 11, 12) ────────
   Card anatomy, per tile: name + chips / big composed number + delta / the basis
   of that comparison / sparkline / footer strip of three labelled figures.
   Two across, four per page — the anatomy needs the room, and the estate has 47
   branches, so the grid pages rather than shrinks. */

.aros-tcards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(0, 1fr);
  gap: var(--space-3, 12px);
  height: 100%;
  min-height: 0;
}

/* Four separate rounded tiles rather than cells of one divided block. Each owns
   its border and radius, and clips its own footer strip to the bottom corners —
   which is what `overflow: hidden` is for here, since the strip reaches the card
   edges with negative margins. Separate tiles also means an unfilled grid slot is
   simply empty, never a grey block. */
.aros-tcard {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-width: 0;
  min-height: 0;
  padding: 11px 14px 0;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-md, 10px);
  overflow: hidden;
}

.aros-tcard-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

.aros-tcard-name {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--color-text-muted, #6B6A65);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Rule 7 / rule 8: state and estimates travel in mono uppercase chips. */
.aros-chip {
  flex: none;
  padding: 1px 5px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: var(--radius-sm, 5px);
  border: 1px solid var(--color-border, #E4E3DE);
  color: var(--color-text-muted, #6B6A65);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Tinted pill, still dashed — the dash is rule 8 (this figure is inferred, not
   measured), the tint is rule 6 (it says whether the running period is tracking
   above or below the last complete one). Colour without that meaning would be
   decoration; a grey chip on a grey card was invisible. */
.aros-chip--est {
  border-style: dashed;
  border-radius: var(--radius-pill, 999px);
  padding: 1px 7px;
  border-color: var(--color-border-strong, #A8A79E);
  background: var(--color-surface-alt, #F2F1ED);
  color: var(--color-text-muted, #6B6A65);
}
.aros-chip--est[data-tone="up"] {
  background: var(--color-status-good-surface, rgba(12,163,12,.10));
  border-color: var(--color-status-good, #0CA30C);
  color: var(--color-status-good-text, #0A7D0A);
}
.aros-chip--est[data-tone="warn"] {
  background: var(--color-status-warning-surface, rgba(250,178,25,.16));
  border-color: var(--color-status-warning, #FAB219);
  color: var(--color-status-warning-text, #8A6100);
}
.aros-chip--est[data-tone="down"] {
  background: var(--color-status-critical-surface, rgba(208,59,59,.10));
  border-color: var(--color-status-critical, #D03B3B);
  color: var(--color-status-critical-text, #C0272B);
}

.aros-tcard-value {
  display: flex;
  align-items: baseline;
  gap: 3px;
  margin-top: 3px;
  min-width: 0;
}

.aros-tcard-num {
  font-size: clamp(20px, 1.8vw, 27px);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.1;
  color: var(--color-text, #24231F);
  font-variant-numeric: tabular-nums;
}

.aros-tcard-unit {
  font-size: .55em;
  font-weight: 500;
  color: var(--color-text-muted, #6B6A65);
}

.aros-tcard-delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-left: 5px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 10px;
  font-weight: 600;
  color: var(--color-text-subtle, #96948D);
  font-variant-numeric: tabular-nums;
}
.aros-tcard-delta .aros-tcard-arrow { width: 8px; height: 8px; }
.aros-tcard-delta[data-tone="up"]   { color: var(--color-status-good-text, #0A7D0A); }
.aros-tcard-delta[data-tone="down"] { color: var(--color-status-critical-text, #C0272B); }

/* The period the headline number belongs to, on the number's own baseline. */
.aros-tcard-per {
  margin-left: auto;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--color-text-subtle, #96948D);
  white-space: nowrap;
  flex: none;
}

/* Rule 9: the derivation sits with the figure. */
.aros-tcard-basis {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 8.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--color-text-subtle, #96948D);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.aros-tcard-plot { flex: 1; min-height: 0; margin: 6px 0 5px; }
.aros-tcard-plot > svg { display: block; }

/* Rule 4: a TINTED FULL-BLEED FOOTER STRIP, flush to the card edges — the same
   nested surface the panel bars use. This was a plain border-top with 8px labels,
   which read as fine print rather than as the card's three headline comparisons.
   Negative margins are what reach past the card's own padding to the edges.
   Rule 11: the three columns share x-positions across every card in the grid. */
.aros-tcard-foot {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0 -14px 0;
  /* Three lines now (label / figure / basis), so the strip needs the extra 2px. */
  padding: 6px 12px 7px;
  /* Deep forest, chosen over the grey it replaced (#50555C) — grey read as unfinished
     across four tiles. White text clears 11.93:1 on it and the 74% basis line 8.8:1,
     both computed rather than eyeballed. Direction is carried by the drawn arrows, not
     by this ground: green is the semantic "good" hue, so the FIGURES stay white and
     never inherit it — otherwise a falling metric would sit on a green field. */
  background: var(--aros-strip, #1F3D2B);
  border-top: 1px solid var(--aros-strip, #1F3D2B);
}

.aros-tcard-fig {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
  /* A hairline anchors each column's x-position instead of relying on the gap.
     Centring means the padding must be symmetric or the label sits off-centre
     within its own third. */
  border-left: 1px solid rgba(255,255,255,.22);
}
.aros-tcard-fig:first-child { border-left: 0; }

.aros-tcard-figk {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #FFFFFF;
}

/* Every figure on the strip is pure white — the pastel green/red steps read as
   "not white" against it, and the drawn arrow already carries direction. */
.aros-tcard-figv {
  display: flex;
  align-items: center;
  gap: 3px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: #FFFFFF;
  font-variant-numeric: tabular-nums;
}

/* The width/height ATTRIBUTES are not enough, and neither is a bare class:
   `.chart-body svg { width:100%; height:auto }` in the legacy styles.css is
   specificity (0,1,1) and reaches every svg inside a card body, so the arrow grew
   to 50px — the strip went to 92px tall and squeezed every sparkline to 3.5px.
   Scoped to its owning component (0,2,0) rather than fought with !important. */
.aros-tcard .aros-tcard-arrow { flex: none; display: block; width: 9px; height: 9px; }

/* Rule 9: the basis, on the strip rather than hidden in a title attribute. */
.aros-tcard-figb {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255,255,255,.74);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ── Pager (lives in the panel's footer strip) ─────────────────────────────── */

.aros-pager { display: flex; align-items: center; gap: 6px; flex: none; }

.aros-pager-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  font-size: 13px;
  line-height: 1;
  color: var(--color-text-muted, #6B6A65);
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-sm, 5px);
  cursor: pointer;
}
.aros-pager-btn:hover:not(:disabled) {
  color: var(--color-text, #24231F);
  border-color: var(--color-border-strong, #A8A79E);
}
.aros-pager-btn:disabled { opacity: .38; cursor: default; }

.aros-pager-lbl {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  letter-spacing: .06em;
  color: var(--color-text-subtle, #96948D);
  font-variant-numeric: tabular-nums;
  min-width: 26px;
  text-align: center;
}

/* Two across needs the width; below that one card per row, still four per page. */
@media (max-width: 900px) {
  .aros-tcards { grid-template-columns: minmax(0, 1fr); }
}

/* ── Segmented value pills under a chart ──────────────────────────────────── */

.aros-segpills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2, 8px);
  margin-top: var(--space-3, 12px);
  flex: none;
}

/* Same reservation as the footer: renderOutletPills() fills this after the chart
   has been drawn and sized, and it is ~44px tall. Reserving it keeps the chart's
   drawn aspect equal to its final box. */
.aros-segpills:empty { min-height: 44px; }

.aros-segpill {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 14px;
  min-width: 92px;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-md, 10px);
  cursor: pointer;
}
/* Class names follow renderOutletPills() in app.js: it emits `aros-segpill-l`
   and `is-active`. These were `-k` and `.active` and matched nothing, so the
   selected outlet pill rendered identically to the other six. */
.aros-segpill-l {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted, #6B6A65);
}
.aros-segpill-v {
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text, #24231F);
}
.aros-segpill.is-active {
  background: var(--aros-sig-bar-bg, #1B1F26);
  border-color: var(--aros-sig-bar-bg, #1B1F26);
}
.aros-segpill.is-active .aros-segpill-l { color: var(--aros-sig-bar-fg-muted, rgba(255,255,255,.62)); }
.aros-segpill.is-active .aros-segpill-v { color: var(--aros-sig-bar-fg, rgba(255,255,255,.94)); }

/* ── Rule 11: list rows on fixed column x-positions ───────────────────────────
   The vocabulary renderTopBranchesList() in app.js emits. It shipped with no
   CSS at all, so ten rows of spans rendered as one run-together paragraph.
   Five anchored columns: mark | name + sub | value | measurement | share.
   Every row shares them, which is the whole point of the rule. */

.aros-rows { list-style: none; margin: 0; padding: 0; }

.aros-row {
  display: grid;
  grid-template-columns: 6px minmax(0, 1.5fr) auto minmax(0, 1.2fr) 44px;
  align-items: center;
  gap: var(--space-3, 12px);
  padding: 7px 0;
  border-bottom: 1px solid var(--color-border, #E4E3DE);
}
.aros-row:last-child { border-bottom: 0; }

/* Rule 6: the mark is the one data blue, not a per-row identity colour. */
.aros-row-mark {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--aros-sig-blue, #1D5BB8);
}

.aros-row-id { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

.aros-row-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--color-text, #24231F);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.aros-row-sub {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-subtle, #96948D);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Rule 2: value + demoted unit, tabular so the column reads as a rule. */
.aros-row-val {
  display: flex;
  align-items: baseline;
  gap: 1px;
  justify-content: flex-end;
  font-variant-numeric: tabular-nums;
}
.aros-row-num {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--color-text, #24231F);
}
.aros-row-unit {
  font-size: 9.5px;
  font-weight: 500;
  color: var(--color-text-muted, #6B6A65);
}

/* Rule 10: measurement is a thin bar, never a pie. */
.aros-row-desc { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

.aros-row-track {
  height: 4px;
  border-radius: 999px;
  background: var(--color-surface-sunken, #EBEAE4);
  overflow: hidden;
}
.aros-row-track > i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--aros-sig-blue, #1D5BB8);
}

.aros-row-descText {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--color-text-subtle, #96948D);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Rule 7: share travels as a mono chip, right-anchored on its own x-position. */
.aros-row-chip {
  justify-self: end;
  padding: 2px 5px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  letter-spacing: .04em;
  color: var(--color-text-muted, #6B6A65);
  background: var(--color-surface-alt, #F2F1ED);
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-sm, 5px);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The brand summary flips in a .pnl-table, which signature.css already styles;
   this only has to be a full-width host that scrolls itself, never the page. */
.aros-listtable { width: 100%; overflow-x: auto; }

/* A panel whose fetch failed — app.js toggles this. Marked, not hidden, and by
   the bar rather than by tinting the whole card (rule 6: colour carries meaning). */
.aros-panel--failed > .aros-panelbar {
  background: var(--color-status-critical-surface, rgba(208,59,59,.10));
  border-bottom-color: var(--color-status-critical, #D03B3B);
}
.aros-panel--failed > .aros-panelbar .chart-title { color: var(--color-status-critical-text, #C0272B); }

/* Page meta strip. Left: page name. Right: the active filter context. */
.aros-meta { display: block; }
.aros-meta-ctx {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  margin-bottom: var(--space-3, 12px);
}
.aros-meta-page {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text, #24231F);
  flex: none;
}

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

/* Below the 12-column grid's comfortable width every panel goes full width. This
   listed only span-8 and span-4 — the spans that happened to be in the markup at
   the time — so re-planning the rows (revenue is now span-12) would have left
   span-6 panels stuck in a half-width column on a narrow laptop. Match on the
   attribute instead, and it cannot go stale again. */
@media (max-width: 1280px) {
  .aros-kpirow { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .aros-panels > [class*="aros-span-"] { grid-column: span 12; }
}

@media (max-width: 760px) {
  .aros-kpirow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .aros-kpi { min-height: 112px; padding: 12px 13px; }
  .aros-panels { grid-template-columns: minmax(0, 1fr); }
  .aros-panels > [class*="aros-span-"] { grid-column: auto; }

  /* One panel per row here, so a fixed row height aligns nothing — it only
     squeezes each chart into whatever the bar, footer and pill row leave. Panels
     size to their content again; .aros-scroll still caps the long lists. */
  .aros-panels { grid-auto-rows: auto; }
  .aros-panel-body > .chart-body { min-height: 240px; }
  .aros-scroll { max-height: 420px; }
}

/* Five anchored columns need room. Below this the measurement column is dropped
   rather than squeezed — a 30px track carries no information and squeezing it is
   what breaks the shared x-positions the rule exists to hold. */
@media (max-width: 560px) {
  .aros-row { grid-template-columns: 6px minmax(0, 1fr) auto 42px; }
  .aros-row-desc { display: none; }
}

@media (max-width: 420px) {
  .aros-kpirow { grid-template-columns: minmax(0, 1fr); }
}

/* Long lists and wide tables scroll inside their own card, never the page, and
   never by stretching the card. Outlet revenue draws one row per outlet — 37 of
   them, a 993px svg — which dragged its grid row to triple height and left the
   panel beside it sitting in a column of white space. The cap is what keeps a
   row of panels a row of panels; the content is reached by scrolling. */
.aros-scroll {
  max-height: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* A hairline scrollbar — visible enough to advertise that there is more below,
   quiet enough not to read as a border (rule 3). */
.aros-scroll { scrollbar-width: thin; scrollbar-color: var(--color-border-strong, #A8A79E) transparent; }
.aros-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.aros-scroll::-webkit-scrollbar-track { background: transparent; }
.aros-scroll::-webkit-scrollbar-thumb {
  background: var(--color-border-strong, #A8A79E);
  border: 2px solid transparent;
  border-radius: 999px;
  background-clip: content-box;
}

/* Rule 1: chart legends are labels, so mono uppercase — not a bold sans run. */
.aros-chart-legend text {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  fill: var(--color-text-muted, #6B6A65);
}
.aros-panel--primary .aros-chart-legend text { fill: var(--color-text-muted, #6B6A65); }

/* Print: signature.css flattens the legacy dark bar to a hairline so the PDF
   path doesn't emit a solid black band. Converted panels need the same, and its
   rule no longer reaches them. */
@media print {
  .aros-panelbar,
  .aros-panel--primary > .aros-panelbar {
    background: transparent;
    border-bottom: 1px solid #ccc;
  }
  .aros-panelbar .chart-title,
  .aros-panel--primary > .aros-panelbar .chart-title,
  .aros-panelbar h2,
  .aros-panel--primary > .aros-panelbar h2 { color: #222; }
  .aros-panelbar .chart-title svg,
  .aros-panel--primary > .aros-panelbar .chart-title svg { color: #666; }
  .aros-panelfoot { background: transparent; }
}

:root { --aros-ink: #1B1F26; }

/* ── Top restaurants: movers board ─────────────────────────────────────────────
   Six anchored columns: rank | movement | name + share | value | change. The old
   row had a mark dot and a measurement bar; rank and movement carry more here,
   because the panel's job is what CHANGED, not who is biggest. */
.aros-row--mv {
  /* Name is sized to content, not 1fr — stretching it opened a dead void across the
     middle of every row. The bar takes that space instead. */
  /* The name column is a FIXED width, not auto: sized to content it varied per row,
     so every bar started at a different x and the column had no edge to read down
     (rule 11 — anchored alignment). Names longer than it ellipsis. */
  grid-template-columns: 16px 34px minmax(150px, 250px) minmax(40px, 1fr) auto 40px;
  gap: 10px;
  padding: 5px 0;
}

.aros-row--mv .aros-row-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12.5px;
}

.aros-row--mv .aros-row-track { height: 4px; }
/* Ink, like every other measurement bar on the page — the blue read as a data
   series when it is a magnitude. */
.aros-row--mv .aros-row-track > i { background: var(--aros-sig-bar-bg, #1B1F26); }

/* One colour source per row: the movement chip. The change figure is ink — with
   both tinted, ten rows carried twenty red/green marks and neither read as the
   signal. */
.aros-row--mv .aros-row-chg { color: var(--color-text-muted, #63635C); }
.aros-row--mv .aros-row-chg[data-tone="up"],
.aros-row--mv .aros-row-chg[data-tone="down"] { color: var(--color-text-muted, #63635C); }

.aros-row-rank {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 11px;
  font-weight: 600;
  color: var(--color-text-subtle, #6E6D65);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.aros-mv {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 1px 5px;
  border-radius: var(--radius-pill, 999px);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Rule 6: movement is the one thing on this row colour is allowed to encode. */
.aros-mv[data-dir="up"]   { color: var(--color-status-good-text, #0A7D0A);     background: var(--color-status-good-surface, #E7F2E7); }
.aros-mv[data-dir="down"] { color: var(--color-status-critical-text, #C0272B); background: var(--color-status-critical-surface, #FBEAEA); }
.aros-mv[data-dir="flat"] { color: var(--color-text-subtle, #6E6D65);          background: transparent; }
.aros-mv[data-dir="new"]  { color: var(--color-text, #24231F);                 background: var(--color-surface-sunken, #EBEAE4); letter-spacing: .06em; }
.aros-mv .aros-mv-arrow { width: 8px; height: 8px; flex: none; display: block; }

.aros-row-chg {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 10.5px;
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-subtle, #6E6D65);
}
.aros-row-chg[data-tone="up"]   { color: var(--color-status-good-text, #0A7D0A); }
.aros-row-chg[data-tone="down"] { color: var(--color-status-critical-text, #C0272B); }

/* ── OOS: long lists scroll inside the panel ───────────────────────────────────
   The page was 32,915px tall — about 33 screens — because every panel printed
   its whole result set inline: 301 rows in "Out Right Now" (15,102px), 200 in
   "Recurring & Chronic" (10,469px). Panels were also wildly ragged next to each
   other (589px beside 10,469px), so a row of two never read as a row.

   Same fix Overview already uses (.aros-scroll): a fixed body height with the
   list scrolling inside it. The count stays complete — nothing is truncated —
   but the panel is a panel again. Chosen per-panel rather than globally because
   the ranked money list is the page's headline and earns more room than the
   reference tables below it. */
#oos-impact-list    { max-height: 560px; }
/* 320: a 301-row table is a lookup, not a read. The sticky header below keeps
   the columns legible while it scrolls. */
#oos-current-table  { max-height: 320px; }
/* 300, not 420: these two are reference panels under the headline ranking, and
   at 420 they took a full screen each for content the reader consults rather
   than scans. Both get the same cap so the row still reads as a row. */
#oos-cross-branch,
#oos-recurring      { max-height: 300px; }
#oos-top-items,
#oos-by-branch      { max-height: 300px; }
#oos-alerts-list    { max-height: 320px; }

#oos-impact-list,
#oos-current-table,
#oos-cross-branch,
#oos-recurring,
#oos-top-items,
#oos-by-branch,
#oos-alerts-list {
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* A scrolled table loses its header on the first wheel notch, which is the one
   thing a 301-row table cannot afford. */
#oos-current-table thead th,
#oos-top-items thead th,
#oos-by-branch thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-surface, #fff);
  box-shadow: inset 0 -1px 0 var(--color-border, #E4E3DE);
}

/* ── OOS row density ──────────────────────────────────────────────────────────
   Capping the panels was only half the problem: an impact row was 95px and an
   alert row 96px, so a 520px panel showed five of twenty-five and the page felt
   like nothing but scrolling. Overview's equivalent rows are 28px. These bring
   the same density here — the row keeps every field, it just stops padding them
   apart. */
#page-oos .oos-imp-row {
  padding: 7px 2px;
  gap: 10px;
  align-items: center;
}
#page-oos .oos-imp-sub { margin-top: 1px; font-size: 0.7rem; }
#page-oos .oos-imp-codes { margin-top: 3px; gap: 3px; }
#page-oos .oos-imp-label { font-size: 0.56rem; padding: 1px 5px; }
/* The bar is 5px of measurement carrying 7px of margin above it. */
#page-oos .oos-imp-bar { margin-top: 4px; height: 4px; }
#page-oos .oos-imp-name { font-size: 0.82rem; }

#page-oos .oos-alert { padding: 6px 4px; gap: 8px; font-size: 0.76rem; }
#page-oos .oos-alert svg { width: 14px; height: 14px; }

#page-oos .oos-table td,
#page-oos .oos-table th { padding: 5px 10px; }

/* With the rows compact, the headline ranking earns its height back. */
#oos-impact-list { max-height: 540px; }

/* ── OOS: restaurant view ────────────────────────────────────────────────────
   A disclosure row in five columns — rank, chevron, identity, a fixed 110px
   measurement track, money. The bar is a COLUMN. Stacked full-width under the
   sub-line, as it was, it read as an underline struck through the sentence. */
#page-oos .oos-rest { display: flex; flex-direction: column; }

#page-oos .oos-rest-row { border-bottom: 1px solid var(--color-border, #E4E3DE); }
#page-oos .oos-rest-row:last-child { border-bottom: none; }

#page-oos .oos-rest-head {
  display: grid;
  grid-template-columns: 20px 18px minmax(0, 1fr) 110px auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 6px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
#page-oos .oos-rest-head:hover { background: var(--color-surface-alt, #F2F1ED); }
#page-oos .oos-rest-head:focus-visible {
  outline: 2px solid var(--color-focus-ring, #1D5BB8);
  outline-offset: -2px;
}

#page-oos .oos-rest-rank {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.7rem;
  color: var(--color-text-subtle);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* The control, not a glyph wedged against the name: its own hit area, its own
   hairline, and the only thing on the row that moves. */
#page-oos .oos-rest-chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border-radius: 5px;
  border: 1px solid var(--color-border, #E4E3DE);
  color: var(--color-text-subtle);
  transition: transform 140ms ease, color 140ms ease, border-color 140ms ease;
}
#page-oos .oos-rest-head:hover .oos-rest-chev,
#page-oos .oos-rest-row.is-open .oos-rest-chev {
  color: var(--color-text);
  border-color: var(--color-border-strong, #A8A79E);
}
#page-oos .oos-rest-row.is-open .oos-rest-chev { transform: rotate(90deg); }

#page-oos .oos-rest-id { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
#page-oos .oos-rest-name {
  font-size: 0.82rem; font-weight: 700; color: var(--color-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-oos .oos-rest-sub {
  font-size: 0.7rem; color: var(--color-text-muted, #6B6A65);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

#page-oos .oos-rest-bar {
  height: 4px; border-radius: 999px;
  background: var(--color-surface-alt, #F2F1ED);
  overflow: hidden;
}
#page-oos .oos-rest-bar > i { display: block; height: 100%; border-radius: 999px; }

#page-oos .oos-rest-money {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.86rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap;
}

/* The drawer. Indented to the identity column so it reads as belonging to the
   row it opened from, tinted so the ranking stays the thing you scan. */
#page-oos .oos-rest-items {
  margin: 0 6px 8px 58px;
  padding: 4px 10px 6px;
  border-radius: 8px;
  background: var(--color-surface-alt, #F2F1ED);
}

#page-oos .oos-sub-row {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto 46px 84px;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  font-size: 0.74rem;
}
#page-oos .oos-sub-rank {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.66rem;
  color: var(--color-text-subtle);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
#page-oos .oos-sub-name {
  color: var(--color-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Rule 8: an inferred rate never sits beside a measured one unmarked. */
#page-oos .oos-sub-est {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; font-weight: 700; letter-spacing: .06em;
  padding: 1px 4px; border-radius: 4px;
  border: 1px dashed var(--color-border-strong, #A8A79E);
  color: var(--color-text-subtle);
}
#page-oos .oos-sub-est.is-blank { border: 0; padding: 0; }
#page-oos .oos-sub-hrs {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.66rem; color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
}
#page-oos .oos-sub-money {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-weight: 600; color: var(--color-text);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
#page-oos .oos-sub-more,
#page-oos .oos-sub-empty {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem; letter-spacing: .04em;
  color: var(--color-text-subtle);
  padding: 4px 0 2px;
}

/* The slider sits in the panel bar with the pills. */
.oos-topn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: none;
}
.oos-topn[hidden] { display: none; }
.oos-topn-label {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--aros-sig-bar-fg-muted, rgba(36,31,26,.66));
  white-space: nowrap;
}
.oos-topn-label b { color: var(--aros-sig-bar-fg, #241F1A); font-variant-numeric: tabular-nums; }
.oos-topn input[type="range"] {
  width: 96px;
  accent-color: var(--aros-sig-bar-fg, #241F1A);
  cursor: pointer;
}

/* ── Active List (Admin → Active List) ────────────────────────────────────────
   One decision per restaurant, so the row is a switch, a name, and — only once
   it is off — the date it stopped trading. The date input is the load-bearing
   control: without it the exclusion is absolute and rewrites history. */
#page-active .act-search {
  flex: none;
  width: 180px;
  height: 26px;
  font-size: 0.72rem;
}

#page-active .act-summary {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-muted, #6B6A65);
  font-variant-numeric: tabular-nums;
}

#page-active .act-list { display: flex; flex-direction: column; }

#page-active .act-row {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 168px minmax(0, 1.1fr);
  align-items: center;
  gap: 12px;
  padding: 7px 6px;
  border-bottom: 1px solid var(--color-border, #E4E3DE);
}
#page-active .act-row:last-child { border-bottom: none; }
#page-active .act-row.is-off { background: var(--color-surface-alt, #F2F1ED); }

#page-active .act-id { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
#page-active .act-name {
  font-size: 0.82rem; font-weight: 700; color: var(--color-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-active .act-row.is-off .act-name { color: var(--color-text-muted, #6B6A65); }
#page-active .act-code {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.6rem; letter-spacing: .06em;
  color: var(--color-text-subtle);
}

#page-active .act-state {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-text-subtle);
}

#page-active .act-from { display: inline-flex; align-items: center; gap: 7px; }
#page-active .act-from-label {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-text-muted, #6B6A65);
  white-space: nowrap;
}
#page-active .act-date {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.7rem;
  padding: 2px 6px;
  border: 1px solid var(--color-border-strong, #A8A79E);
  border-radius: 6px;
  background: var(--color-surface, #fff);
  color: var(--color-text);
}

#page-active .act-note {
  font-size: 0.68rem;
  color: var(--color-text-muted, #6B6A65);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The switch. Native checkbox kept in the DOM for keyboard and screen readers,
   moved off-screen rather than display:none so it stays focusable. */
#page-active .act-sw { display: inline-flex; cursor: pointer; }
#page-active .act-sw input {
  position: absolute; opacity: 0; width: 0; height: 0;
}
#page-active .act-sw-track {
  display: block; width: 30px; height: 17px;
  border-radius: 999px;
  background: var(--color-border-strong, #A8A79E);
  transition: background 140ms ease;
}
#page-active .act-sw-knob {
  display: block; width: 13px; height: 13px; margin: 2px;
  border-radius: 999px; background: #fff;
  transition: transform 140ms ease;
}
#page-active .act-sw input:checked + .act-sw-track { background: var(--aros-sig-blue, #16406F); }
#page-active .act-sw input:checked + .act-sw-track .act-sw-knob { transform: translateX(13px); }
#page-active .act-sw input:focus-visible + .act-sw-track {
  outline: 2px solid var(--color-focus-ring, #1D5BB8);
  outline-offset: 2px;
}

@media (max-width: 900px) {
  #page-active .act-row { grid-template-columns: 34px minmax(0, 1fr); }
  #page-active .act-state, #page-active .act-from, #page-active .act-note {
    grid-column: 2; margin-left: 0;
  }
}

/* ── Active List: layout, evidence column, change timeline ──────────────────── */
.act-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--space-4, 12px);
  align-items: start;
}
@media (max-width: 1200px) {
  .act-layout { grid-template-columns: minmax(0, 1fr); }
}

#page-active .act-row {
  grid-template-columns: 34px minmax(0, 1fr) 150px minmax(0, 1.15fr);
}

/* Rista's own flag reads Active for every outlet ever, so the last CLOSED sale is
   the column that actually decides. Stale rows carry the warning ink. */
#page-active .act-evidence {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem;
  letter-spacing: .02em;
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-active .act-evidence.is-stale { color: var(--color-status-warning-text, #8A5A00); font-weight: 600; }

.act-audit-pane #act-audit { max-height: 620px; overflow-y: auto; overscroll-behavior: contain; }

.act-tl { list-style: none; margin: 0; padding: 2px 0 0; position: relative; }
/* The spine. Drawn on the list, not per item, so it is continuous. */
.act-tl::before {
  content: '';
  position: absolute;
  left: 5px; top: 8px; bottom: 8px;
  width: 1px;
  background: var(--color-border, #E4E3DE);
}

.act-tl-item {
  position: relative;
  display: grid;
  grid-template-columns: 11px minmax(0, 1fr);
  gap: 10px;
  padding: 7px 0;
}

.act-tl-dot {
  width: 9px; height: 9px;
  margin-top: 4px;
  border-radius: 999px;
  background: var(--color-surface, #fff);
  border: 2px solid var(--color-text-subtle, #96948D);
  z-index: 1;
}
.act-tl-dot[data-icon="trash"] { border-color: var(--color-status-critical, #C0453B); }
.act-tl-dot[data-icon="plus"]  { border-color: var(--color-status-good, #3E7A56); }
.act-tl-dot[data-icon="power"] { border-color: var(--aros-sig-blue, #16406F); }
.act-tl-item.is-fail .act-tl-dot { background: var(--color-status-critical, #C0453B); border-color: var(--color-status-critical, #C0453B); }

.act-tl-body { min-width: 0; }
.act-tl-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.act-tl-verb {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.6rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--color-text, #24231F); font-weight: 700;
}
.act-tl-when {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; color: var(--color-text-subtle); flex: none;
}
.act-tl-what {
  font-size: 0.74rem; color: var(--color-text);
  margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.act-tl-who {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; color: var(--color-text-subtle); margin-top: 1px;
}
.act-tl-err { color: var(--color-status-critical-text, #C0272B); }

/* ── Store groupings: + picker, named chips, inline delete confirm ─────────── */

/* Name first, code demoted — GSHBKDP / KHBYFGD / TBCKPHB are indistinguishable
   as bare codes, which is how one sat mis-filed for months. */
.grp-chip-name { font-weight: 600; }
.grp-chip-code {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem;
  letter-spacing: .05em;
  color: var(--color-text-subtle);
  margin-left: 5px;
}

.grp-add-btn { font-size: 1rem; line-height: 1; font-weight: 600; }
.grp-add-btn.is-open {
  background: var(--aros-sig-blue, #16406F);
  border-color: var(--aros-sig-blue, #16406F);
  color: #fff;
}

.grp-add-panel {
  margin: 6px 0 8px;
  padding: 7px;
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: 8px;
  background: var(--color-surface-alt, #F2F1ED);
}
.grp-add-search { width: 100%; height: 26px; font-size: 0.72rem; }
.grp-add-list { max-height: 190px; overflow-y: auto; overscroll-behavior: contain; margin-top: 6px; }

.grp-add-row {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  padding: 4px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.grp-add-row:hover { background: var(--color-surface, #fff); }
.grp-add-row:focus-visible { outline: 2px solid var(--color-focus-ring, #1D5BB8); outline-offset: -2px; }
.grp-add-plus {
  font-weight: 700; color: var(--color-status-good, #3E7A56);
  flex: none; width: 11px; text-align: center;
}
.grp-add-name {
  font-size: 0.74rem; color: var(--color-text);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.grp-add-code {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .05em; color: var(--color-text-subtle);
  margin-left: auto; flex: none;
}
/* (set_id, branch_code) is the primary key, so adding is a MOVE. Say so before
   the click, not after. */
.grp-badge-move {
  flex: none;
  background: var(--color-status-warning-surface, #FBF0DC);
  color: var(--color-status-warning-text, #8A5A00);
}

/* Deleting a group unassigns every store in it. A native confirm() can be
   suppressed by the browser and looks nothing like the page. */
.grp-group-card.is-confirming { border-color: var(--color-status-critical, #C0453B); }
.grp-confirm {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 6px 0 8px;
  padding: 8px;
  border-radius: 8px;
  background: var(--color-status-critical-surface, #FBEAEA);
}
.grp-confirm-q { font-size: 0.72rem; color: var(--color-status-critical-text, #C0272B); }
.grp-confirm-acts { display: flex; gap: 6px; justify-content: flex-end; }
.grp-confirm-acts .grp-btn { padding: 3px 10px; font-size: 0.68rem; }

/* The rule button sits in the page header beside the count. */
#page-active .act-rule-btn {
  margin-left: 10px;
  padding: 3px 10px;
  font-size: 0.66rem;
  vertical-align: middle;
}

/* The groupings page gains the history column. Below 1500px it drops to the
   two-pane layout and the log goes full width underneath, rather than squeezing
   three panes into a width that fits two. */
@media (min-width: 1500px) {
  .grp-layout { grid-template-columns: 320px minmax(0, 1fr) 300px; }
}
@media (max-width: 1499px) {
  .grp-audit-pane { grid-column: 1 / -1; }
}
.grp-audit-pane #grp-audit { max-height: 560px; overflow-y: auto; overscroll-behavior: contain; }

/* Both lists scroll inside their panel instead of growing the page. 40 branches
   at ~40px is 1,600px of restaurant list — the same "the page is nothing but
   scrolling" problem the OOS panels were capped for. */
#page-active #act-list {
  max-height: 620px;
  overflow-y: auto;
  overscroll-behavior: contain;
}



/* ── Global view switch (in the filter bar, beside Branch / From / To) ────────
   A flip switch, same anatomy as the Active List one so the dashboard has a
   single switch idiom. It lives in the filter bar rather than the meta strip
   because it IS a global filter — and because the strip has its own layout that
   an extra child breaks. */
.dim-row { display: flex; align-items: center; gap: 8px; min-height: var(--control-height-sm, 32px); }

.dim-side {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.66rem;
  letter-spacing: .05em;
  color: var(--color-text-subtle, #96948D);
  white-space: nowrap;
  transition: color 140ms ease;
}
.dim-side.is-on { color: var(--color-text, #24231F); font-weight: 700; }

.dim-flip { display: inline-flex; cursor: pointer; flex: none; }
/* Kept in the DOM and focusable — moved off-screen, not display:none. */
.dim-flip input { position: absolute; opacity: 0; width: 0; height: 0; }
.dim-flip-track {
  display: block; width: 32px; height: 18px;
  border-radius: 999px;
  background: var(--color-border-strong, #A8A79E);
  transition: background 140ms ease;
}
.dim-flip-knob {
  display: block; width: 14px; height: 14px; margin: 2px;
  border-radius: 999px; background: #fff;
  transition: transform 140ms ease;
}
.dim-flip input:checked + .dim-flip-track { background: var(--aros-sig-bar-bg, #1B1F26); }
.dim-flip input:checked + .dim-flip-track .dim-flip-knob { transform: translateX(14px); }
.dim-flip input:focus-visible + .dim-flip-track {
  outline: 2px solid var(--color-focus-ring, #1D5BB8);
  outline-offset: 2px;
}

.dim-sel {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.68rem;
  height: 26px;
  padding: 0 6px;
  border: 1px solid var(--color-border, #E4E3DE);
  border-radius: var(--radius-sm, 8px);
  background: var(--color-surface, #fff);
  color: var(--color-text, #24231F);
  cursor: pointer;
  max-width: 150px;
}
.dim-sel[hidden] { display: none; }

/* A footnote on a group card, not a headline. It had no rule at all, so it
   inherited body size and drowned the chips it was annotating. */
.grp-hidden-note {
  margin: 6px 0 0;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.56rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-subtle, #96948D);
  cursor: help;
}

/* Rename affordances. The group name is a button that looks like text until you
   hover it — a pencil icon on twelve cards would be twelve pieces of chrome. */
.grp-group-name {
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  padding: 1px 4px;
  margin-left: -4px;
  border-radius: 5px;
  cursor: text;
  text-align: left;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.grp-group-name:hover { background: var(--color-surface-alt, #F2F1ED); box-shadow: inset 0 0 0 1px var(--color-border, #E4E3DE); }
.grp-group-name:focus-visible { outline: 2px solid var(--color-focus-ring, #1D5BB8); outline-offset: 1px; }

.grp-rename-in {
  font: inherit;
  font-weight: 700;
  padding: 1px 5px;
  min-width: 0;
  flex: 1 1 auto;
  border: 1px solid var(--color-focus-ring, #1D5BB8);
  border-radius: 5px;
  background: var(--color-surface, #fff);
}
.grp-rename-set { font-size: inherit; width: 100%; max-width: 320px; }

/* ── Forecast page ──────────────────────────────────────────────────────────── */
#page-forecast .fc-kpirow { margin-bottom: var(--space-6, 20px); }
#page-forecast .fc-runmeta {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem; letter-spacing: .04em;
  color: var(--color-text-muted, #6B6A65);
  font-variant-numeric: tabular-nums;
}

/* Ranked-bar list, shared by brand totals and accuracy-by-restaurant. */
#page-forecast .fc-rank { display: flex; flex-direction: column; }
#page-forecast .fc-rank-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 120px 72px;
  align-items: center; gap: 10px;
  padding: 5px 2px;
  border-bottom: 1px solid var(--color-border, #E4E3DE);
}
#page-forecast .fc-rank-row:last-child { border-bottom: none; }
#page-forecast .fc-rank-name {
  font-size: 0.76rem; color: var(--color-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-forecast .fc-rank-bar {
  height: 4px; border-radius: 999px;
  background: var(--color-surface-alt, #F2F1ED); overflow: hidden;
}
#page-forecast .fc-rank-bar > i {
  display: block; height: 100%; border-radius: 999px;
  background: var(--aros-sig-bar-bg, #1B1F26);
}
/* Accuracy is the one place colour is semantic here — it is a verdict, not a series. */
#page-forecast .fc-rank-bar > i.is-good { background: var(--color-status-good, #3E7A56); }
#page-forecast .fc-rank-bar > i.is-warn { background: var(--color-status-warning, #C68A2E); }
#page-forecast .fc-rank-bar > i.is-bad  { background: var(--color-status-critical, #C0453B); }
#page-forecast .fc-rank-val {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.72rem; font-weight: 600; text-align: right;
  font-variant-numeric: tabular-nums; color: var(--color-text);
}

/* Brand × restaurant cells. The RANGE is the point — a bare number here would
   imply a precision the model does not have. */
#page-forecast .fc-cells { display: flex; flex-direction: column; max-height: 460px; overflow-y: auto; overscroll-behavior: contain; }
#page-forecast .fc-cell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 140px 150px;
  align-items: center; gap: 12px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--color-border, #E4E3DE);
}
#page-forecast .fc-cell:last-child { border-bottom: none; }
#page-forecast .fc-cell-id { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
#page-forecast .fc-cell-brand { font-size: 0.78rem; font-weight: 700; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#page-forecast .fc-cell-branch {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.6rem; letter-spacing: .05em; color: var(--color-text-subtle);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-forecast .fc-cell-bar { height: 4px; border-radius: 999px; background: var(--color-surface-alt, #F2F1ED); overflow: hidden; }
#page-forecast .fc-cell-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--aros-sig-bar-bg, #1B1F26); }
#page-forecast .fc-cell-val {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.82rem; font-weight: 700; text-align: right;
  font-variant-numeric: tabular-nums; color: var(--color-text);
  display: flex; flex-direction: column; gap: 1px;
}
#page-forecast .fc-cell-range {
  font-size: 0.6rem; font-weight: 500; color: var(--color-text-subtle); letter-spacing: .02em;
}

/* ── Forecast: Next 7 Days by Brand, as a matrix ─────────────────────────────
   A table, not a chart: the question is how much of what on which day, and
   nobody preparing food reads a stacked bar. Cell shading is per-BRAND, so a
   small brand's busy day still reads as busy. */
#page-forecast .fcm-wrap { overflow-x: auto; overscroll-behavior-x: contain; }

#page-forecast .fcm {
  width: 100%;
  border-collapse: separate;
  border-spacing: 2px;
  font-variant-numeric: tabular-nums;
}

#page-forecast .fcm th {
  border: 0;
  background: transparent;
  padding: 0 0 4px;
}
#page-forecast .fcm-corner {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-subtle); text-align: left; padding-left: 2px;
}

#page-forecast .fcm-day { text-align: center; line-height: 1.15; }
#page-forecast .fcm-dow {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-text);
}
#page-forecast .fcm-date {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; color: var(--color-text-subtle);
}
/* Weekends are when prep goes wrong, so they get a marker rather than a colour. */
#page-forecast .fcm-day.is-weekend .fcm-dow { color: var(--aros-sig-blue, #16406F); }

#page-forecast .fcm-brand {
  text-align: left;
  font-size: 0.74rem; font-weight: 700;
  color: var(--color-text);
  padding: 0 10px 0 2px;
  white-space: nowrap;
  max-width: 190px; overflow: hidden; text-overflow: ellipsis;
}

#page-forecast .fcm-cell {
  text-align: center;
  padding: 6px 4px;
  border-radius: 5px;
  min-width: 62px;
  cursor: default;
}
#page-forecast .fcm-v {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.78rem; font-weight: 700;
  color: var(--color-text);
  letter-spacing: -0.01em;
}
#page-forecast .fcm-nil { color: var(--color-text-subtle); background: transparent; }

/* Only shown when the move is worth acting on — see the 8% gate in the JS. */
#page-forecast .fcm-delta {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; font-weight: 700; letter-spacing: .03em;
  margin-top: 1px;
}
#page-forecast .fcm-delta.is-up { color: var(--color-status-good-text, #0A7D0A); }
#page-forecast .fcm-delta.is-down { color: var(--color-status-critical-text, #C0272B); }

/* The week column and the totals row are the summary lines — inked, not tinted. */
#page-forecast .fcm-wk {
  border-left: 2px solid var(--color-border, #E4E3DE);
  background: var(--color-surface-alt, #F2F1ED);
}
#page-forecast th.fcm-wk {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-muted); background: transparent; border-left: 0;
}
#page-forecast .fcm-totalrow .fcm-brand,
#page-forecast .fcm-totalrow .fcm-cell { border-top: 2px solid var(--color-border-strong, #A8A79E); }
#page-forecast .fcm-totalrow .fcm-v { font-size: 0.82rem; }
#page-forecast .fcm-total { background: transparent; }

#page-forecast .fcm-note {
  margin: 10px 0 0;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .04em;
  color: var(--color-text-subtle);
  line-height: 1.5;
}

/* Brand rows expand to their restaurants, in place — the comparison you want is
   this brand's restaurants against each other on the SAME days. */
#page-forecast .fcm-row.is-expandable { cursor: pointer; }
#page-forecast .fcm-row.is-expandable:hover .fcm-brand { color: var(--aros-sig-blue, #16406F); }
#page-forecast .fcm-row.is-expandable:focus-visible { outline: 2px solid var(--color-focus-ring, #1D5BB8); outline-offset: -2px; }
/* A real control, not a CSS triangle: its own hit area and hairline, so it
   reads as something you press. Same idiom as the OOS restaurant rows. */
#page-forecast .fcm-caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px; height: 17px;
  margin-right: 8px;
  vertical-align: -4px;
  border-radius: 5px;
  border: 1px solid var(--color-border, #E4E3DE);
  background: var(--color-surface, #fff);
  color: var(--color-text-subtle, #96948D);
  transition: transform 140ms ease, color 140ms ease, border-color 140ms ease, background 140ms ease;
}
#page-forecast .fcm-row.is-expandable:hover .fcm-caret {
  color: var(--color-text, #24231F);
  border-color: var(--color-border-strong, #A8A79E);
}
#page-forecast .fcm-row.is-open .fcm-caret {
  transform: rotate(90deg);
  background: var(--aros-sig-blue, #16406F);
  border-color: var(--aros-sig-blue, #16406F);
  color: #fff;
}

#page-forecast .fcm-sub { display: none; }
#page-forecast .fcm-sub.is-shown { display: table-row; }
#page-forecast .fcm-subname {
  font-weight: 500;
  font-size: 0.7rem;
  color: var(--color-text-muted, #6B6A65);
  padding-left: 20px;
}
#page-forecast .fcm-sub .fcm-v { font-weight: 500; font-size: 0.72rem; color: var(--color-text-muted, #6B6A65); }

/* Matrix legend. Above the grid and built from the same marks the cells use —
   the previous version was a paragraph underneath, which nobody reads and which
   is no help while your eye is on a number. */
#page-forecast .fcm-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  padding: 0 2px 10px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--color-border, #E4E3DE);
}
#page-forecast .fcm-lg {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.6rem;
  letter-spacing: .03em;
  color: var(--color-text-muted, #6B6A65);
  white-space: nowrap;
}
#page-forecast .fcm-lg .fcm-delta { display: inline; margin: 0; font-size: 0.6rem; }
#page-forecast .fcm-swatch {
  display: inline-block; width: 13px; height: 13px; border-radius: 3px;
  background: rgba(27,31,38,.04);
}
#page-forecast .fcm-swatch.is-dark { background: rgba(27,31,38,.18); margin-left: -3px; }
#page-forecast .fcm-lg-caret {
  width: 15px; height: 15px; margin-right: 0; vertical-align: middle;
}
#page-forecast .fcm-lg-quiet { color: var(--color-text-subtle, #96948D); }

@media (max-width: 900px) {
  #page-forecast .fcm-legend { gap: 6px 12px; }
  #page-forecast .fcm-lg-quiet { display: none; }
}

/* The forecast cell tooltip has no private styles — it is built from the shared
   .tt-* zones in aros/signature.css, and is the reference use of them. */

/* Every change is shown now; a near-flat one is inked neutral so the eye skips it. */
#page-forecast .fcm-delta.is-flat { color: var(--color-text-subtle, #96948D); font-weight: 500; }
#page-forecast .fcm-sub .fcm-delta { font-size: 0.5rem; }

/* Title, then the caption, then the pills hard right. The bar is space-between,
   so without this the caption floats to the middle and leaves a hole after a
   short title like "ACCURACY". */
#page-forecast .chart-header:has(#fc-acc-mode) .chart-desc,
#page-forecast .chart-header:has(#fc-item-scope) .chart-desc {
  margin-right: auto;
}

/* ── Item tier, as a daily matrix ────────────────────────────────────────────
   Same table idiom as the brand matrix, one level down: scope rows (brand /
   restaurant / group) that open into their items across the same seven days.
   Item numbers are a top-down split of the cell forecast, replaced by the
   counted actual once a day settles — see src/forecast.js. */
#page-forecast .fci-wrap { overflow-x: auto; overscroll-behavior-x: contain; }
#page-forecast .fci {
  width: 100%;
  border-collapse: separate;
  border-spacing: 2px;
  font-variant-numeric: tabular-nums;
}
#page-forecast .fci th { border: 0; background: transparent; padding: 0 0 4px; }
#page-forecast .fci-corner {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-subtle); text-align: left; padding-left: 2px;
}
#page-forecast .fci-day { text-align: center; line-height: 1.15; }
#page-forecast .fci-dow {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-text);
}
#page-forecast .fci-date {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; color: var(--color-text-subtle);
}
#page-forecast .fci-day.is-weekend .fci-dow { color: var(--aros-sig-blue, #16406F); }

#page-forecast .fci-lbl {
  text-align: left; white-space: nowrap;
  padding: 0 10px 0 2px;
  max-width: 260px; overflow: hidden; text-overflow: ellipsis;
}
/* Hover, focus and open behave exactly as the brand matrix's rows do — same
   blue on the label, same focus ring, no underline. */
#page-forecast .fci-scope { cursor: pointer; }
#page-forecast .fci-scope .fci-lbl b { font-size: 0.8rem; font-weight: 700; color: var(--color-text); }
#page-forecast .fci-scope:hover .fci-lbl b { color: var(--aros-sig-blue, #16406F); }
#page-forecast .fci-scope:focus-visible { outline: 2px solid var(--color-focus-ring, #1D5BB8); outline-offset: -2px; }
#page-forecast .fci-n {
  margin-left: 8px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-text-subtle);
}
/* The caret is .fcm-caret, shared with the brand matrix — two drill-downs on one
   page with two different marks for the same gesture is just confusing. Only the
   open/hover states need rebinding to this table's row class. */
#page-forecast .fci-scope:hover .fcm-caret {
  color: var(--color-text, #24231F);
  border-color: var(--color-border-strong, #A8A79E);
}
#page-forecast .fci-scope.is-open .fcm-caret {
  transform: rotate(90deg);
  background: var(--aros-sig-blue, #16406F);
  border-color: var(--aros-sig-blue, #16406F);
  color: #fff;
}

/* Item rows are hidden until the scope opens — display:none on a <tr> keeps the
   column widths of the visible rows honest, which visibility:collapse does not. */
#page-forecast .fci-item { display: none; }
#page-forecast .fci-item.is-shown { display: table-row; }
#page-forecast .fci-iname {
  padding-left: 21px;
  font-size: 0.73rem; font-weight: 500; color: var(--color-text);
}
#page-forecast .fci-sh {
  margin-left: 8px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; color: var(--color-text-subtle);
}
#page-forecast .fci-rest .fci-lbl {
  padding-left: 21px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.6rem; color: var(--color-text-subtle);
}

#page-forecast .fci-c {
  text-align: center;
  padding: 5px 4px;
  border-radius: 5px;
  min-width: 58px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.74rem; font-weight: 700;
  color: var(--color-text);
}
#page-forecast .fci-v { display: block; }
#page-forecast .fci-item .fci-v { font-weight: 500; font-size: 0.7rem; }

/* Same chip, same thresholds and same ink as the brand matrix — this is the one
   comparison both tables make, so it must not read as two different things. */
#page-forecast .fci-delta {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; font-weight: 700; letter-spacing: .03em;
  margin-top: 1px;
}
#page-forecast .fci-delta.is-up { color: var(--color-status-good-text, #0A7D0A); }
#page-forecast .fci-delta.is-down { color: var(--color-status-critical-text, #C0272B); }
#page-forecast .fci-delta.is-flat { color: var(--color-text-subtle, #96948D); font-weight: 500; }
#page-forecast .fci-item .fci-delta { font-size: 0.5rem; }

#page-forecast .fci-totalrow .fci-lbl,
#page-forecast .fci-totalrow .fci-c { border-top: 2px solid var(--color-border-strong, #A8A79E); }
#page-forecast .fci-totalrow .fci-lbl b { font-size: 0.8rem; font-weight: 700; }
#page-forecast .fci-totalrow .fci-v { font-size: 0.8rem; }
#page-forecast .fci-nil { color: var(--color-text-subtle); background: transparent; }
#page-forecast .fci-wk {
  border-left: 2px solid var(--color-border, #E4E3DE);
  background: var(--color-surface-alt, #F2F1ED);
}
#page-forecast th.fci-wk {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.58rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-text-muted); background: transparent; border-left: 0;
}

/* ── Counted, not forecast ───────────────────────────────────────────────────
   A settled day has to be legible as history at a glance, or the table reads as
   a prediction for a day that already happened. An underline on the column head
   plus a solid rule under the cells: no extra colour, because the tint channel
   is already carrying volume. */
#page-forecast .fcm-state,
#page-forecast .fci-state {
  display: block; margin-top: 2px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.48rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-text-muted);
}
#page-forecast .fcm-day.is-partial .fcm-state,
#page-forecast .fci-day.is-partial .fci-state { color: var(--color-accent-text, #8A5F09); }
#page-forecast .fcm-cell.is-actual,
#page-forecast .fci-c.is-actual { box-shadow: inset 0 -2px 0 var(--color-text-muted); }
#page-forecast .fcm-swatch.is-actual {
  background: transparent; box-shadow: inset 0 -2px 0 var(--color-text-muted);
}

@media (max-width: 700px) {
  #page-forecast .fci-lbl { max-width: 150px; }
  #page-forecast .fci-c { min-width: 48px; font-size: 0.68rem; }
}

/* Placeholder tiles say so on the tile. A panel that looks finished but is not
   is worse than an empty one — someone starts trusting it. */
#page-forecast .fc-placeholder-tag {
  flex-shrink: 0;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  padding: 2px 7px; border-radius: var(--radius-pill, 999px);
  background: var(--color-status-warning-surface, rgba(250,178,25,.16));
  color: var(--color-accent-text, #8A5F09);
}
#page-forecast .fc-placeholder-note {
  margin: 0 0 14px;
  padding: 9px 12px;
  border-radius: var(--radius-sm, 8px);
  background: var(--color-surface-alt, #F2F1ED);
  font-size: 0.76rem; line-height: 1.5;
  color: var(--color-text-muted, #63635C);
}
#page-forecast .fc-placeholder-note b { color: var(--color-text, #1A1A18); font-weight: 600; }

/* Cumulative share, next to the item's own. Quieter than the share — you scan
   down it looking for where it crosses 80%, you do not read every value. */
/* In a pill, so it cannot be misread as part of the item's own share sitting
   next to it — two bare percentages side by side is exactly the ambiguity this
   is meant to remove. */
#page-forecast .fci-cum {
  margin-left: 7px;
  padding: 1px 6px;
  border-radius: var(--radius-pill, 999px);
  background: var(--color-surface-alt, #F2F1ED);
  border: 1px solid var(--color-border, #E4E3DE);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.52rem; font-weight: 600; letter-spacing: .04em;
  color: var(--color-text-muted, #63635C);
  white-space: nowrap;
}

/* Item-count slider. Lives in the panel bar, so it has to sit inside 34px and
   read as a control rather than a form field. */
#page-forecast .fc-slider {
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
  font-family: var(--aros-sig-mono, var(--font-mono));
}
#page-forecast .fc-slider-l {
  font-size: 0.55rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-text-muted);
}
#page-forecast .fc-slider-v {
  min-width: 20px; text-align: right;
  font-size: 0.68rem; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--color-text);
}
#page-forecast .fc-slider input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 108px; height: 3px; margin: 0; padding: 0;
  border-radius: 999px;
  background: var(--color-border-strong, #A8A79E);
  cursor: pointer;
}
#page-forecast .fc-slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; border-radius: 999px;
  background: var(--aros-sig-blue, #16406F);
  border: 2px solid var(--color-surface, #fff);
  box-shadow: 0 0 0 1px var(--aros-sig-blue, #16406F);
}
#page-forecast .fc-slider input[type="range"]::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 999px;
  background: var(--aros-sig-blue, #16406F);
  border: 2px solid var(--color-surface, #fff);
  box-shadow: 0 0 0 1px var(--aros-sig-blue, #16406F);
}
#page-forecast .fc-slider input[type="range"]:focus-visible {
  outline: 2px solid var(--color-focus-ring, #1D5BB8); outline-offset: 4px;
}
@media (max-width: 900px) {
  #page-forecast .fc-slider input[type="range"] { width: 72px; }
}

/* "so far" — today's counted total, on the cell. It sits in the chip slot, so it
   must not read as a chip: no status colour, mono, and quieter than the forecast
   above it. It is a fact, not a judgement. */
#page-forecast .fcm-sofar,
#page-forecast .fci-sofar {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; font-weight: 500; letter-spacing: .02em;
  margin-top: 1px;
  color: var(--color-accent-text, #8A5F09);
  white-space: nowrap;
}
#page-forecast .fcm-sub .fcm-sofar,
#page-forecast .fci-item .fci-sofar { font-size: 0.5rem; }

/* The page's own window picker, and the banner for a window that predates
   forecasting. The global From/To bar is hidden here — see navigateToPage. */
#page-forecast .fc-window { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
#page-forecast .fc-window-l {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.55rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-text-muted);
}
#page-forecast .fc-nowindow {
  margin: 0 0 16px;
  padding: 12px 16px;
  border-radius: var(--radius-sm, 8px);
  background: var(--color-status-warning-surface, rgba(250,178,25,.16));
  font-size: 0.82rem; line-height: 1.5;
  color: var(--color-text, #1A1A18);
}

/* The item row gained a second time column: hours lost YESTERDAY and MTD, in
   place of one cell that mixed "4d 23h" with "2.7h" and could not be scanned.
   Both are bounded by their period, so both fit the same narrow width. */
#page-oos .oos-sub-row {
  grid-template-columns: 18px minmax(0, 1fr) auto 50px 50px 84px;
}
#page-oos .oos-sub-mtd { color: var(--color-text-subtle); }
#page-oos .oos-sub-head {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.6rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--color-text-subtle);
  border-bottom: 1px solid var(--color-separator);
  padding-bottom: 4px;
  margin-bottom: 2px;
}
#page-oos .oos-sub-head .oos-sub-money { font-weight: inherit; }

/* ════════════════════════════════════════════════════════════════════════════
   EDGE — the Overview panel treatment
   ────────────────────────────────────────────────────────────────────────────
   Three things this changes, all of them complaints about the old panel:

   1. NO SAND STRIPS. The bar and the foot were both #E6D8C7, so the white plot
      read as a hole cut in a beige card — a colour the chart itself never uses.
      The panel is now ONE surface; the header separates by space and weight.
   2. THE PANEL LEADS WITH ITS ANSWER. A kicker names the scope, then the total
      is stated at 30px. You should not have to read an axis to learn the number.
   3. PILLS ON ONE LINE. The outlet chips stacked name over value in a column,
      which is what made seven of them feel crammed. Name and value now sit on a
      single row inside one pill, and the group scrolls instead of wrapping.

   The accent is a single warm hue and is kept OFF the data — it marks the active
   control and the kicker, never a bar or a line.
   ════════════════════════════════════════════════════════════════════════════ */
/* Indigo, chosen 2026-08-29 over terracotta/cobalt/teal/forest/aubergine.
   The hue picked was #3B4CA8; it ships as #443C9E because #3B4CA8 sits OKLab
   ΔE 4.7 from --aros-sig-blue (#1D5BB8), which paints 18 data marks in this
   file — below ~8 the two read as one colour, and the accent's whole job is to
   mark CONTROLS and never data. #443C9E is ΔE 8.8 and 8.80:1 on white.
   RETUNING THIS HUE MEANS RE-CHECKING THAT DISTANCE, or the rule dies quietly. */
:root { --edge-accent: #443C9E; --edge-accent-fg: #FFFFFF; }

/* Dark mode inverts: ink-on-indigo needs the pill to go LIGHT, exactly as
   --aros-sig-sel does. #9A90F0 is 6.74:1 against #10131A and ΔE 9.4 from the
   dark-mode data blue (#4C8FE8) — the same separation the light pair keeps.
   This override must live in THIS file: overview.css loads after signature.css,
   so a dark block written there would be re-overridden by the :root above. */
:root[data-mode="dark"] { --edge-accent: #9A90F0; --edge-accent-fg: #10131A; }

/* 1 · one surface ---------------------------------------------------------- */
/* Scoping dropped 2026-08-29: this is the app's panel treatment, not Overview's.
   Two structures carry it, because the pages were never built alike —
   Overview wraps panels in .aros-panel > .aros-panelbar, the other 17 pages use
   .chart-container > .chart-header. Both get the same result. */
.aros-panelbar {
  background: transparent;
  border-bottom: 0;
  min-height: 0;
  padding: 18px 20px 0;
  align-items: flex-start;
}
.aros-panel--primary > .aros-panelbar {
  background: transparent;
  border-bottom-color: transparent;
}
.aros-panelfoot {
  background: transparent;
  border-top: 0;
  padding: 4px 20px 16px;
  color: var(--color-text-subtle);
}

/* The .chart-header equivalent. Its hairline was the same idea as Overview's
   sand strip — a drawn line doing work that space and weight do better. */
.chart-header {
  border-bottom: 0;
  padding-bottom: 0;
  margin-bottom: 14px;
  align-items: flex-start;
}

/* The title becomes a kicker on BOTH structures. It reads as a scope label
   rather than a heading, which is what lets the panel's own number (Overview's
   .aros-hero, or the first figure in the body elsewhere) be the loudest thing
   in the panel. .chart-desc directly beneath it carries the sentence, so the
   pairing keeps the hierarchy the big bold title used to hold on its own. */
.aros-panelbar .chart-title,
.aros-panel--primary > .aros-panelbar .chart-title,
.chart-header .chart-title {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--edge-accent);
  line-height: 1.5;
}
/* Icons were sized against a 1rem bold heading and dwarf a 10px kicker.
   Only Complaints and P&L carry them inline. */
.chart-header .chart-title svg {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  color: var(--edge-accent);
  opacity: .75;
}
/* The desc is now the panel's readable line, not a footnote under a heading. */
.chart-header .chart-desc {
  margin-top: 5px;
  font-size: 0.78rem;
  font-weight: var(--font-weight-regular, 400);
  color: var(--color-text-muted);
}

/* .chart-header is a flex ROW — `title | right-hand controls`, nowrap. A
   .chart-desc written as a direct sibling therefore lands in the CONTROLS slot
   and gets squeezed by it. Measured at 1440px on Raw Material: the Pricing Agent
   desc wanted 1425px and was allotted 1048px, and the title wanted 97px and got
   72 — so both were cut off mid-word, on every panel that has a desc.
   The clipping predates the Edge work, but demoting the title to a kicker made
   the desc the line that carries the panel, so a cut sentence now costs meaning
   rather than a footnote. Wrap the header and give the desc its own full row;
   panels whose header holds real controls are unaffected, because the desc
   taking 100% simply pushes those onto the first row beside the title.
   The row is only half of it: the sand-bar block at signature.css:586 also had
   the desc on `white-space:nowrap` with an ellipsis, at a specificity this rule
   cannot reach, so the six longest descs were still cut off after being given a
   full row. That truncation is deleted at its source rather than overridden — a
   `normal` written here loses 0-2-0 to 0-5-0 and does nothing. */
.chart-header { flex-wrap: wrap; }
.chart-header > .chart-desc { flex: 1 0 100%; }

/* 2 · the panel states its total ------------------------------------------- */
.aros-hero { padding: 8px 20px 0; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.aros-hero[hidden] { display: none; }
.aros-hero-value {
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}
.aros-hero-note { font-size: 13px; color: var(--color-text-muted); }

/* 3 · pills on one line, scrolling instead of wrapping --------------------- */
.aros-segpills {
  flex-wrap: nowrap;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding-bottom: 2px;
  gap: 8px;
}
.aros-segpills::-webkit-scrollbar { height: 0; }
.aros-segpill {
  flex-direction: row;
  align-items: baseline;
  gap: 10px;
  flex: 0 0 auto;
  padding: 10px 16px;
  border-radius: 999px;
  white-space: nowrap;
}
.aros-segpill.is-active {
  background: var(--edge-accent);
  border-color: transparent;
  color: var(--edge-accent-fg);
}
.aros-segpill.is-active * { color: var(--edge-accent-fg); }

/* The accent is now the SELECTED state for every pill in the app, not just this
   toggle — the shared rule at signature.css:852 (.pill/.group-pill/.cmp-pill/
   .view-pill/.rep-mode-btn/.platform-pill/.oos-pill/.grp-pill) reads
   var(--edge-accent) directly. Custom properties resolve at use time, so that
   file referencing a token defined here is fine regardless of load order.
   It REPLACES --aros-sig-sel (near-black ink). The old note about the selected
   pill deliberately avoiding --aros-sig-blue still holds and is still satisfied:
   indigo sits OKLab ΔE 8.8 from the data blue, so a control still cannot be
   mistaken for a mark that encodes a value. */
