/* ============================================================================
   AROS Component Layer — Book 011 §4 (The Component Library)
   ----------------------------------------------------------------------------
   Restyles the existing Jelly Belly dashboard components to AROS contracts
   BY SELECTOR. No markup changes required.

   Load order:  fonts.css → styles.css → aros/tokens.css → aros/components.css
   Owns:        component contracts (§4), focus/state model (§9), the
                estimate-vs-actual treatment (§5.4 / AROS-000-054).
   Does NOT own: palette/tokens (aros/tokens.css), page layout (aros/layout.css),
                chart internals (aros/charts.css).

   Rules honoured here:
     AROS-011-014  radius + control-height are tokens; ≥44px touch targets
     AROS-011-016  elevation is intent, never a raw shadow
     AROS-011-017  motion tokenised + reduced-motion aware
     AROS-011-035  tables scroll inside their container, never the page
     AROS-011-036  numeric cells tabular + right aligned
     AROS-011-037  severity/status pills encode by icon + label, colour reinforces
     AROS-011-039  buttons express action weight; danger is visually guarded
     AROS-011-040  inputs are ≥44px on touch with a visible focus ring
     AROS-011-047  empty / loading / error are defined states
     AROS-011-049  no decorative stripes, no top gradient bars
     AROS-011-061  estimates are visually distinct from actuals, by construction
     AROS-011-100  meaning is never colour-alone
   ========================================================================== */


/* ----------------------------------------------------------------------------
   0. Token resolution layer
   ----------------------------------------------------------------------------
   NOT a palette. Every value below is a `var()` chain that resolves an AROS
   semantic token (aros/tokens.css) with the legacy styles.css alias as the
   fallback, so this file renders correctly whether or not tokens.css has
   loaded. Add no literal colours here.
   -------------------------------------------------------------------------- */
:root {
  --cx-bg:            var(--color-bg, var(--bg));
  --cx-surface:       var(--color-surface, var(--card-bg));
  --cx-surface-alt:   var(--color-surface-alt, var(--fill));
  --cx-text:          var(--color-text, var(--text-primary));
  --cx-text-muted:    var(--color-text-muted, var(--text-tertiary));
  --cx-text-subtle:   var(--color-text-subtle, var(--text-tertiary));
  --cx-border:        var(--color-border, var(--card-border));
  --cx-border-strong: var(--color-border-strong, var(--card-border));
  --cx-hairline:      var(--color-separator, var(--separator));

  --cx-primary-bg:     var(--color-action-primary-bg, var(--blue));
  --cx-primary-fg:     var(--color-action-primary-fg, #fff);
  --cx-primary-hover:  var(--color-action-primary-hover, var(--blue));
  --cx-primary-active: var(--color-action-primary-active, var(--blue));

  --cx-secondary-bg:     var(--color-action-secondary-bg, var(--card-bg));
  --cx-secondary-fg:     var(--color-action-secondary-fg, var(--text-primary));
  --cx-secondary-border: var(--color-action-secondary-border, var(--card-border));
  --cx-ghost-fg:         var(--color-action-ghost-fg, var(--text-secondary));

  --cx-disabled-bg:   var(--color-state-disabled-bg, transparent);
  --cx-disabled-fg:   var(--color-state-disabled-fg, var(--text-tertiary));

  --cx-focus:         var(--color-focus-ring, var(--blue));

  /* Fixed status marks (AROS-011-011) plus their AA-verified text/surface
     companions. Pills use the companions; marks are for glyphs only. */
  --cx-good:          var(--color-status-good, var(--green));
  --cx-warning:       var(--color-status-warning, var(--orange));
  --cx-serious:       var(--color-status-serious, var(--orange));
  --cx-critical:      var(--color-status-critical, var(--red));

  --cx-good-text:     var(--color-status-good-text, var(--green));
  --cx-warning-text:  var(--color-status-warning-text, var(--orange));
  --cx-serious-text:  var(--color-status-serious-text, var(--orange));
  --cx-critical-text: var(--color-status-critical-text, var(--red));

  --cx-good-surface:     var(--color-status-good-surface, transparent);
  --cx-warning-surface:  var(--color-status-warning-surface, transparent);
  --cx-serious-surface:  var(--color-status-serious-surface, transparent);
  --cx-critical-surface: var(--color-status-critical-surface, transparent);

  --cx-radius-sm:     var(--radius-sm, 8px);
  --cx-radius-md:     var(--radius-md, 10px);
  --cx-radius-lg:     var(--radius-lg, var(--radius-card, 14px));
  --cx-radius-pill:   var(--radius-pill, 999px);

  --cx-h-sm:          var(--control-height-sm, 32px);
  --cx-h-md:          var(--control-height-md, 38px);
  --cx-h-lg:          var(--control-height-lg, 44px);

  --cx-s1:            var(--space-1, 2px);
  --cx-s2:            var(--space-2, 4px);
  --cx-s3:            var(--space-3, 8px);
  --cx-s4:            var(--space-4, 12px);
  --cx-s5:            var(--space-5, 16px);
  --cx-s6:            var(--space-6, 20px);
  --cx-s7:            var(--space-7, 24px);

  --cx-fs-xs:         var(--font-size-xs, 0.69rem);
  --cx-fs-sm:         var(--font-size-sm, 0.78rem);
  --cx-fs-md:         var(--font-size-md, 0.83rem);
  --cx-fs-lg:         var(--font-size-lg, 0.95rem);
  --cx-fs-2xl:        var(--font-size-2xl, 1.4rem);

  --cx-fw-medium:     var(--font-weight-medium, 550);
  --cx-fw-semibold:   var(--font-weight-semibold, 650);
  --cx-fw-bold:       var(--font-weight-bold, 750);

  --cx-elev-flat:     var(--elevation-flat, none);
  --cx-elev-raised:   var(--elevation-raised, var(--card-shadow));
  --cx-elev-overlay:  var(--elevation-overlay, var(--card-hover-shadow));

  --cx-motion:        var(--motion-standard, 180ms);
  --cx-motion-fast:   var(--motion-fast, 110ms);
  --cx-ease:          var(--ease-standard, cubic-bezier(0.2, 0, 0.2, 1));

  /* Interaction states — authored per theme×mode in tokens.css. */
  --cx-tint-hover:    var(--color-state-hover, color-mix(in srgb, var(--cx-text) 5%, transparent));
  --cx-tint-active:   var(--color-state-active, color-mix(in srgb, var(--cx-text) 9%, transparent));
  --cx-tint-selected: var(--color-state-selected, color-mix(in srgb, var(--cx-primary-bg) 10%, transparent));

  --cx-hatch-angle:   var(--viz-estimate-hatch-angle, 45deg);
}


/* ----------------------------------------------------------------------------
   1. The AROS focus ring (AROS-011-101, §9)
   ----------------------------------------------------------------------------
   One ring, one offset, everywhere. Legacy `:focus` box-shadow rings are
   replaced so focus never reads as two different affordances.
   -------------------------------------------------------------------------- */
.grp-btn:focus-visible,
.grp-icon-btn:focus-visible,
.grp-link-btn:focus-visible,
.grp-chip-x:focus-visible,
.grp-pill:focus-visible,
.rep-btn:focus-visible,
.rep-mode-btn:focus-visible,
.rep-step-btn:focus-visible,
.rep-select-wrap select:focus-visible,
.filter-apply-btn:focus-visible,
.filter-input:focus-visible,
.filter-select:focus-visible,
.loc-add-btn:focus-visible,
.select-apply-btn:focus-visible,
.select-option:focus-visible,
.pill:focus-visible,
.view-pill:focus-visible,
.group-pill:focus-visible,
.platform-pill:focus-visible,
.oos-showall:focus-visible,
.grp-input:focus-visible,
.grp-select:focus-visible,
.grp-store-row:focus-visible,
.cb-row input[type="checkbox"]:focus-visible,
.grp-store-row input[type="checkbox"]:focus-visible,
.grp-branch input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--cx-focus);
  outline-offset: 2px;
  box-shadow: none;
}

/* Segmented children live inside an `overflow:hidden` track — inset the ring
   so it is not clipped by the parent. */
.rep-export .rep-btn:focus-visible,
.rep-mode .rep-mode-btn:focus-visible,
.period-pills .pill:focus-visible,
.comm-view-toggle .view-pill:focus-visible,
.chart-group-toggle .group-pill:focus-visible,
.select-dropdown .select-option:focus-visible {
  outline-offset: -2px;
}

/* Mouse activation must not paint a ring. */
.grp-btn:focus:not(:focus-visible),
.rep-btn:focus:not(:focus-visible),
.rep-mode-btn:focus:not(:focus-visible),
.rep-step-btn:focus:not(:focus-visible),
.filter-apply-btn:focus:not(:focus-visible),
.loc-add-btn:focus:not(:focus-visible),
.pill:focus:not(:focus-visible),
.view-pill:focus:not(:focus-visible),
.grp-pill:focus:not(:focus-visible) {
  outline: none;
}


/* ============================================================================
   2. BUTTONS — §4.6, AROS-011-039
   ==========================================================================*/

/* 2.1 Secondary (the default weight) */
.grp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cx-s2);
  min-height: var(--cx-h-md);
  padding: 0 var(--cx-s4);
  border: 1px solid var(--cx-secondary-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-secondary-bg);
  color: var(--cx-secondary-fg);
  font-family: inherit;
  font-size: var(--cx-fs-md);
  font-weight: var(--cx-fw-semibold);
  line-height: 1.2;
  cursor: pointer;
  transition: background var(--cx-motion-fast) var(--cx-ease),
              border-color var(--cx-motion-fast) var(--cx-ease),
              box-shadow var(--cx-motion-fast) var(--cx-ease);
}

.grp-btn:hover:not([disabled]) {
  background-color: var(--cx-secondary-bg);
  background-image: linear-gradient(var(--cx-tint-hover), var(--cx-tint-hover));
  border-color: var(--cx-border-strong);
  box-shadow: var(--cx-elev-flat);
}

.grp-btn:active:not([disabled]) {
  background-color: var(--cx-secondary-bg);
  background-image: linear-gradient(var(--cx-tint-active), var(--cx-tint-active));
}

/* 2.2 Primary — the single strongest action on a surface */
.grp-btn-primary,
.filter-apply-btn,
.loc-add-btn,
.select-apply-btn {
  background: var(--cx-primary-bg);
  border: 1px solid var(--cx-primary-bg);
  color: var(--cx-primary-fg);
  box-shadow: var(--cx-elev-flat);
}

.grp-btn-primary:hover:not([disabled]),
.filter-apply-btn:hover:not([disabled]),
.loc-add-btn:hover:not([disabled]),
.select-apply-btn:hover:not([disabled]) {
  background: var(--cx-primary-hover);
  border-color: var(--cx-primary-hover);
  /* AROS-011-017: no decorative lift — depth changes, geometry does not. */
  transform: none;
  box-shadow: var(--cx-elev-raised);
  filter: none;
}

.grp-btn-primary:active:not([disabled]),
.filter-apply-btn:active:not([disabled]),
.loc-add-btn:active:not([disabled]),
.select-apply-btn:active:not([disabled]) {
  transform: none;
  box-shadow: var(--cx-elev-flat);
  background: var(--cx-primary-active);
  border-color: var(--cx-primary-active);
}

/* Legacy `.filter-apply-btn` shipped status-green as an action colour and
   `.loc-add-btn` a decorative gradient. Both violate AROS-011-011 /
   AROS-011-049; normalise them to the primary contract. */
.filter-apply-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s2);
  height: auto;
  min-height: var(--cx-h-md);
  padding: 0 var(--cx-s6);
  border-radius: var(--cx-radius-md);
  font-size: var(--cx-fs-md);
  font-weight: var(--cx-fw-semibold);
  white-space: nowrap;
}

.loc-add-btn {
  min-height: var(--cx-h-md);
  padding: 0 var(--cx-s6);
  border-radius: var(--cx-radius-md);
  font-family: inherit;
  font-size: var(--cx-fs-sm);
  font-weight: var(--cx-fw-semibold);
}

.loc-add-btn-sm {
  min-height: var(--cx-h-sm);
  padding: 0 var(--cx-s4);
  font-size: var(--cx-fs-xs);
}

.select-apply-btn {
  width: 100%;
  min-height: var(--cx-h-md);
  padding: 0;
  border-radius: var(--cx-radius-sm);
  font-size: var(--cx-fs-sm);
  font-weight: var(--cx-fw-semibold);
}

/* 2.3 Ghost — lowest weight, no chrome until interacted with */
.grp-btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--cx-ghost-fg);
}

.grp-btn-ghost:hover:not([disabled]) {
  background: var(--cx-tint-hover);
  border-color: transparent;
  color: var(--cx-text);
  box-shadow: none;
}

/* 2.4 Danger — destructive weight. Declared AFTER ghost so the
   `grp-btn-ghost grp-btn-danger` pairing in markup reads as danger.
   AROS-011-039: destructive intent is legible before activation. */
.grp-btn-danger {
  background: transparent;
  border-color: color-mix(in srgb, var(--cx-critical) 45%, transparent);
  color: var(--cx-critical-text);
}

.grp-btn-danger:hover:not([disabled]) {
  background: var(--cx-critical-surface);
  border-color: var(--cx-critical);
  color: var(--cx-critical-text);
}

.grp-btn-danger:active:not([disabled]) {
  background: color-mix(in srgb, var(--cx-critical) 18%, transparent);
}

.grp-btn-danger:focus-visible {
  outline-color: var(--cx-critical);
}

/* 2.5 Disabled + busy (AROS-011-039: loading disables re-entry) */
.grp-btn[disabled],
.grp-btn:disabled,
.rep-btn[disabled],
.rep-step-btn[disabled],
.filter-apply-btn[disabled],
.loc-add-btn[disabled],
.select-apply-btn[disabled],
.grp-icon-btn[disabled],
.grp-link-btn[disabled] {
  opacity: 1;
  color: var(--cx-disabled-fg);
  background: var(--cx-disabled-bg);
  border-color: transparent;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

.grp-btn[aria-busy="true"],
.rep-btn[aria-busy="true"],
.filter-apply-btn[aria-busy="true"],
.loc-add-btn[aria-busy="true"] {
  pointer-events: none;
  opacity: 0.7;
}

/* 2.6 Export cluster — a segmented action group, one hairline, one radius */
.rep-export {
  display: inline-flex;
  gap: 0;
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-surface);
  overflow: hidden;
  box-shadow: var(--cx-elev-flat);
}

.rep-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s3);
  min-height: var(--cx-h-md);
  padding: 0 var(--cx-s5);
  border: none;
  background: transparent;
  color: var(--cx-text);
  font-family: inherit;
  font-size: var(--cx-fs-md);
  font-weight: var(--cx-fw-semibold);
  cursor: pointer;
  transition: background var(--cx-motion-fast) var(--cx-ease),
              color var(--cx-motion-fast) var(--cx-ease);
}

.rep-btn + .rep-btn {
  border-left: 1px solid var(--cx-border);
}

.rep-btn:hover:not([disabled]) {
  background: var(--cx-tint-hover);
  color: var(--cx-text);
}

.rep-btn:active:not([disabled]) {
  background: var(--cx-tint-active);
}

.rep-btn svg {
  flex-shrink: 0;
  color: var(--cx-text-muted);
}

/* 2.7 Icon buttons + stepper */
.rep-step-btn,
.grp-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--cx-h-sm);
  min-height: var(--cx-h-sm);
  padding: 0;
  border-radius: var(--cx-radius-sm);
  cursor: pointer;
  line-height: 1;
  transition: background var(--cx-motion-fast) var(--cx-ease),
              color var(--cx-motion-fast) var(--cx-ease);
}

.rep-step-btn {
  width: var(--cx-h-sm);
  height: var(--cx-h-sm);
  border: 1px solid var(--cx-border);
  background: var(--cx-surface);
  color: var(--cx-text);
  font-size: var(--cx-fs-lg);
}

.rep-step-btn:hover:not([disabled]) {
  background: var(--cx-tint-hover);
  color: var(--cx-text);
  border-color: var(--cx-border-strong);
}

.rep-step-btn:active:not([disabled]) {
  background: var(--cx-tint-active);
}

.grp-icon-btn {
  border: 1px solid transparent;
  background: transparent;
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-lg);
}

.grp-icon-btn:hover:not([disabled]) {
  background: var(--cx-critical-surface);
  color: var(--cx-critical-text);
}

/* 2.8 Link button — an action that reads as text */
.grp-link-btn {
  border: none;
  background: none;
  padding: var(--cx-s1) 0;
  color: var(--cx-primary-bg);
  font-family: inherit;
  font-size: var(--cx-fs-sm);
  font-weight: var(--cx-fw-semibold);
  text-underline-offset: 3px;
  cursor: pointer;
  border-radius: var(--cx-radius-sm);
}

.grp-link-btn:hover:not([disabled]),
.grp-link-btn:focus-visible {
  text-decoration: underline;
}

/* 2.9 "Show all" affordance on the OOS lists */
.oos-showall {
  min-height: var(--cx-h-sm);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-surface);
  color: var(--cx-text);
  font-size: var(--cx-fs-sm);
  font-weight: var(--cx-fw-semibold);
  cursor: pointer;
}

.oos-showall:hover {
  background: var(--cx-tint-hover);
}


/* ============================================================================
   3. SEGMENTED CONTROLS & PILLS — §4.5
   ----------------------------------------------------------------------------
   Active state = token surface + weight + elevation, never colour alone
   (AROS-011-038 / AROS-011-100).
   ==========================================================================*/

/* 3.1 Tracks */
.rep-mode,
.period-pills,
.comm-view-toggle,
.chart-group-toggle,
.comm-platform-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s1);
  padding: var(--cx-s1);
  background: var(--cx-surface-alt);
  border: 1px solid transparent;
}

.rep-mode,
.comm-view-toggle,
.comm-platform-toggle {
  border-radius: var(--cx-radius-pill);
}

.period-pills,
.chart-group-toggle {
  border-radius: var(--cx-radius-md);
}

.period-pills {
  height: auto;
  min-height: calc(var(--cx-h-md) + var(--cx-s1) * 2);
  /* Wraps at every width, not just on mobile. The labels became words rather than
     two-character codes when the pills stopped being rolling windows, and a fixed
     row would have pushed the Apply button off the bar on a narrow desktop. */
  flex-wrap: wrap;
}

/* 3.2 Segments */
.rep-mode-btn,
.period-pills .pill,
.view-pill,
.group-pill,
.platform-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cx-s2);
  border: none;
  background: transparent;
  color: var(--cx-text-muted);
  font-family: inherit;
  font-weight: var(--cx-fw-semibold);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--cx-motion-fast) var(--cx-ease),
              color var(--cx-motion-fast) var(--cx-ease);
}

.rep-mode-btn,
.view-pill,
.platform-pill {
  min-height: var(--cx-h-sm);
  padding: 0 var(--cx-s5);
  border-radius: var(--cx-radius-pill);
  font-size: var(--cx-fs-sm);
}

.period-pills .pill {
  min-height: var(--cx-h-sm);
  padding: 0 var(--cx-s5);
  border-radius: var(--cx-radius-sm);
  font-size: var(--cx-fs-sm);
}

.group-pill {
  min-height: calc(var(--cx-h-sm) - 6px);
  padding: 0 var(--cx-s4);
  border-radius: var(--cx-radius-sm);
  font-size: var(--cx-fs-xs);
}

.rep-mode-btn:hover:not(.active),
.period-pills .pill:hover:not(.active),
.view-pill:hover:not(.active),
.group-pill:hover:not(.active),
.platform-pill:hover:not(.active) {
  background: var(--cx-tint-hover);
  color: var(--cx-text);
}

.rep-mode-btn.active,
.period-pills .pill.active,
.view-pill.active,
.group-pill.active,
.platform-pill.active,
.rep-mode-btn[aria-selected="true"],
.view-pill[aria-selected="true"] {
  background: var(--cx-surface);
  color: var(--cx-text);
  font-weight: var(--cx-fw-bold);
  box-shadow: var(--cx-elev-raised);
}

/* Legacy one-off: the reconciliation segment painted itself a bespoke blue.
   Chrome is achromatic in Graphite — fold it back into the standard state. */
.view-pill[data-view="reconciliation"].active {
  background: var(--cx-surface);
  color: var(--cx-text);
}

/* 3.3 Filter pills (multi-select chips with a count) */
.grp-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s3);
  min-height: var(--cx-h-md);
  padding: 0 var(--cx-s5);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-pill);
  background: var(--cx-surface);
  color: var(--cx-text);
  font-family: inherit;
  font-size: var(--cx-fs-md);
  font-weight: var(--cx-fw-semibold);
  cursor: pointer;
  transition: background var(--cx-motion-fast) var(--cx-ease),
              border-color var(--cx-motion-fast) var(--cx-ease);
}

.grp-pill:hover:not(.active) {
  background-color: var(--cx-surface);
  background-image: linear-gradient(var(--cx-tint-hover), var(--cx-tint-hover));
  border-color: var(--cx-border-strong);
  box-shadow: none;
}

.grp-pill.active {
  background: var(--cx-primary-bg);
  border-color: var(--cx-primary-bg);
  color: var(--cx-primary-fg);
  font-weight: var(--cx-fw-bold);
}

.grp-pill-count,
.grp-group-count,
.oos-pill-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  padding: 0 var(--cx-s2);
  border-radius: var(--cx-radius-pill);
  background: var(--cx-surface-alt);
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1.7;
}

.grp-pill.active .grp-pill-count {
  background: color-mix(in srgb, var(--cx-primary-fg) 26%, transparent);
  color: var(--cx-primary-fg);
}

.rep-mode-btn.active .oos-pill-count,
.oos-pill.active .oos-pill-count {
  background: var(--cx-surface-alt);
  color: var(--cx-text);
}

/* `grp-pill-new` reads as "not yet real" — dashed is the non-colour cue. */
.grp-pill-new {
  border-style: dashed;
  background: transparent;
  color: var(--cx-text-muted);
}


/* ============================================================================
   4. FORM CONTROLS & INPUTS — §4.7, AROS-011-040
   ==========================================================================*/

.grp-input,
.grp-select,
.filter-input,
.filter-select,
.rep-select-wrap select {
  min-height: var(--cx-h-md);
  height: auto;
  padding: 0 var(--cx-s4);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-surface);
  color: var(--cx-text);
  font-family: inherit;
  font-size: var(--cx-fs-md);
  font-weight: var(--cx-fw-medium);
  transition: border-color var(--cx-motion-fast) var(--cx-ease),
              background var(--cx-motion-fast) var(--cx-ease);
}

.grp-input:hover:not(:disabled),
.filter-input:hover:not(:disabled),
.filter-select:hover:not(:disabled),
.rep-select-wrap select:hover:not(:disabled) {
  border-color: var(--cx-border-strong);
}

/* One focus expression for every field — the ring, not a coloured glow. */
.grp-input:focus,
.grp-select:focus,
.filter-input:focus,
.filter-select:focus,
.rep-select-wrap select:focus {
  outline: none;
  border-color: var(--cx-focus);
  background: var(--cx-surface);
  box-shadow: none;
}

.grp-input:focus-visible,
.grp-select:focus-visible,
.filter-input:focus-visible,
.filter-select:focus-visible,
.rep-select-wrap select:focus-visible {
  outline: 2px solid var(--cx-focus);
  outline-offset: 2px;
}

.grp-input:disabled,
.filter-input:disabled,
.filter-select:disabled,
.rep-select-wrap select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.grp-input::placeholder,
.filter-input::placeholder {
  color: var(--cx-text-muted);
}

.grp-select,
.filter-select,
.rep-select-wrap select {
  cursor: pointer;
}

.filter-select option,
.rep-select-wrap select option {
  background: var(--cx-surface);
  color: var(--cx-text);
}

.filter-label,
.rep-field label,
.grp-dim-picker label,
.loc-field > span {
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-semibold);
}

.rep-chev {
  color: var(--cx-text-muted);
}

/* 4.1 Combobox popover — overlay elevation, not a card */
.custom-select {
  position: relative;
}

.select-dropdown {
  margin-top: var(--cx-s2);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-surface);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: var(--cx-elev-overlay);
  overscroll-behavior: contain;
}

.select-option {
  display: flex;
  align-items: center;
  min-height: var(--cx-h-sm);
  padding: var(--cx-s3) var(--cx-s4);
  border-bottom: 1px solid var(--cx-hairline);
  color: var(--cx-text);
  font-size: var(--cx-fs-sm);
  cursor: pointer;
}

.select-option:last-child {
  border-bottom: none;
}

.select-option:hover,
.select-option[aria-selected="true"] {
  background: var(--cx-tint-hover);
}

.select-apply {
  padding: var(--cx-s3) var(--cx-s4);
  background: var(--cx-surface);
  border-top: 1px solid var(--cx-hairline);
}

/* 4.2 Checkboxes and their rows — the row is the hit target */
.cb-row,
.grp-store-row,
.grp-branch,
.grp-toggle {
  cursor: pointer;
}

.cb-row input[type="checkbox"],
.grp-store-row input[type="checkbox"],
.grp-branch input[type="checkbox"],
.grp-toggle input[type="checkbox"],
.grp-store-row input,
.grp-toggle input {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  accent-color: var(--cx-primary-bg);
  cursor: pointer;
}

.grp-store-row {
  border: 1px solid transparent;
  border-radius: var(--cx-radius-sm);
  color: var(--cx-text);
}

.grp-store-row:hover {
  background: var(--cx-tint-hover);
}

.grp-store-row.picked,
.grp-store-row[aria-selected="true"] {
  background: var(--cx-tint-selected);
  border-color: color-mix(in srgb, var(--cx-primary-bg) 28%, transparent);
}

.grp-store-code {
  color: var(--cx-text);
  font-weight: var(--cx-fw-bold);
}

.grp-store-name,
.grp-hint,
.grp-sel-count,
.oos-note {
  color: var(--cx-text-muted);
}

.grp-sel-count {
  color: var(--cx-text);
}

.grp-inline-form,
.grp-group-card {
  background: var(--cx-surface);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-lg);
}

.grp-err {
  color: var(--cx-critical-text);
}


/* ============================================================================
   5. CARDS & SURFACES — §4.1 StatCard, §4.2 Panel
   ----------------------------------------------------------------------------
   AROS-011-049: no decorative stripe, no top gradient bar. Emphasis comes from
   token elevation and content.
   ==========================================================================*/

.glass-card {
  background: var(--cx-surface);
  /* Graphite has no glass: elevation is a tight drop shadow, not a blur. */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-lg);
  box-shadow: var(--cx-elev-raised);
  transition: box-shadow var(--cx-motion) var(--cx-ease);
}

.glass-card.no-blur {
  background: var(--cx-surface);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.glass-card:hover {
  box-shadow: var(--cx-elev-raised);
}

/* Hover depth is reserved for cards that are themselves interactive. */
.glass-card[role="button"]:hover,
.glass-card a:hover,
.summary-card[tabindex]:hover {
  box-shadow: var(--cx-elev-overlay);
}

/* 5.1 StatCard */
.summary-card {
  display: flex;
  align-items: center;
  gap: var(--cx-s4);
  padding: var(--cx-s6) var(--cx-s5);
}

.card-icon-wrap {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--cx-radius-md);
  /* Tinted surface, not a gradient fill (AROS-011-049). The per-card
     `--accent` set in markup keeps entity identity; ink stays legible. */
  background: color-mix(in srgb, var(--accent, var(--cx-text)) 12%, var(--cx-surface-alt));
  color: color-mix(in srgb, var(--accent, var(--cx-text)) 62%, var(--cx-text));
}

.card-label {
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.card-value {
  color: var(--cx-text);
  font-size: var(--cx-fs-2xl);
  font-weight: var(--cx-fw-bold);
  line-height: 1.25;
  letter-spacing: -0.02em;
  /* AROS-011-015: hero/stat figures use proportional numerals. */
  font-variant-numeric: proportional-nums;
}

.card-desc {
  margin-top: var(--cx-s1);
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-medium);
  line-height: 1.35;
}

/* 5.2 Panel */
.chart-container {
  padding: var(--cx-s6);
  overflow: hidden;
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cx-s4);
  margin-bottom: var(--cx-s4);
  padding-bottom: var(--cx-s3);
  border-bottom: 1px solid var(--cx-hairline);
}

.chart-title {
  display: flex;
  align-items: center;
  gap: var(--cx-s3);
  color: var(--cx-text);
  font-size: var(--cx-fs-lg);
  font-weight: var(--cx-fw-bold);
  letter-spacing: -0.01em;
}

/* Panel icons are chrome, not data — muted ink, never a series hue. */
.chart-title svg {
  color: var(--cx-text-muted);
  opacity: 1;
}

.chart-desc {
  margin-top: var(--cx-s1);
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-medium);
  line-height: 1.4;
}

.chart-body {
  position: relative;
  width: 100%;
}


/* ============================================================================
   6. TABLES — §4.3 DataTable, AROS-011-035 / -036
   ==========================================================================*/

.rep-table-wrap,
.oos-table-wrap,
.pnl-table-wrap {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.rep-table,
.oos-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--cx-fs-md);
  color: var(--cx-text);
}

/* Header strip — sticky, and MUST stay opaque or scrolled rows bleed through. */
.rep-table th,
.oos-table th {
  background: var(--cx-surface-alt);
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: left;
  padding: var(--cx-s4) var(--cx-s5);
  border-bottom: 1px solid var(--cx-border);
  white-space: nowrap;
}

.rep-table th {
  position: sticky;
  top: 0;
  z-index: 2;
}

.rep-table td,
.oos-table td {
  padding: var(--cx-s4) var(--cx-s5);
  border-bottom: 1px solid var(--cx-hairline);
  white-space: nowrap;
}

.oos-table td {
  vertical-align: middle;
}

/* Zebra + hover. Hierarchy rows (subtotal/grand) opt out so their emphasis
   is not competing with the stripe. */
.rep-table tbody tr:nth-child(even):not(.rep-subtotal):not(.rep-grand) td,
.oos-table tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--cx-text) 2.5%, transparent);
}

.rep-table tbody tr:hover td,
.oos-table tbody tr:hover td {
  background: var(--cx-tint-hover);
}

/* AROS-011-036: money/quantity columns are tabular AND right-aligned. */
.rep-table th.rep-num,
.rep-table td.rep-num,
.oos-table .oos-num,
.oos-table th.oos-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

/* Store subtotal — the row you scan */
.rep-subtotal td {
  background: color-mix(in srgb, var(--cx-text) 6%, transparent);
  color: var(--cx-text);
  font-weight: var(--cx-fw-bold);
  border-top: 1px solid var(--cx-border);
  border-bottom: 1px solid var(--cx-border);
}

.rep-subtotal:hover td {
  background: color-mix(in srgb, var(--cx-text) 9%, transparent);
}

.rep-caret {
  color: var(--cx-text-muted);
}

/* Brand rows — indented children */
.rep-brand-row td {
  color: var(--cx-text-muted);
  font-weight: var(--cx-fw-medium);
}

.rep-brand-row:hover td {
  background: var(--cx-tint-hover);
  color: var(--cx-text);
}

.rep-brand-row .rep-brand::before {
  background: var(--cx-border);
}

/* Grand total — sticky bottom. Solid, because it floats over live rows;
   and neutral, because status green is reserved for state (AROS-011-011). */
.rep-grand td {
  position: sticky;
  bottom: 0;
  z-index: 1;
  background: var(--cx-surface-alt);
  color: var(--cx-text);
  font-weight: var(--cx-fw-bold);
  border-top: 2px solid var(--cx-text);
  border-bottom: none;
  padding: var(--cx-s4) var(--cx-s5);
}

.oos-sub,
.oos-alert-meta,
.oos-rec-meta,
.oos-imp-per {
  color: var(--cx-text-muted);
}


/* ============================================================================
   7. BADGES, CHIPS & STATUS PILLS — §4.4, AROS-011-037
   ----------------------------------------------------------------------------
   Severity is encoded by SHAPE first (◆ critical, ▲ warning, ● ok) and colour
   second, so a greyscale or CVD render still separates the three levels.
   The glyphs are geometric marks, not emoji (AROS-011-046).
   ==========================================================================*/

.oos-sev-crit,
.oos-sev-warn,
.oos-sev-ok,
.oos-badge,
.oos-alert-badge,
.grp-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s2);
  padding: var(--cx-s1) var(--cx-s3);
  border-radius: var(--cx-radius-pill);
  border: 1px solid transparent;
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  line-height: 1.5;
}

.oos-sev-crit::before,
.oos-sev-warn::before,
.oos-sev-ok::before {
  font-size: 0.85em;
  line-height: 1;
}

.oos-sev-crit {
  color: var(--cx-critical-text);
  background: var(--cx-critical-surface);
  border-color: color-mix(in srgb, var(--cx-critical) 34%, transparent);
}

.oos-sev-crit::before { content: "\25C6"; }   /* ◆ critical */

.oos-sev-warn {
  color: var(--cx-warning-text);
  background: var(--cx-warning-surface);
  border-color: color-mix(in srgb, var(--cx-warning) 42%, transparent);
}

.oos-sev-warn::before { content: "\25B2"; }   /* ▲ warning */

.oos-sev-ok {
  color: var(--cx-good-text);
  background: var(--cx-good-surface);
  border-color: color-mix(in srgb, var(--cx-good) 36%, transparent);
}

.oos-sev-ok::before { content: "\25CF"; }     /* ● good */

/* Recurrence badges — same anatomy, state-coloured, shape-marked. */
.oos-badge-chronic {
  color: var(--cx-critical-text);
  background: var(--cx-critical-surface);
  border-color: color-mix(in srgb, var(--cx-critical) 34%, transparent);
}

.oos-badge-recurring {
  color: var(--cx-warning-text);
  background: var(--cx-warning-surface);
  border-color: color-mix(in srgb, var(--cx-warning) 42%, transparent);
}

.oos-badge-new {
  color: var(--cx-text);
  background: var(--cx-surface-alt);
  border-color: var(--cx-border);
}

/* Neutral informational badge */
.oos-alert-badge {
  color: var(--cx-text);
  background: var(--cx-surface-alt);
  border-color: var(--cx-border);
}

.grp-badge {
  max-width: 96px;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--cx-good-text);
  background: var(--cx-good-surface);
  border-color: color-mix(in srgb, var(--cx-good) 36%, transparent);
}

/* Removable chip */
.grp-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s2);
  padding: var(--cx-s1) var(--cx-s2) var(--cx-s1) var(--cx-s3);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-sm);
  background: var(--cx-surface-alt);
  color: var(--cx-text);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-semibold);
}

.grp-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  min-height: 18px;
  padding: 0;
  border: none;
  border-radius: var(--cx-radius-sm);
  background: transparent;
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-sm);
  line-height: 1;
  cursor: pointer;
}

.grp-chip-x:hover {
  background: var(--cx-critical-surface);
  color: var(--cx-critical-text);
}

.grp-group-count {
  color: var(--cx-text);
}

/* OOS money emphasis — pair colour with the existing severity text. */
.oos-money-crit { color: var(--cx-critical-text); }
.oos-money-warn { color: var(--cx-warning-text); }
.oos-money-mild { color: var(--cx-text-muted); }

.oos-imp-label-out,
.oos-code-out {
  color: var(--cx-critical-text);
  background: var(--cx-critical-surface);
}

.oos-imp-label-sell,
.oos-code-sell {
  color: var(--cx-good-text);
  background: var(--cx-good-surface);
}

.oos-code-more {
  background: var(--cx-surface-alt);
  color: var(--cx-text-muted);
}


/* ============================================================================
   8. EMPTY, LOADING & ERROR STATES — §4.12, AROS-011-047 / -066
   ==========================================================================*/

.grp-empty,
.oos-empty,
.chart-empty,
.chart-error {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cx-s3);
  min-height: 96px;
  padding: var(--cx-s7) var(--cx-s5);
  border: 1px dashed var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: transparent;
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-md);
  font-weight: var(--cx-fw-medium);
  line-height: 1.5;
  text-align: center;
  opacity: 1;
}

.grp-empty-sm {
  min-height: 0;
  padding: var(--cx-s3) var(--cx-s4);
  border: none;
  font-size: var(--cx-fs-sm);
}

/* Error carries a non-colour cue as well as the critical token. */
.chart-error {
  color: var(--cx-critical-text);
  border-color: color-mix(in srgb, var(--cx-critical) 35%, transparent);
  background: var(--cx-critical-surface);
}

.chart-error::before {
  content: "!";
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  font-size: 0.8em;
  font-weight: var(--cx-fw-bold);
  line-height: 1;
}

/* Loading skeleton — activates on `aria-busy`, so no markup class is needed.
   Footprint-preserving: no layout shift when the data lands. */
.chart-body[aria-busy="true"],
.rep-table-wrap[aria-busy="true"],
.oos-table-wrap[aria-busy="true"] {
  position: relative;
  min-height: 120px;
  border-radius: var(--cx-radius-md);
  background: linear-gradient(
    100deg,
    var(--cx-surface-alt) 30%,
    color-mix(in srgb, var(--cx-text) 3%, var(--cx-surface-alt)) 50%,
    var(--cx-surface-alt) 70%
  );
  background-size: 220% 100%;
  animation: cx-skeleton 1.4s var(--cx-ease) infinite;
}

@keyframes cx-skeleton {
  from { background-position: 120% 0; }
  to   { background-position: -120% 0; }
}


/* ============================================================================
   9. THE ESTIMATE TREATMENT — §5.4 / §6, AROS-000-054, AROS-011-001 / -061
   ----------------------------------------------------------------------------
   CONTRACT
     `.aros-estimated`        an inferred / modelled figure. Apply to the
                              element carrying the number (span, td, .card-value).
                              Renders: diagonal hatch behind the value +
                              dashed underline + a trailing "est." marker.
     `.aros-estimated--bare`  same, minus the trailing marker — use when the
                              surrounding copy already says "estimated".
     `.aros-measured`         explicit counterpart for a measured figure.
                              Visually quiet by design: measurement is the
                              default, estimation is the marked case.
     `.aros-estimate-legend`  the legend affordance. Contains
                              `.aros-legend-item` children, each with a
                              `.aros-legend-swatch` that is `--measured` or
                              `--estimated`.

   Three independent, non-colour cues (CVD-, greyscale- and print-safe):
     1. texture   — 45° hatch behind the figure
     2. line      — dashed underline
     3. text      — the persistent "est." marker
   Colour is deliberately NOT one of the cues.

   For the Out-of-Stock table this maps to `basis`:
     basis === 'own'   → measured   (leave bare, or `.aros-measured`)
     basis === 'peer'  → `.aros-estimated`
     basis === 'none'  → no figure should be presented as fact at all
   ==========================================================================*/

.aros-estimated {
  --cx-est-ink: var(--cx-text-muted);
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 0.35em;
  padding: 0 0.28em;
  border-bottom: 1px dashed color-mix(in srgb, var(--cx-text) 45%, transparent);
  background-image: repeating-linear-gradient(
    var(--cx-hatch-angle),
    color-mix(in srgb, var(--cx-text) 9%, transparent) 0,
    color-mix(in srgb, var(--cx-text) 9%, transparent) 1px,
    transparent 1px,
    transparent 5px
  );
  background-clip: padding-box;
  font-style: normal;
}

.aros-estimated::after {
  content: "est.";
  flex-shrink: 0;
  font-size: 0.68em;
  font-weight: var(--cx-fw-bold);
  font-style: normal;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--cx-est-ink);
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--cx-text) 30%, transparent);
  border-radius: var(--cx-radius-sm);
  padding: 0 0.3em;
  line-height: 1.5;
  vertical-align: baseline;
}

.aros-estimated--bare::after {
  content: none;
}

/* Table cells: the hatch fills the cell, the marker stays with the number. */
td.aros-estimated,
th.aros-estimated {
  display: table-cell;
  border-bottom: 1px solid var(--cx-hairline);
  /* the cell keeps the row hairline; the dash rides under the text instead */
  text-decoration: underline dashed
    color-mix(in srgb, var(--cx-text) 45%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

td.aros-estimated::after {
  margin-left: 0.4em;
}

/* Whole row inferred → mark the numeric cells, not the labels. */
tr.aros-estimated {
  display: table-row;
  border-bottom: none;
  background-image: none;
}

tr.aros-estimated > td.rep-num,
tr.aros-estimated > td.oos-num,
tr.aros-estimated > .oos-num {
  background-image: repeating-linear-gradient(
    var(--cx-hatch-angle),
    color-mix(in srgb, var(--cx-text) 9%, transparent) 0,
    color-mix(in srgb, var(--cx-text) 9%, transparent) 1px,
    transparent 1px,
    transparent 5px
  );
}

/* A StatCard whose headline value is inferred. */
.card-value.aros-estimated {
  display: inline-flex;
  padding: 0 0.2em;
}

.card-value.aros-estimated::after {
  font-size: 0.5em;
}

/* Measured — the quiet default. Present so the legend has a counterpart and
   so a surface may state provenance explicitly (§4.1 AROS-011-032). */
.aros-measured {
  background-image: none;
  border-bottom: 1px solid transparent;
  font-style: normal;
}

.aros-measured--marked::after {
  content: "measured";
  margin-left: 0.4em;
  font-size: 0.68em;
  font-weight: var(--cx-fw-semibold);
  letter-spacing: 0.04em;
  color: var(--cx-text-muted);
}

/* 9.1 The legend affordance */
.aros-estimate-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cx-s4);
  margin-top: var(--cx-s3);
  padding: var(--cx-s3) var(--cx-s4);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-md);
  background: var(--cx-surface-alt);
  color: var(--cx-text-muted);
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-medium);
  line-height: 1.5;
}

.aros-legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--cx-s2);
}

.aros-legend-swatch {
  width: 22px;
  height: 12px;
  flex-shrink: 0;
  border-radius: 3px;
  border: 1px solid color-mix(in srgb, var(--cx-text) 30%, transparent);
}

.aros-legend-swatch--measured {
  background: color-mix(in srgb, var(--cx-text) 22%, transparent);
  border-style: solid;
}

.aros-legend-swatch--estimated {
  border-style: dashed;
  background-image: repeating-linear-gradient(
    var(--cx-hatch-angle),
    color-mix(in srgb, var(--cx-text) 26%, transparent) 0,
    color-mix(in srgb, var(--cx-text) 26%, transparent) 1px,
    transparent 1px,
    transparent 4px
  );
}

/* 9.2 The treatment must survive print, greyscale and forced colours
       (AROS-011-026 — a theme may not weaken it). */
@media print {
  .aros-estimated {
    border-bottom: 1px dashed #000;
    background-image: repeating-linear-gradient(45deg,
      rgba(0, 0, 0, 0.18) 0, rgba(0, 0, 0, 0.18) 1px,
      transparent 1px, transparent 5px);
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .aros-estimate-legend {
    border: 1px solid #000;
  }
}

@media (forced-colors: active) {
  .aros-estimated {
    border-bottom: 1px dashed CanvasText;
    forced-color-adjust: none;
  }

  .aros-estimated::after {
    border-color: CanvasText;
    color: CanvasText;
  }
}


/* ============================================================================
   10. DENSITY & TOUCH — AROS-011-014 / -103, ≥44px at ≤768px
   ==========================================================================*/
@media (max-width: 768px) {
  .grp-btn,
  .grp-btn-primary,
  .grp-btn-ghost,
  .grp-btn-danger,
  .rep-btn,
  .rep-mode-btn,
  .filter-apply-btn,
  .loc-add-btn,
  .select-apply-btn,
  .oos-showall,
  .grp-pill,
  .grp-input,
  .grp-select,
  .filter-input,
  .filter-select,
  .rep-select-wrap select,
  .period-pills .pill,
  .view-pill,
  .platform-pill,
  .grp-store-row,
  .select-option,
  .cb-row {
    min-height: var(--cx-h-lg);
  }

  .rep-step-btn,
  .grp-icon-btn {
    width: var(--cx-h-lg);
    height: var(--cx-h-lg);
    min-width: var(--cx-h-lg);
    min-height: var(--cx-h-lg);
  }

  .grp-link-btn,
  .grp-chip-x {
    min-height: 32px;
    padding-block: var(--cx-s2);
  }

  .period-pills {
    min-height: calc(var(--cx-h-lg) + var(--cx-s1) * 2);
  }

  .period-pills .pill,
  .rep-mode-btn,
  .view-pill {
    font-size: var(--cx-fs-sm);
    padding-inline: var(--cx-s4);
  }

  .cb-row input[type="checkbox"],
  .grp-store-row input[type="checkbox"],
  .grp-branch input[type="checkbox"] {
    width: 20px;
    height: 20px;
  }

  .summary-card {
    padding: var(--cx-s4);
    gap: var(--cx-s3);
  }

  .chart-container {
    padding: var(--cx-s5);
  }

  .rep-table td,
  .rep-table th,
  .oos-table td,
  .oos-table th {
    padding: var(--cx-s4);
  }

  .grp-empty,
  .oos-empty,
  .chart-empty,
  .chart-error {
    min-height: 80px;
    padding: var(--cx-s5) var(--cx-s4);
  }
}

/* Pointer-fine desktop may opt into compact density (AROS-011-109) while
   still clearing the AA target floor. */
@media (min-width: 1200px) and (pointer: fine) {
  .rep-table td,
  .oos-table td {
    padding-block: var(--cx-s3);
  }
}


/* ============================================================================
   11. MOTION — AROS-011-017 / -104
   ==========================================================================*/
/* tokens.css already collapses --motion-* and neutralises animation globally
   under `prefers-reduced-motion`. Only the cases it cannot reach are handled
   here: a shimmer that must become a static plane, and residual transforms. */
@media (prefers-reduced-motion: reduce) {
  .chart-body[aria-busy="true"],
  .rep-table-wrap[aria-busy="true"],
  .oos-table-wrap[aria-busy="true"] {
    animation: none;
    background: var(--cx-surface-alt);
  }

  .grp-btn:hover,
  .filter-apply-btn:hover,
  .loc-add-btn:hover,
  .grp-pill:hover {
    transform: none;
  }
}


/* ============================================================================
   12. PRINT — keep the reports legible without chrome
   ==========================================================================*/
@media print {
  .rep-table th,
  .rep-grand td,
  .rep-subtotal td {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .rep-grand td {
    position: static;
  }

  .glass-card,
  .chart-container {
    box-shadow: none;
    border: 1px solid #000;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DATE RANGE PICKER  (js/utils/datepicker.js)
   Replaces `<input type="date">`, whose calendar was Chrome's own control — not
   styleable at any level, so it dropped a foreign blue, a foreign type stack and
   foreign geometry into the middle of the filter bar.
   ═════════════════════════════════════════════════════════════════════════ */

.dp-field { cursor: pointer; }

.dp-pop {
  position: absolute;
  z-index: 1200;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border-strong, #A8A79E);
  border-radius: var(--radius-md, 10px);
  box-shadow: 0 8px 28px rgba(20, 20, 19, .14);
  overflow: hidden;
  user-select: none;
}

/* Sand bar, same as every panel head. */
.dp-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  padding: 7px 10px;
  background: #E6D8C7;
  border-bottom: 1px solid rgba(36,31,26,.20);
}

.dp-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: none;
  border: 1px solid rgba(36,31,26,.22);
  border-radius: var(--radius-sm, 5px);
  background: transparent;
  color: #241F1A;
  cursor: pointer;
}
.dp-nav:hover { background: rgba(36,31,26,.08); }

.dp-range {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #241F1A;
}
.dp-range i { font-style: normal; opacity: .5; }
/* The end being picked is underlined, so the popover says what the next click does. */
.dp-range b.is-picking {
  box-shadow: inset 0 -2px 0 rgba(36,31,26,.55);
}

.dp-months { display: flex; gap: var(--space-4, 16px); padding: 12px; }
.dp-month { width: 182px; }

.dp-mhead {
  margin-bottom: 8px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text, #24231F);
  text-align: center;
}

.dp-dow, .dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); }

.dp-dow span {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  letter-spacing: .04em;
  color: var(--color-text-subtle, #6E6D65);
  text-align: center;
  padding-bottom: 4px;
}

.dp-grid { row-gap: 1px; }

.dp-day {
  height: 24px;
  border: 0;
  background: transparent;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text, #24231F);
  cursor: pointer;
  border-radius: 0;
}
.dp-day.is-out { visibility: hidden; }
.dp-day:hover:not(.is-out) { background: var(--color-surface-alt, #F2F1ED); }

/* The range reads as one continuous band: the interior is a tint with square
   corners and only the two ends are rounded, so there are no gaps between days. */
.dp-day.is-in { background: var(--color-surface-sunken, #EBEAE4); }
.dp-day.is-edge {
  background: #1B1F26;
  color: #fff;
}
.dp-day.is-from { border-radius: 5px 0 0 5px; }
.dp-day.is-to   { border-radius: 0 5px 5px 0; }
.dp-day.is-from.is-to { border-radius: 5px; }

/* Today is marked by a hairline under the number, never by a fill that could be
   mistaken for a selection. */
.dp-day.is-today:not(.is-edge) { box-shadow: inset 0 -2px 0 var(--color-border-strong, #A8A79E); }

.dp-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
  padding: 7px 12px 8px;
  background: #E6D8C7;
  border-top: 1px solid rgba(36,31,26,.20);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: rgba(36,31,26,.72);
}

.dp-clear {
  border: 1px solid rgba(36,31,26,.22);
  border-radius: var(--radius-pill, 999px);
  background: transparent;
  padding: 2px 9px;
  font: inherit;
  color: #241F1A;
  cursor: pointer;
}
.dp-clear:hover { background: rgba(36,31,26,.08); }

/* Cancel and Apply sit together at the right; the range no longer commits on the
   second click, so Apply is the only thing that reloads the page. */
.dp-acts { display: flex; align-items: center; gap: 6px; }

.dp-apply {
  border: 1px solid #241F1A;
  border-radius: var(--radius-pill, 999px);
  background: #241F1A;
  padding: 2px 11px;
  font: inherit;
  color: #F3E9DC;
  cursor: pointer;
}
.dp-apply:hover:not(:disabled) { background: #3A322A; border-color: #3A322A; }
/* Disabled until both ends are picked — an Apply that does nothing is worse than
   one that is visibly not ready. */
.dp-apply:disabled {
  background: transparent;
  border-color: rgba(36,31,26,.18);
  color: rgba(36,31,26,.36);
  cursor: default;
}

/* ----------------------------------------------------------------------------
   Raw Material Pricing + Discount Patterns
   ----------------------------------------------------------------------------
   Shared vocabulary: both pages lead with one rupee figure, back it with a stat
   row, and rank every table by money. Colour is reinforcement only — the sign is
   always in the text (+/-, pp), never colour-alone (AROS-011-100).
   -------------------------------------------------------------------------- */
.rm-hero {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--cx-s7);
  padding: var(--cx-s6) var(--cx-s7);
  background: var(--cx-surface);
  border: 1px solid var(--cx-border);
  border-radius: var(--cx-radius-lg);
}
.rm-hero-main { display: flex; flex-direction: column; gap: 2px; min-width: 240px; }
.rm-hero-label,
.rm-stat-label {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--cx-text-muted);
}
.rm-hero-value {
  font-size: var(--cx-fs-2xl); font-weight: var(--cx-fw-bold);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--cx-text);
}
.rm-hero-sub { font-size: var(--cx-fs-sm); color: var(--cx-text-muted); }
.rm-hero-stats { display: flex; flex-wrap: wrap; gap: var(--cx-s7); margin-left: auto; }
.rm-stat { display: flex; flex-direction: column; gap: 1px; }
.rm-stat-value {
  font-size: var(--cx-fs-lg); font-weight: var(--cx-fw-semibold);
  font-variant-numeric: tabular-nums; color: var(--cx-text);
}
.rm-stat-sub { font-size: var(--cx-fs-xs); color: var(--cx-text-subtle); }
.rm-hero-window {
  flex-basis: 100%;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); color: var(--cx-text-subtle);
  padding-top: var(--cx-s3); border-top: 1px solid var(--cx-hairline);
}
.rm-hero-window i { font-style: normal; opacity: .7; }

/* Up is bad on both pages — a price rise and a discount rise both cost money. */
.rm-up, .dsc-up { color: var(--cx-critical-text); }
.rm-down, .dsc-down { color: var(--cx-good-text); }
.rm-dim { color: var(--cx-text-subtle); }
.rm-impact { font-weight: var(--cx-fw-semibold); }
.rm-unit { color: var(--cx-text-subtle); font-size: .86em; margin-left: 2px; }
.rm-price-tag {
  display: block; font-size: var(--cx-fs-xs); color: var(--cx-text-muted);
  font-variant-numeric: tabular-nums;
}
.rm-vendor-link { color: var(--cx-text); text-decoration: underline; text-underline-offset: 2px; }
.rm-vendor-link:hover { color: var(--cx-primary-bg); }
.rm-sub {
  margin: var(--cx-s4) 0 var(--cx-s3);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--cx-text-muted);
}
.rm-foot {
  margin: var(--cx-s4) 0 0; font-size: var(--cx-fs-xs);
  color: var(--cx-text-subtle); line-height: 1.5; max-width: 90ch;
}
.dsc-chan { color: var(--cx-text-muted); font-size: .92em; }

/* Campaign rows — a disclosure, not a card stack. */
.dsc-camp { border-bottom: 1px solid var(--cx-hairline); }
.dsc-camp:last-of-type { border-bottom: 0; }
.dsc-camp-head {
  display: grid; width: 100%;
  grid-template-columns: 14px minmax(140px, 1.6fr) minmax(110px, 1fr) auto auto auto;
  align-items: center; gap: var(--cx-s4);
  padding: var(--cx-s4) var(--cx-s2);
  background: transparent; border: 0; cursor: pointer; text-align: left;
  font: inherit; color: var(--cx-text);
}
.dsc-camp-head:hover { background: var(--cx-tint-hover); }
.dsc-camp-caret { color: var(--cx-text-subtle); font-size: 10px; }
.dsc-camp-name { font-weight: var(--cx-fw-semibold); }
.dsc-camp-channel { color: var(--cx-text-muted); font-size: var(--cx-fs-sm); }
.dsc-camp-move { font-variant-numeric: tabular-nums; white-space: nowrap; }
.dsc-camp-since {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); color: var(--cx-text-subtle); white-space: nowrap;
}
.dsc-camp-excess {
  font-weight: var(--cx-fw-bold); font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap;
}
.dsc-camp-body { padding: 0 var(--cx-s2) var(--cx-s5) calc(14px + var(--cx-s4)); }
.dsc-spark { display: block; width: 100%; height: 54px; overflow: visible; }
.dsc-spark-line { fill: none; stroke: var(--cx-critical); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
/* The detected start date, marked on the series so "since when" is readable. */
.dsc-spark-mark { stroke: var(--cx-text-subtle); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.dsc-spark-axis {
  display: flex; justify-content: space-between;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); color: var(--cx-text-subtle);
  margin-bottom: var(--cx-s4);
}

@media (max-width: 900px) {
  .rm-hero-stats { margin-left: 0; gap: var(--cx-s5); }
  .dsc-camp-head { grid-template-columns: 14px 1fr auto; row-gap: var(--cx-s2); }
  .dsc-camp-channel, .dsc-camp-since { grid-column: 2 / -1; }
}

/* Half-width cards on the two Money pages.
   `.charts-grid` items stretch to the tallest in the row, so a 5-row panel beside
   a 22-row one grew to 830px with 550px of nothing under its table — and the
   wrap's own scrollbar floated in the middle of that void. Align to the start so
   each card is its own content height.
   The scrollbar was false too: `.rep-table` carries `min-width: 780px` for the
   wide Reports matrix, which forces a horizontal scroll on a 4-column table in a
   616px column. These tables are narrow; let them fit. */
#page-rawmat .charts-grid,
#page-discounts .charts-grid { align-items: start; }

#page-rawmat .charts-grid .rep-table,
#page-discounts .charts-grid .rep-table { min-width: 0; }

#page-rawmat .charts-grid .rep-table td,
#page-rawmat .charts-grid .rep-table th,
#page-discounts .charts-grid .rep-table td,
#page-discounts .charts-grid .rep-table th { padding-left: 12px; padding-right: 12px; }

/* Row sparkline. Recessive ink line, direction carried on the endpoint dot only —
   the signed % sits in the next column, so colour is reinforcement and never the
   sole cue (AROS-011-100). */
.rm-spark-cell { width: 84px; padding-right: 4px !important; }
.rm-spark { display: block; overflow: visible; }
.rm-spark-line {
  fill: none; stroke: var(--cx-text-subtle); stroke-width: 1.4;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.rm-spark-split {
  stroke: var(--cx-border-strong); stroke-width: 1; stroke-dasharray: 2 2;
  vector-effect: non-scaling-stroke;
}
.rm-spark-dot { fill: var(--cx-text-subtle); }
.rm-spark-dot.rm-up { fill: var(--cx-critical); }
.rm-spark-dot.rm-down { fill: var(--cx-good); }
.rm-th-sub {
  display: block; font-weight: 400;
  font-size: var(--cx-fs-xs); letter-spacing: .02em;
  text-transform: none; color: var(--cx-text-subtle);
}

/* The per-day use line under an item name, and the skew badge beside a price.
   Both were rendered by rawmat.js with NO rule behind them, so they ran straight
   into the text before them — "Eggs/pcs995 pcs/day" and "₹31.85+8%" read as one
   token each. A class emitted by JS without a rule is invisible in review and
   obvious on screen; check both sides when adding one. */
.rm-rate {
  display: block;
  margin-top: 2px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs);
  color: var(--cx-text-subtle);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rm-skew {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: var(--cx-radius-sm, 6px);
  background: var(--cx-tint-hover);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs);
  font-weight: var(--cx-fw-medium);
  color: var(--cx-text-muted);
  cursor: help;
}
/* The item cell carries two lines now, so it must not be clamped to one. */
#rm-movers .rep-table td:first-child { white-space: normal; min-width: 200px; }

/* ── Panel-bar filter pills ──────────────────────────────────────────────────
   signature.css already knew this shape was wrong — its comment says "the base
   .rep-mode-btn is min-height 32px and the bar is 34px" — but the rule it wrote
   only covers .oos-pill, so .rep-mode-btn kept overflowing the sand bar top and
   bottom. Sized to sit INSIDE the bar with real air around it. */
.chart-container:not(.aros-panel) > .chart-header:first-child .rep-mode {
  background: transparent;
  padding: 0;
  gap: 5px;
  flex-shrink: 0;
  align-self: center;
}
.chart-container:not(.aros-panel) > .chart-header:first-child .rep-mode-btn {
  min-height: 26px;
  padding: 0 13px;
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  letter-spacing: .07em;
  border-radius: 999px;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

/* These three pills are not a neutral segmented control — they select a
   DIRECTION, and the table already paints that direction red or green. Carrying
   the same colour on the control means the filter and the data agree instead of
   the control being chrome that says nothing. "All" stays ink: no direction. */
#rm-mover-view .rep-mode-btn[data-view="up"].active {
  background: var(--cx-critical);
  border-color: var(--cx-critical);
  color: #FFF;
}
#rm-mover-view .rep-mode-btn[data-view="down"].active {
  background: var(--cx-good);
  border-color: var(--cx-good);
  color: #FFF;
}
#rm-mover-view .rep-mode-btn[data-view="up"]:not(.active) { color: var(--cx-critical-text); }
#rm-mover-view .rep-mode-btn[data-view="down"]:not(.active) { color: var(--cx-good-text); }

/* The prior-comparison half of a sparkline. The line must reach back before the
   filtered range to show a trend at all, so the half you actually asked for is
   the solid one and the run-up is faint. */
.rm-spark-prev { stroke: var(--cx-text-subtle); opacity: .34; stroke-dasharray: 2 2; }

/* ── Pricing agent ───────────────────────────────────────────────────────────
   A recommendation panel, not a table: the money leads, the evidence sits one
   click away, and what the agent REFUSED is on the same page as what it advised. */
.pa-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--cx-s7);
  padding-bottom: var(--cx-s5); margin-bottom: var(--cx-s4);
  border-bottom: 1px solid var(--cx-hairline);
}
.pa-head-main { display: flex; flex-direction: column; gap: 2px; min-width: 240px; }
.pa-head-value {
  font-size: var(--cx-fs-2xl); font-weight: var(--cx-fw-bold);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--cx-good-text);
}
.pa-per { font-size: var(--cx-fs-sm); font-weight: var(--cx-fw-medium); opacity: .65; margin-left: 2px; }
.pa-verdicts { display: flex; flex-wrap: wrap; gap: var(--cx-s6); margin-left: auto; }
.pa-verdict { display: flex; flex-direction: column; gap: 1px; max-width: 130px; }
.pa-verdict-n {
  font-size: var(--cx-fs-lg); font-weight: var(--cx-fw-semibold);
  font-variant-numeric: tabular-nums; color: var(--cx-text);
}
.pa-verdict-l { font-size: var(--cx-fs-xs); color: var(--cx-text-subtle); line-height: 1.3; }
.pa-v-act .pa-verdict-n { color: var(--cx-good-text); }
.pa-v-no .pa-verdict-n { color: var(--cx-text-muted); }
.pa-v-dim .pa-verdict-n { color: var(--cx-text-subtle); }

.pa-card { border-bottom: 1px solid var(--cx-hairline); }
.pa-card:last-of-type { border-bottom: 0; }
.pa-card-head {
  display: grid; width: 100%;
  grid-template-columns: 14px minmax(150px, 1.1fr) minmax(240px, 1.6fr) auto auto;
  align-items: center; gap: var(--cx-s5);
  padding: var(--cx-s4) var(--cx-s2);
  background: transparent; border: 0; cursor: pointer; text-align: left;
  font: inherit; color: var(--cx-text);
}
.pa-card-head:hover { background: var(--cx-tint-hover); }
.pa-caret { color: var(--cx-text-subtle); font-size: 10px; }
.pa-item { font-weight: var(--cx-fw-semibold); }
.pa-swap { display: flex; align-items: center; gap: var(--cx-s3); min-width: 0; }
.pa-from, .pa-to {
  display: flex; flex-direction: column; min-width: 0;
  font-size: var(--cx-fs-sm); line-height: 1.25;
}
.pa-from { color: var(--cx-text-muted); }
.pa-to { color: var(--cx-text); font-weight: var(--cx-fw-medium); }
.pa-from b, .pa-to b { font-variant-numeric: tabular-nums; font-weight: var(--cx-fw-semibold); }
.pa-from b { color: var(--cx-text-subtle); }
.pa-to b { color: var(--cx-good-text); }
.pa-arrow { color: var(--cx-text-subtle); flex-shrink: 0; }
.pa-gap {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); color: var(--cx-text-muted); white-space: nowrap;
}
.pa-save {
  font-weight: var(--cx-fw-bold); font-variant-numeric: tabular-nums;
  color: var(--cx-good-text); text-align: right; white-space: nowrap;
}
.pa-card-body { padding: 0 var(--cx-s2) var(--cx-s5) calc(14px + var(--cx-s5)); }

.pa-tests { display: flex; flex-wrap: wrap; gap: var(--cx-s3) var(--cx-s6); margin-bottom: var(--cx-s3); }
.pa-test { display: inline-flex; align-items: center; gap: 6px; font-size: var(--cx-fs-sm); color: var(--cx-text-muted); }
.pa-tick { color: var(--cx-text-subtle); font-size: 11px; }
.pa-pass .pa-tick { color: var(--cx-good); }
.pa-basis { margin: 0 0 var(--cx-s4); font-size: var(--cx-fs-xs); color: var(--cx-text-subtle); line-height: 1.55; max-width: 90ch; }
.pa-row-inc td { background: var(--cx-tint-hover); }
.pa-badge {
  display: inline-block; margin-left: 6px; padding: 1px 6px;
  border-radius: 999px; background: var(--cx-tint-hover);
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--cx-text-muted);
}

/* The refusals are the trust-builder, so they get a real disclosure and not a
   footnote nobody opens. */
.pa-refused { margin-top: var(--cx-s5); padding-top: var(--cx-s4); border-top: 1px solid var(--cx-hairline); }
.pa-refused-toggle {
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: var(--cx-fs-xs); letter-spacing: .04em;
  color: var(--cx-text-muted); text-decoration: none;
}
.pa-refused-toggle:hover { color: var(--cx-text); }
.pa-would { font-variant-numeric: tabular-nums; color: var(--cx-text-muted); white-space: nowrap; }
.pa-whynot { color: var(--cx-text-subtle); font-size: var(--cx-fs-xs); white-space: normal; line-height: 1.45; }
.pa-panel .rep-table { min-width: 0; }
.pa-panel .rep-table td { white-space: normal; }

@media (max-width: 900px) {
  .pa-verdicts { margin-left: 0; gap: var(--cx-s5); }
  .pa-card-head { grid-template-columns: 14px 1fr auto; row-gap: var(--cx-s3); }
  .pa-swap { grid-column: 2 / -1; }
}
.pa-list { display: block; }
.pa-v-ok .pa-verdict-n { color: var(--cx-text); }

/* ── COGS page ─────────────────────────────────────────────────────────────
   These live in components.css rather than overview.css only because every
   class here is new (`cg-*`), so nothing else in the cascade competes for them
   and the load order cannot matter. The two `rm-hero-stat*` rules complete the
   hero vocabulary the Raw Material page already established but never needed a
   labelled stat column for. */
.rm-hero-stat { display: flex; flex-direction: column; gap: 1px; min-width: 96px; }
.rm-hero-statv {
  font-size: var(--cx-fs-lg, 1.05rem);
  font-weight: var(--cx-fw-bold, 600);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--cx-text, var(--color-text));
}

/* The provenance line under a panel — why a number is what it is. Prose, so it
   opts out of the mono/uppercase caption treatment signature.css applies. */
.cg-note {
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-sm, 8px);
  background: var(--color-surface-sunken, #F6F4EF);
  color: var(--color-text-muted);
  font-size: 0.76rem;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: normal;
}
.cg-note strong { color: var(--color-text); font-variant-numeric: tabular-nums; }

/* Uncosted items are a gap in the data, not an error — warning surface, not
   critical. It states a limit on every other number on the page, so it sits
   ABOVE its table rather than below it. */
.cg-warn {
  margin-bottom: 12px;
  padding: 12px 14px;
  border-radius: var(--radius-sm, 8px);
  background: var(--color-status-warning-surface, rgba(250, 178, 25, .16));
  color: var(--color-text);
  font-size: 0.8rem;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: normal;
}

/* Second line inside a table cell — the SKU or category under an item name. */
.cg-sub {
  display: block;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  color: var(--color-text-subtle);
  margin-top: 2px;
}

.cg-legend {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.cg-key { width: 14px; height: 2px; border-radius: 1px; display: inline-block; }
.cg-key-total { background: var(--aros-sig-blue, #1D5BB8); }
.cg-key-mat { background: var(--color-text-subtle, #8A8578); margin-left: 14px; }
