/* ──────────────────────────────────────────────────────────────────────────
   CDI Visalia Plant Dashboard — v2
   Design language: clean, professional, plant-floor-friendly. Modeled on
   modern monitoring/observability tools (Linear, Vercel, Grafana 11) but
   with CDI's green/gold accent and high-contrast values for big screens.
   ────────────────────────────────────────────────────────────────────────── */

/* Alpine FOUC guard (v2.9.0607.8): x-cloak only REMOVES the attribute on init —
   the matching CSS rule must be supplied by us. Without it, every x-show panel
   (and overlay like .sa-modal-root) is visible from first paint until Alpine
   boots, producing a brief "flash" of the Service-Accounts create modal etc.
   `!important` so it beats element display rules (e.g. .sa-modal-root flex). */
[x-cloak] { display: none !important; }

:root {
  /* CDI brand */
  --cdi-green:        #1B5E20;
  --cdi-green-mid:    #2E7D32;
  --cdi-green-light:  #66BB6A;
  --cdi-gold:         #FFC107;
  --cdi-gold-hover:   #FFD54F;

  /* Neutral scale (dark theme) */
  --n-950:  #07090B;     /* page background */
  --n-900:  #0F1316;     /* card surface     */
  --n-850:  #161B20;     /* card raised      */
  --n-800:  #1D232A;     /* hover            */
  --n-700:  #2A323A;     /* border-default   */
  --n-600:  #3A4450;     /* border-strong    */
  --n-500:  #6B7682;     /* muted text       */
  --n-400:  #8E99A6;     /* secondary text   */
  --n-300:  #B8C2CD;     /* body text        */
  --n-100:  #E8ECF1;     /* heading text     */
  --n-50:   #F5F7FA;     /* highest contrast */

  /* Semantic */
  --ok:        #4ADE80;
  --warn:      #F59E0B;
  --bad:       #F87171;
  --info:      #60A5FA;
  --neutral:   #94A3B8;

  /* Typography scale */
  --fs-xs:   11px;
  --fs-sm:   12px;
  --fs-base: 14px;
  --fs-md:   15px;
  --fs-lg:   17px;
  --fs-xl:   22px;
  --fs-2xl:  28px;
  --fs-3xl:  38px;
  --fs-4xl:  56px;
  --fs-5xl:  72px;

  /* Radii */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.35);
  --shadow-lg: 0 12px 32px rgba(0,0,0,0.5);

  /* Motion */
  --t-fast: 120ms ease;
  --t:      180ms ease;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  background: var(--n-950);
  color: var(--n-300);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: var(--fs-base);
  line-height: 1.5;
  font-feature-settings: "ss01", "cv11", "tnum";
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}
body { padding-bottom: 32px; }
a { color: var(--cdi-gold); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--cdi-gold-hover); }
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.01em; color: var(--n-100); }
/* Inline code = plain BOLD body text, NOT a highlighted chip (v2.9.0606.13,
   standardised per user preference — applies on every page including the admin
   Help docs). Multi-line `pre code` blocks keep a monospace block look below. */
code {
  font-family: inherit;
  font-size: inherit; font-weight: 700;
  background: transparent;
  padding: 0; border: 0; border-radius: 0;
  color: inherit;
}
pre code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-weight: 400; font-size: 0.9em;
}
pre {
  background: rgba(127, 127, 127, 0.10);
  padding: 10px 12px; border-radius: 6px; overflow-x: auto;
}
/* Native date / time / datetime-local pickers — force the body font onto
   the parent input AND every shadow-DOM pseudo-element. Chromium's date
   inputs use shadow DOM that doesn't reliably inherit from the parent,
   so each pseudo needs an explicit declaration. Plus:
   - Explicit font-family (not `inherit`) to dodge edge cases where the
     UA stylesheet's `font: -webkit-small-control` shorthand resets the
     family before our cascade reaches it.
   - `font-feature-settings: normal` to drop the body's tabular-numeral
     feature so date digits render with their natural proportional
     widths — tabular numerals make the value text read as monospace-ish
     against the body labels.
   - `!important` because the UA stylesheet's user-agent rules can win
     against descendant-pseudo specificity in some browser versions.  */
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="date"]::-webkit-datetime-edit,
input[type="date"]::-webkit-datetime-edit-fields-wrapper,
input[type="date"]::-webkit-datetime-edit-text,
input[type="date"]::-webkit-datetime-edit-month-field,
input[type="date"]::-webkit-datetime-edit-day-field,
input[type="date"]::-webkit-datetime-edit-year-field,
input[type="time"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit-fields-wrapper,
input[type="time"]::-webkit-datetime-edit-text,
input[type="time"]::-webkit-datetime-edit-hour-field,
input[type="time"]::-webkit-datetime-edit-minute-field,
input[type="time"]::-webkit-datetime-edit-second-field,
input[type="time"]::-webkit-datetime-edit-ampm-field,
input[type="datetime-local"]::-webkit-datetime-edit,
input[type="datetime-local"]::-webkit-datetime-edit-fields-wrapper,
input[type="datetime-local"]::-webkit-datetime-edit-text,
input[type="datetime-local"]::-webkit-datetime-edit-month-field,
input[type="datetime-local"]::-webkit-datetime-edit-day-field,
input[type="datetime-local"]::-webkit-datetime-edit-year-field,
input[type="datetime-local"]::-webkit-datetime-edit-hour-field,
input[type="datetime-local"]::-webkit-datetime-edit-minute-field,
input[type="datetime-local"]::-webkit-datetime-edit-second-field,
input[type="datetime-local"]::-webkit-datetime-edit-ampm-field,
input[type="month"]::-webkit-datetime-edit,
input[type="month"]::-webkit-datetime-edit-fields-wrapper,
input[type="month"]::-webkit-datetime-edit-text,
input[type="month"]::-webkit-datetime-edit-month-field,
input[type="month"]::-webkit-datetime-edit-year-field {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif !important;
  font-size: inherit !important;
  font-feature-settings: normal !important;
  font-variant-numeric: normal !important;
}
/* In descriptive contexts (admin help text, hints, modal bodies, dialog
   titles) the chip styling makes inline references stand out as separate
   visual elements when the admin just wants them to read as normal prose.
   Soften to inherit so phrases like "the Reset button" or "the audit log"
   blend with the surrounding text. Chip styling is preserved in release
   notes and any other context with its own explicit rule. */
.settings-card-sub code,
.settings-card-sub strong code,
.hint code,
.app-confirm-body code,
.empty code,
label code {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  background: transparent;
  padding: 0;
  border: 0;
  color: inherit;
}
[data-theme="light"] .settings-card-sub code,
[data-theme="light"] .settings-card-sub strong code,
[data-theme="light"] .hint code,
[data-theme="light"] .app-confirm-body code,
[data-theme="light"] .empty code,
[data-theme="light"] label code {
  background: transparent;
  border: 0;
  color: inherit;
}
/* .code-mono is intentionally a NO-OP class. We keep the class so
   existing markup using it still works, but the font is the body font —
   OT request: no monospace anywhere in the dashboard. */
.code-mono { font-family: inherit; }
/* Global form-control font consistency — every native input that
   isn't already styled by a wrapper inherits the page font. Inputs
   inside .threshold-editor, .settings-field, .filters etc. already
   set `font-family: inherit`; this catches the few rogue inputs
   browsers default to Arial. */
input, select, textarea, button {
  font-family: inherit;
}

.icon         { display: inline-block; vertical-align: -3px; }
.icon-inline  { vertical-align: -2px; }

/* ── Top nav ─────────────────────────────────────────────────────────────── */
.topnav {
  background: linear-gradient(180deg, rgba(15,19,22,0.95) 0%, rgba(7,9,11,0.95) 100%);
  border-bottom: 1px solid var(--n-700);
  backdrop-filter: blur(12px);
  position: sticky; top: 0; z-index: 100;
}
.topnav-inner {
  max-width: 1700px; margin: 0 auto;
  display: flex; align-items: center; gap: 18px;
  padding: 0 24px; height: 60px;
}
.brand {
  display: flex; align-items: center; gap: 12px;
  color: var(--n-50); padding-right: 18px;
  border-right: 1px solid var(--n-700);
  margin-right: 4px; white-space: nowrap;
}
.brand:hover { color: var(--n-50); }
.brand img { height: 36px; width: auto; }
.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-line-1 { font-size: var(--fs-md); font-weight: 700; color: var(--n-50); }
.brand-line-2 { font-size: var(--fs-xs); color: var(--n-500); letter-spacing: 0.3px; }

.nav-tabs {
  display: flex; gap: 2px; list-style: none; margin: 0; padding: 0;
  flex: 0 1 auto; min-width: 0;
  /* Priority-plus overflow: the strip sizes to its content and any tabs that
     don't fit are moved into the "More ▾" dropdown by static/nav-collapse.js.
     `overflow: hidden` is the safety net that keeps a tab from spilling for the
     frame before the JS reflows — which is exactly why the .nav-more dropdown
     lives OUTSIDE this element (a child would get clipped by this rule). */
  overflow: hidden;
}
/* Tabs must NOT shrink. Without this the <li> are flex items with the default
   shrink:1 and they squish to fit the strip — so the strip never reports an
   overflow (scrollWidth == clientWidth) yet the right-most label still clips
   ("Admin" → "Adn") and "More" never appears. flex:0 0 auto keeps each tab at
   its natural width so a too-wide strip genuinely overflows and the JS moves
   the right-most tab into More. */
.nav-tabs > li { flex: 0 0 auto; }
.nav-tabs::-webkit-scrollbar { display: none; }
/* When the resize logic adds .icon-only to a tab, its label span hides and
   the padding tightens. The icon itself stays full size. */
.nav-tabs li a.icon-only            { padding: 8px 10px; }
.nav-tabs li a.icon-only > span     { display: none; }
.nav-tabs li a {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; border-radius: var(--r-sm);
  color: var(--n-400); font-weight: 500; font-size: var(--fs-sm);
  white-space: nowrap; transition: all var(--t-fast);
  border: 1px solid transparent;
}
.nav-tabs li a:hover {
  background: var(--n-850); color: var(--n-100); text-decoration: none;
}
.nav-tabs li a.active {
  background: rgba(255, 193, 7, 0.12); color: var(--cdi-gold);
  border-color: rgba(255, 193, 7, 0.3); font-weight: 600;
}
.nav-tabs li a.admin {
  margin-left: 6px; color: var(--cdi-green-light);
}
.nav-tabs li a.admin.active {
  background: rgba(102, 187, 106, 0.14); color: var(--cdi-green-light);
  border-color: rgba(102, 187, 106, 0.3);
}

/* ── "More ▾" overflow dropdown (priority-plus nav) ───────────────────────── */
.nav-more { position: relative; flex: none; display: flex; align-items: center; align-self: stretch; }
.nav-more[hidden] { display: none; }   /* JS unhides only once it holds tabs */
.nav-more-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; border-radius: var(--r-sm);
  background: transparent; border: 1px solid transparent;
  color: var(--n-400); font-family: inherit; font-weight: 500; font-size: var(--fs-sm);
  white-space: nowrap; cursor: pointer; transition: all var(--t-fast);
}
.nav-more-btn:hover { background: var(--n-850); color: var(--n-100); }
.nav-more-btn.active {                 /* the open page is a tab now inside More */
  background: rgba(255, 193, 7, 0.12); color: var(--cdi-gold);
  border-color: rgba(255, 193, 7, 0.3); font-weight: 600;
}
.nav-more-caret { transition: transform var(--t-fast); }
.nav-more-btn[aria-expanded="true"] .nav-more-caret { transform: rotate(180deg); }
.nav-more-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 200;
  min-width: 210px; list-style: none; margin: 0; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--n-900); border: 1px solid var(--n-700);
  border-radius: var(--r-sm); box-shadow: 0 10px 28px rgba(0,0,0,0.4);
}
.nav-more-menu[hidden] { display: none; }
.nav-more-menu li { display: block; }
.nav-more-menu li a {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 12px; border-radius: var(--r-sm);
  color: var(--n-300); font-weight: 500; font-size: var(--fs-sm);
  white-space: nowrap; border: 1px solid transparent; transition: all var(--t-fast);
}
.nav-more-menu li a > span { display: inline; }   /* labels always show in the menu */
.nav-more-menu li a:hover { background: var(--n-850); color: var(--n-100); text-decoration: none; }
.nav-more-menu li a.active {
  background: rgba(255, 193, 7, 0.12); color: var(--cdi-gold);
  border-color: rgba(255, 193, 7, 0.3); font-weight: 600;
}
.nav-more-menu li a.admin { color: var(--cdi-green-light); }
.nav-more-menu li a.admin.active {
  background: rgba(102, 187, 106, 0.14); color: var(--cdi-green-light);
  border-color: rgba(102, 187, 106, 0.3);
}

.nav-right {
  display: flex; align-items: center; gap: 6px;
  margin-left: auto;                   /* take the slack, stay pinned right */
  padding-left: 14px; border-left: 1px solid var(--n-700);
  height: 30px;
}
/* Help icon — sits in .nav-right, right of the theme toggle (admin-only). */
.nav-help-icon {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 6px; border-radius: var(--r-sm);
  color: var(--cdi-green-light); border: 1px solid transparent;
  transition: all var(--t-fast);
}
.nav-help-icon:hover { background: var(--n-850); color: var(--n-100); text-decoration: none; }
.nav-help-icon.active {
  background: rgba(102, 187, 106, 0.14); color: var(--cdi-green-light);
  border-color: rgba(102, 187, 106, 0.3);
}
.live-pulse {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.7);
  animation: pulse-ring 2s infinite;
}
@keyframes pulse-ring {
  0%   { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.7); }
  70%  { box-shadow: 0 0 0 10px rgba(74, 222, 128, 0); }
  100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0); }
}
.live-label {
  font-size: var(--fs-xs); font-weight: 700; color: var(--ok);
  letter-spacing: 1px;
}

/* ── Page shell + headers ────────────────────────────────────────────────── */
.page { max-width: 1700px; margin: 0 auto; padding: 12px 24px 40px; }

.page-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  margin-bottom: 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--n-800);
}
/* Compact variant — used on the Overview where we want to minimise vertical
   space above the dashboard tiles. Eyebrow + subtitle dropped; title sits
   tight against the page top and the section grid follows immediately. */
.page-header-compact {
  margin-bottom: 6px; padding-bottom: 4px;
}
.page-header-compact .page-title {
  font-size: var(--fs-xl); line-height: 1;
}
.page-header-text { display: flex; flex-direction: column; gap: 4px; }
.page-eyebrow {
  font-size: var(--fs-xs); color: var(--n-500); font-weight: 600;
  letter-spacing: 1.5px; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 6px;
}
.page-title {
  font-size: var(--fs-2xl); font-weight: 700; color: var(--n-50);
  line-height: 1.1; display: inline-flex; align-items: center; gap: 12px;
}
.page-title .icon { color: var(--cdi-gold); }
.page-subtitle { color: var(--n-400); font-size: var(--fs-md); margin-top: 4px; }
.page-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

.section { margin-bottom: 18px; }
.section-title {
  font-size: var(--fs-lg); color: var(--n-100); font-weight: 600;
  margin: 0 0 8px; display: inline-flex; align-items: center; gap: 8px;
}
.section-title .icon { color: var(--cdi-gold); }
.section-header {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 16px; flex-wrap: wrap; margin-bottom: 14px;
}
.section-sub-line { font-size: var(--fs-sm); color: var(--n-400); margin: 2px 0 0; }
.subsection-title {
  font-size: var(--fs-md); color: var(--n-100); font-weight: 600;
  margin: 0 0 12px; display: flex; align-items: center; gap: 8px;
}
.subsection-title::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(to right, var(--n-800), transparent);
}

/* ── Filter controls ─────────────────────────────────────────────────────── */
.filters {
  display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap;
}
.filters label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-xs); color: var(--n-500);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.7px;
}
.filters select, .filters input[type="text"], .filters input[type="number"] {
  background: var(--n-900); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 8px 10px; font-size: var(--fs-base); min-width: 180px;
  transition: border-color var(--t-fast);
  font-family: inherit;
}
.filters select:focus, .filters input:focus {
  outline: none; border-color: var(--cdi-gold);
}
.filter-wide select, .filter-wide input { min-width: 320px; }

/* ── Toolbar (under page header, in x-data scope) ─────────────────────────── */
.toolbar {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 24px;
}
/* Variant: meta-only toolbars (e.g. /silos after the sort dropdown was
   removed) — pin the lone child to the right edge instead of leaving
   it stuck on the left from the default `space-between`. */
.toolbar.toolbar-right { justify-content: flex-end; }
.toolbar-meta {
  font-size: var(--fs-sm); color: var(--n-400);
  font-variant-numeric: tabular-nums;
}
.toolbar-meta-strong {
  color: var(--n-100); font-weight: 700; font-size: var(--fs-md);
}
[data-theme="light"] .toolbar-meta { color: var(--n-500); }
[data-theme="light"] .toolbar-meta-strong { color: var(--cdi-green); }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  background: var(--cdi-gold); color: var(--cdi-green);
  border: none; border-radius: var(--r-sm);
  padding: 8px 14px; font-size: var(--fs-sm); font-weight: 700;
  cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background var(--t-fast), transform var(--t-fast);
  font-family: inherit;
}
.btn:hover { background: var(--cdi-gold-hover); text-decoration: none;
             transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-ghost {
  background: transparent; color: var(--n-300);
  border: 1px solid var(--n-700);
}
.btn-ghost:hover {
  background: var(--n-850); color: var(--n-50);
  border-color: var(--n-600);
}
.btn-danger {
  background: rgba(248, 113, 113, 0.15); color: var(--bad);
  border: 1px solid rgba(248, 113, 113, 0.3);
}
.btn-danger:hover { background: rgba(248, 113, 113, 0.25); color: var(--bad); }

/* ── Cards ───────────────────────────────────────────────────────────────── */
.card {
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: var(--r-md);
  padding: 16px;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
  position: relative;
}
.card-raised { background: var(--n-850); }
.card-clickable { cursor: pointer; }
.card-clickable:hover { border-color: var(--n-600); box-shadow: var(--shadow-md); }

.grid { display: grid; gap: 10px; }
/* Plant-Volumes-by-Product-Type tile row (Overview).
   v2.9.0528.14 — auto-fit so adding/removing a product type reflows
   the row instead of leaving an empty 5th cell or wrapping a 5th tile
   onto a near-empty second row. minmax(220px, 1fr) keeps each tile
   readable (matches the cap on a hand-tuned 4-column 1500px viewport)
   while letting 1 / 2 / 3 / 4 / 5+ tiles share one row when possible.
   Distinct from `.section-grid` which deliberately stays at fixed
   5-column to preserve its 2-row span pattern. */
.product-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
/* Five-column desktop grid with explicit responsive breakpoints, NOT
   auto-fit. Was previously `auto-fit, minmax(190px, 1fr)` — on wide
   monitors that packed 7+ tiles per row, which broke the carefully-
   planned 2-row pattern (full-height tiles span 2 rows; compact tiles
   stack 2 per column). With a fixed 5 columns the pattern always
   resolves predictably:
     • Plant Section Status: 1 full + 4 compact → 5 cols × 2 rows
     • Butter Line:          1 full + 8 compact → 5 cols × 2 rows
     • Powder Lines:         3 full + 4 compact → 5 cols × 2 rows
   At narrower viewports the column count steps down explicitly via the
   media queries below so the same content shrinks proportionally
   instead of reflowing into a different number of cells.

   `grid-auto-flow: dense` lets the engine backfill empty cells with
   subsequent compact tiles when a full-height tile takes both rows. */
.section-grid {
  grid-template-columns: repeat(5, 1fr);
  grid-auto-rows: minmax(50px, auto);
  grid-auto-flow: dense;
}
/* Step down responsively. Each break point keeps the same compact /
   full distinction; only the column count changes. */
@media (max-width: 1500px) { .section-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 1100px) { .section-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 800px)  { .section-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px)  { .section-grid { grid-template-columns: 1fr; } }
/* The span-2 / span-1 rule is for the Overview grid only. Dedicated-page
   summary bands (.summary-band) have their own dense layout and should
   keep their natural single-row height — the `:not(.summary-band)`
   guard prevents Butter/Powder/Receiving summary tiles from inflating
   to 2 grid-row heights. */
.section-grid:not(.summary-band) > .section-card         { grid-row: span 2; }
.section-grid:not(.summary-band) > .section-card-compact { grid-row: span 1; min-height: 64px; }
.section-card-compact { padding: 8px 12px; }
/* Inside a compact card the big number is closer to the header — drop
   the flex-stretch on `.section-big` so the value doesn't get pulled to
   the bottom of a half-height card. */
.section-card-compact .section-big   { flex: none; padding: 0;
                                        font-size: var(--fs-2xl); }
.section-card-compact .section-sub   { margin-top: 2px; }
/* Rec Bays compact tile (v2.9.0602.2): keep the pip strip tight so the
   tile height tracks the rest of the Plant-Section-Status row instead of
   ballooning. Smaller pips + minimal gap above them. */
.rec-bays-tile .benhill-strip { margin-top: 4px; gap: 2px; }
.rec-bays-tile .benhill-pip   { width: 15px; height: 15px; font-size: 9px; }
.silos-grid   { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }

/* 4-column variant of the summary band, for pages that publish exactly
   four headline tiles (e.g. /silos: Total / Avg / High / Low). Stretches
   the tiles edge-to-edge instead of leaving a fifth empty cell from the
   default 5-column .section-grid. Same responsive step-down as the
   parent. */
.section-grid.section-grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1100px) { .section-grid.section-grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px)  { .section-grid.section-grid-4 { grid-template-columns: 1fr; } }

/* v2.9.0528.14 — the two .product-grid media queries (1100px → 2col,
   700px → 1col) are gone. auto-fit + minmax(220px, 1fr) on the base
   rule now handles every viewport: tiles step down 4 → 3 → 2 → 1 as
   the container narrows, on a per-tile-width threshold instead of
   a hand-picked breakpoint. .section-grid below is unaffected — its
   5/4/3/2/1 fixed-column cascade still has the same explicit rules. */

/* ── Product totals (Overview) ───────────────────────────────────────────── */
.product-card {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 12px 8px;
  text-align: center;
  border-top: 3px solid var(--accent);
}
.product-card header {
  display: flex; align-items: center; justify-content: center; gap: 10px;
}
.product-card .product-name {
  /* Larger, more prominent title (was --fs-xs = 11px). */
  font-size: var(--fs-lg); font-weight: 700;
  color: var(--accent); letter-spacing: 1.6px; text-transform: uppercase;
}
.product-icon {
  width: 32px; height: 32px; flex-shrink: 0;
  background: transparent;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1;
}
.product-value {
  display: flex; align-items: baseline; justify-content: center; gap: 6px;
}
.product-value-num {
  font-size: var(--fs-2xl); font-weight: 700; color: var(--n-50);
  line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.product-value-unit { font-size: var(--fs-sm); color: var(--n-500); }
.product-foot {
  font-size: var(--fs-xs); color: var(--n-500);
  display: flex; align-items: center; justify-content: center; gap: 4px;
}

/* ── Section status (Overview) ───────────────────────────────────────────── */
.section-card {
  display: flex; flex-direction: column;
  padding: 10px 12px;
  text-decoration: none; color: inherit;
  transition: all var(--t-fast);
  min-height: 110px;
}
.section-card:hover {
  text-decoration: none; border-color: var(--cdi-gold);
  transform: translateY(-2px); box-shadow: var(--shadow-md);
}
.section-card header {
  font-size: var(--fs-xs); font-weight: 600;
  color: var(--cdi-gold); margin-bottom: 4px;
  display: flex; align-items: center; gap: 6px;
  text-transform: uppercase; letter-spacing: 0.8px;
}
.section-card.silos     header { color: var(--info); }
.section-card.utilities header { color: var(--cdi-gold); }
.section-card.butter    header { color: #FFCC80; }
.section-card.powder    header { color: #FFB300; }
/* Plant Section Status row (v2.9.0602.3): every tile matches the Powder
   Lines tiles — same header colour + left-border accent — so the three
   Overview sections read uniformly. */
.plant-status-grid > .section-card        { border-left: 3px solid #FFB300; }
.plant-status-grid > .section-card header { color: #FFB300; }
.section-big {
  font-size: var(--fs-3xl); font-weight: 700; line-height: 1.0;
  color: var(--n-50); text-align: center;
  font-variant-numeric: tabular-nums; letter-spacing: -0.03em;
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 4px 0;
}
.section-sub {
  font-size: var(--fs-xs); color: var(--n-400); text-align: center;
  margin-top: 4px;
}

/* Compact variant — used as a per-page summary band above the main content.
   Overview keeps the larger default. */
/* Summary band tiles sit in the parent .section-grid's 5-column track by
   default, which leaves whitespace on the right when the band has fewer
   than 5 tiles (Receiving has 3, Powder has 4). Override with auto-fit
   so the tiles fill the full width and shrink gracefully on narrow
   screens — each tile keeps a 240 px minimum so it never goes unreadable. */
.summary-band {
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
@media (max-width: 1500px) { .summary-band { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); } }
@media (max-width: 1100px) { .summary-band { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } }
@media (max-width: 800px)  { .summary-band { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); } }
@media (max-width: 540px)  { .summary-band { grid-template-columns: 1fr; } }
.summary-band .section-card     {
  min-height: 0; padding: 8px 12px;
  display: grid; grid-template-columns: 1fr auto;
  grid-template-rows: auto auto; column-gap: 12px; row-gap: 0;
  align-items: baseline;
}
.summary-band .section-card header {
  font-size: var(--fs-xs); margin: 0; letter-spacing: 0.6px;
  grid-column: 1; grid-row: 1; align-self: center;
  font-weight: 700;   /* bold top-row tile titles (v2.9.0603.17) */
}
.summary-band .section-big      {
  font-size: var(--fs-xl); flex: none;
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  display: block; text-align: right; line-height: 1;
}
.summary-band .section-sub      {
  font-size: var(--fs-xs); margin: 0; text-align: left;
  grid-column: 1; grid-row: 2;
}

/* Half-height summary band (Butter top row, v2.9.0603.20) — tighter padding
   and a smaller headline so the row takes about half the vertical space. */
.summary-band-half .section-card { padding: 4px 12px; }
.summary-band-half .section-big  { font-size: var(--fs-lg); }
.summary-band-half .section-card header { font-size: 10px; letter-spacing: 0.4px; }
.summary-band-half .section-sub  { font-size: 10px; line-height: 1.15; }

/* ── Admin log feed ────────────────────────────────────────────────────── */
.log-feed {
  font-family: inherit;
  font-size: 12px;
  background: var(--n-900);
  border: 1px solid var(--n-800);
  border-radius: 6px;
  max-height: 540px;
  overflow-y: auto;
  padding: 4px 0;
}
.log-row {
  display: grid;
  grid-template-columns: 70px 70px 160px 1fr;
  gap: 8px;
  padding: 3px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  white-space: pre-wrap;
  word-break: break-word;
  align-items: baseline;
}
.log-row:last-child { border-bottom: 0; }
.log-ts     { color: var(--n-500); font-variant-numeric: tabular-nums; }
.log-level  { font-weight: 700; letter-spacing: 0.5px; }
.log-logger { color: var(--n-400); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.log-msg    { color: var(--n-100); }
.log-debug    .log-level { color: var(--n-500); }
.log-info     .log-level { color: #6BA8FF; }
.log-warning  .log-level { color: #FFB300; }
.log-warning  .log-msg   { color: #FFD27A; }
.log-error    .log-level { color: #F87171; }
.log-error    .log-msg   { color: #FCA5A5; }
.log-critical .log-level,
.log-critical .log-msg   { color: #F87171; font-weight: 700; }
[data-theme="light"] .log-feed {
  background: #F8FAFC;
  border-color: var(--n-800);
}
[data-theme="light"] .log-row {
  border-bottom-color: rgba(0,0,0,0.04);
}
[data-theme="light"] .log-msg     { color: var(--n-50); }
[data-theme="light"] .log-logger  { color: var(--n-500); }
[data-theme="light"] .log-info    .log-level { color: #1D4ED8; }
[data-theme="light"] .log-warning .log-msg   { color: #92400E; }
[data-theme="light"] .log-error   .log-msg   { color: #991B1B; }

/* ── System Logs — single filter bar + expandable detail (v2.9.0529.4) ───── */
.log-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.log-toolbar-search {
  flex: 1 1 240px;
  min-width: 200px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: 6px;
  color: var(--n-500);
}
.log-toolbar-search input {
  flex: 1;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  padding: 7px 0;
  outline: none;
}
.log-toolbar-select {
  flex: 0 0 auto;
  padding: 7px 10px;
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: 6px;
  color: var(--n-200);
  font: inherit;
  cursor: pointer;
}
.log-toolbar-auto {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  color: var(--n-300);
  cursor: pointer;
}
.log-toolbar-auto small { color: var(--n-500); }
.log-timerange { position: relative; }
.log-timerange-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 1400;
  min-width: 260px;
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.log-timerange-pop label { display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-xs); color: var(--n-400); }
.log-timerange-pop input {
  padding: 6px 8px; background: var(--n-850);
  border: 1px solid var(--n-700); border-radius: 5px;
  color: var(--n-100); font: inherit;
}

/* Blue left accent on the whole feed window — mirrors the reference. */
.log-feed { border-left: 3px solid var(--accent-blue, #3B82F6); }

/* The expanded detail panel spans all four grid columns and indents
   slightly under the message. */
.log-detail {
  grid-column: 1 / -1;
  margin-top: 6px;
  padding: 8px 10px;
  background: rgba(255,255,255,0.03);
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11px;
}
.log-detail-row { display: flex; gap: 10px; }
.log-detail-key {
  flex: 0 0 110px;
  color: var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-size: 10px;
}
.log-row { cursor: pointer; }
.log-row:hover { background: rgba(255,255,255,0.03); }

[data-theme="light"] .log-toolbar-search,
[data-theme="light"] .log-toolbar-select,
[data-theme="light"] .log-timerange-pop {
  background: #ffffff;
  border-color: var(--n-300);
  /* Strong near-black text so the filter controls are crisp on white —
     --n-700 in light theme is a pale border-grey (#B8C2CF) and read as
     washed-out here (v2.9.0605.x). */
  color: var(--n-100);
}
[data-theme="light"] .log-toolbar-search input { color: var(--n-100); }
[data-theme="light"] .log-toolbar-search input::placeholder { color: var(--n-500); }
[data-theme="light"] .log-toolbar-auto   { color: var(--n-200); }
[data-theme="light"] .log-detail { background: rgba(0,0,0,0.03); }
[data-theme="light"] .log-row:hover { background: rgba(0,0,0,0.03); }

/* ── Time-in-status tile (Butter + Powder history drawers) ───────────────── */
/* Tile colors come in as inline CSS variables on each instance:
     --state-c       : full-opacity hex (e.g. #10B981) — label + left bar
     --state-bg      : rgba tint for background (computed by DASH.stateColorRgba)
     --state-border  : rgba tint for the outline
     --state-label-c : darker-of-state color used in light theme so label
                       stays legible on the lighter background tint.
   Avoiding CSS color-mix() so this works on every webkit build that ships
   with the plant-floor browsers. */
.tis-tile {
  padding: 10px 12px;
  text-align: center;
  border-radius: 8px;
  border: 1px solid var(--state-border, rgba(136,136,136,0.30));
  border-left: 6px solid var(--state-c, #888);
  background: var(--state-bg, rgba(136,136,136,0.10));
  transition: transform var(--t-fast);
  min-height: 70px;
}
.tis-tile:hover { transform: translateY(-1px); }
.tis-tile-label {
  font-size: var(--fs-xs);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--state-c, var(--n-300));
  margin-bottom: 4px;
}
.tis-tile-duration {
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--n-50);
  font-variant-numeric: tabular-nums;
}
.tis-tile-pct {
  font-size: 10px;
  color: var(--n-400);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
[data-theme="light"] .tis-tile-label    { color: var(--state-label-c, var(--state-c, var(--n-100))); }
[data-theme="light"] .tis-tile-duration { color: var(--n-50); }
[data-theme="light"] .tis-tile-pct      { color: var(--n-500); }

/* ── Report catalog tile (Reports landing grid) ──────────────────────────── */
.report-tile:hover {
  transform: translateY(-2px);
  border-color: var(--cdi-gold);
  box-shadow: var(--shadow-md);
}
.report-tile-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: var(--n-850); border-radius: 8px;
}
[data-theme="light"] .report-tile-icon { background: #F1F5F9; }
.report-tile-title { font-weight: 700; color: var(--cdi-gold); }
[data-theme="light"] .report-tile-title { color: #B45309; }

/* ── Themed confirm modal (window.appConfirm) ──────────────────────────── */
.app-confirm-root {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  animation: appConfirmIn 120ms ease-out;
}
@keyframes appConfirmIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.app-confirm-backdrop {
  position: absolute; inset: 0;
  background: rgba(8, 12, 18, 0.55);
  backdrop-filter: blur(2px);
}
.app-confirm-card {
  position: relative;
  background: var(--n-900); color: var(--n-50);
  border: 1px solid var(--n-700); border-radius: 12px;
  min-width: 320px; max-width: 480px;
  box-shadow: 0 24px 48px rgba(0,0,0,0.5);
  overflow: hidden;
}
.app-confirm-head {
  padding: 16px 20px 0 20px;
}
.app-confirm-head h3 {
  margin: 0; font-size: var(--fs-lg); font-weight: 700;
  color: var(--cdi-gold);
}
.app-confirm-body {
  padding: 12px 20px 18px 20px;
  font-size: var(--fs-base); line-height: 1.5;
  color: var(--n-200);
  white-space: pre-wrap;
}
.app-confirm-foot {
  display: flex; gap: 10px; justify-content: flex-end;
  padding: 12px 20px;
  background: var(--n-850); border-top: 1px solid var(--n-800);
}
[data-theme="light"] .app-confirm-card {
  background: #FFFFFF; color: var(--n-50);
  border-color: var(--n-800);
}
[data-theme="light"] .app-confirm-body { color: var(--n-100); }
[data-theme="light"] .app-confirm-foot { background: #F1F5F9; border-top-color: #E2E8F0; }
.benhill-strip {
  display: flex; flex-wrap: wrap; gap: 3px; justify-content: center;
  margin-top: 6px;
}
.benhill-pip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  font-size: 10px; font-weight: 700; color: #0F1316;
  transition: transform var(--t-fast);
}
.benhill-pip:hover { transform: scale(1.15); cursor: default; }
.benhill-pip.on      { background: var(--ok); }
.benhill-pip.off     { background: var(--bad); }
.benhill-pip.pending { background: var(--n-600); }   /* awaiting PLC tag */

/* ── Silo cards (Silos & Tanks) ──────────────────────────────────────────── */
/* Sized to match the eq-card on Butter / Powder / Receiving so every
   operator page renders tiles at the same scale. Knobs (graphic, font
   sizes, meta row spacing) all stepped down one notch from their
   pre-v2.8 values. */
.silo-card { padding: 10px 12px; }
.silo-head {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 4px;
}
.silo-tag { font-size: var(--fs-base); font-weight: 700; color: var(--cdi-gold); }
.silo-plc { font-size: var(--fs-xs); color: var(--n-500); }
.silo-body { display: flex; align-items: center; gap: 10px; }
.silo-graphic { width: 60px; height: 92px; flex-shrink: 0; }
.silo-stats   { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.silo-lbs-num { font-size: var(--fs-xl); font-weight: 700; color: var(--n-50);
                font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.silo-lbs-unit { font-size: var(--fs-xs); color: var(--n-500); margin-left: 3px; }
.silo-pct     { font-size: var(--fs-md); font-weight: 700; font-variant-numeric: tabular-nums; }
.silo-status  { font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.7px; }

/* Silo cards honour --eq-accent the same way eq-cards do
   (v2.9.0524.5) so admin threshold edits land on the border + pct text. */
.silo-ok       .silo-pct, .silo-ok       .silo-status { color: var(--eq-accent, var(--n-500)); }
.silo-low      .silo-pct, .silo-low      .silo-status { color: var(--warn); }
/* EMPTY is informational, not alarming — distinct from CRITICAL which signals
   overflow risk. Use neutral grey so operators can scan a section and only
   notice red where it actually matters. */
.silo-empty    .silo-pct, .silo-empty    .silo-status { color: var(--eq-accent, var(--n-500)); }
.silo-high     .silo-pct, .silo-high     .silo-status { color: var(--eq-accent, #FFCC00); }
.silo-critical .silo-pct, .silo-critical .silo-status { color: var(--eq-accent, var(--bad)); }
.silo-unknown  .silo-pct, .silo-unknown  .silo-status { color: var(--n-500); }

/* Colored left-edge accent — mirrors the section-card treatment on the
   butter/powder pages so the same color you see in the numeric value is
   echoed at the tile's left border. Lets operators scan a wall of tanks
   and pick out the in-distress ones at a glance. */
.silo-card { border-left: 4px solid var(--n-700); }
.silo-card.silo-ok       { border-left-color: var(--eq-accent, var(--ok));   }
.silo-card.silo-low      { border-left-color: var(--eq-accent, var(--warn));  }
.silo-card.silo-empty    { border-left-color: var(--eq-accent, var(--n-600)); }
.silo-card.silo-high     { border-left-color: var(--eq-accent, #FFCC00);      }
.silo-card.silo-critical { border-left-color: var(--eq-accent, var(--bad));   }
.silo-card.silo-unknown  { border-left-color: var(--eq-accent, var(--n-600)); }

/* Product-type chip shown under the status label on each tank card.
   Color-coded per product so operators can scan a section and spot
   off-pattern tanks (e.g. an RT holding cream instead of raw milk) at
   a glance. Falls back to a neutral chip if the product isn't one of
   the known ones. */
.silo-product {
  margin-top: 2px;
  display: inline-block; align-self: flex-start;
  padding: 1px 7px; border-radius: 10px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.3px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.18);
  color: var(--n-100);
  max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
[data-theme="light"] .silo-product {
  background: rgba(0,0,0,0.05);
  border-color: rgba(0,0,0,0.15);
  color: var(--n-700);
}
/* Per-product color coding. Slugs are computed in transform() —
   lowercase, non-alphanumeric collapsed to hyphens. */
.silo-product.silo-product-raw-milk {
  background: rgba(100,181,246,0.18); border-color: rgba(100,181,246,0.55);
  color: #1e88e5;
}
.silo-product.silo-product-cream-42 {
  background: rgba(255,196,0,0.20); border-color: rgba(255,196,0,0.60);
  color: #b07700;
}
.silo-product.silo-product-buttermilk {
  background: rgba(245,245,220,0.25); border-color: rgba(200,180,140,0.60);
  color: #8a7430;
}
.silo-product.silo-product-cond-skim-low-heat-38,
.silo-product.silo-product-cond-skim-high-heat-38,
.silo-product.silo-product-cond-skim-low-heat-33,
.silo-product.silo-product-whole-milk-condensed {
  background: rgba(76,175,80,0.18); border-color: rgba(76,175,80,0.55);
  color: #1b5e20;
}
[data-theme="light"] .silo-product.silo-product-raw-milk         { color: #0d47a1; }
[data-theme="light"] .silo-product.silo-product-cream-42          { color: #8a5d00; }
[data-theme="light"] .silo-product.silo-product-buttermilk        { color: #5a4d20; }
[data-theme="light"] .silo-product[class*="silo-product-cond-"],
[data-theme="light"] .silo-product.silo-product-whole-milk-condensed { color: #0d3d10; }

/* Per-silo operational placeholders: Temperature, Time-at-Temp, Time-in-Silo.
   Renders below the existing stats inside silo-card. Once real PLC tags
   arrive, JS will replace the placeholder values + apply silo-meta-good /
   silo-meta-warn based on the target ranges noted in each row's title. */
.silo-meta {
  margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--n-700);
  display: flex; flex-direction: column; gap: 1px;
  font-size: 10px;
}
[data-theme="light"] .silo-meta { border-top-color: rgba(0,0,0,0.08); }
.silo-meta-row {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 1px 0;
}
.silo-meta-lbl {
  color: var(--n-500); font-weight: 600; letter-spacing: 0.3px;
  text-transform: uppercase; font-size: 9px;
}
.silo-meta-val { font-weight: 700; font-variant-numeric: tabular-nums; font-size: 11px; }
.silo-meta-pending .silo-meta-val { color: var(--n-500); }
.silo-meta-good   .silo-meta-val { color: #1b5e20; }
.silo-meta-warn   .silo-meta-val { color: var(--warn); }
.silo-meta-bad    .silo-meta-val { color: var(--bad); }
[data-theme="light"] .silo-meta-good .silo-meta-val { color: #1b5e20; }

.silo-section-block { margin-bottom: 30px; }
.silo-section-block .section-meta {
  font-size: var(--fs-xs); color: var(--n-500); margin-left: auto;
  font-variant-numeric: tabular-nums;
}

.empty {
  grid-column: 1 / -1;
  text-align: center; padding: 40px;
  color: var(--n-500); font-style: italic;
}

/* ── Equipment cards (Butter / Powder / Utilities) ───────────────────────── */
.eq-grid       { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.eq-grid-tight { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }

.eq-card {
  display: flex; flex-direction: column;
  padding: 12px 14px; min-height: 150px;
  border-left: 3px solid var(--n-700);
  transition: all var(--t-fast);
  cursor: default;
}
.eq-card-compact { min-height: 100px; }
.eq-card header {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 8px;
}
.eq-label { font-size: var(--fs-base); font-weight: 700; color: var(--cdi-gold); }
.eq-pos   { font-size: var(--fs-xs); color: var(--n-500); }
.eq-status {
  font-size: var(--fs-xl); font-weight: 700;
  text-align: center; letter-spacing: 0.5px;
}
.eq-card-compact .eq-status { font-size: var(--fs-md); }

/* Tote (PDR) — status-only tile (no Run Rate, no Flow). With those
   rows hidden the card has a single value to display, so center it
   vertically and bump the font size so the tile reads at a glance
   from across the room (v2.9.0528.9). The flex: 1 + align-self push
   the .eq-status row into the remaining vertical space, then the
   larger font fills the void. */
.eq-card-tote .eq-status {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(var(--fs-xl) * 2);
  line-height: 1;
  margin: 8px 0;
}
.eq-metrics {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 4px 10px;
  margin: 10px 0 6px;
  font-size: var(--fs-xs);
}
.eq-metric-label { color: var(--n-500); }
.eq-metric-value {
  color: var(--n-100); font-weight: 700; text-align: right;
  font-variant-numeric: tabular-nums;
}
.eq-foot {
  display: flex; justify-content: space-between; gap: 8px;
  font-size: var(--fs-xs); color: var(--n-500);
  margin-top: auto; padding-top: 6px;
  border-top: 1px solid var(--n-800);
}
.eq-tag { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0.65; }
.eq-age { flex-shrink: 0; }

/* Two-line status footer (v2.9.0531.7): "In Status" + "Last Comm." rows,
   styled like the silo-meta block on the Silos page. Each row is an
   uppercase label on the left and a tabular value on the right. The
   value colour on the "Last Comm." row is set inline by
   DASH.statusAgeColor() (green/amber/red by freshness); the "In Status"
   row inherits the default text colour. A `—` placeholder shows when the
   PLC isn't yet sending that signal (e.g. before the heartbeat rolls out
   to a given tag). */
.eq-statmeta {
  margin-top: auto; padding-top: 6px;
  border-top: 1px solid var(--n-800);
  display: flex; flex-direction: column; gap: 1px;
}
[data-theme="light"] .eq-statmeta { border-top-color: rgba(0,0,0,0.08); }
.eq-statmeta-row {
  display: flex; justify-content: space-between; gap: 8px; align-items: baseline;
}
.eq-statmeta-lbl {
  color: var(--n-500); font-weight: 600; letter-spacing: 0.3px;
  text-transform: uppercase; font-size: 9px; flex-shrink: 0;
}
.eq-statmeta-val {
  font-weight: 700; font-variant-numeric: tabular-nums; font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.eq-statmeta-val.is-pending { color: var(--n-500); font-weight: 600; }

/* Per-equipment Run Rate row. Sits between the status text and the
   bottom tag/age footer. Bold value when a rate is published; faded
   "— awaiting tag" when no rate tag exists yet. */
.eq-runrate {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px; margin-top: 6px; padding-top: 6px;
  border-top: 1px dashed var(--n-700);
  font-size: var(--fs-xs);
}
[data-theme="light"] .eq-runrate { border-top-color: rgba(0,0,0,0.10); }
.eq-runrate-lbl {
  color: var(--n-500); text-transform: uppercase;
  letter-spacing: 0.5px; font-weight: 700; font-size: 10px;
}
.eq-runrate-val {
  font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--n-100);
}
[data-theme="light"] .eq-runrate-val { color: var(--n-700); }
.eq-runrate-pending {
  color: var(--n-500); font-weight: 600;
}
.eq-runrate-pending small {
  font-size: 9px; font-weight: 600; opacity: 0.7;
  text-transform: uppercase; letter-spacing: 0.4px;
  margin-left: 4px;
}

/* Plant-6 process-flow rate (PPH = pounds per hour). Same row layout
   as .eq-runrate so the two rows stack cleanly on the same card. PPH
   value uses tabular-nums + the brand gold so it stands out from the
   Run Rate row above (which uses the regular n-100 text color). */
.eq-pph {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px; margin-top: 4px;
  font-size: var(--fs-xs);
}
.eq-pph-lbl {
  color: var(--n-500); text-transform: uppercase;
  letter-spacing: 0.5px; font-weight: 700; font-size: 10px;
}
.eq-pph-val {
  font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--cdi-gold);
}
[data-theme="light"] .eq-pph-val { color: #B45309; }

/* Secondary flow row (e.g. EVP discharge) — same row layout but the
   value uses a slightly muted gold so the Feed row above reads as the
   primary metric. */
.eq-pph-secondary .eq-pph-val { opacity: 0.85; }

/* ── EVP card expansion (v2.9.0527.1) ─────────────────────────────────
   EVP cards carry five additional rows (Temperature, MVR Discharge
   Flow, MVR Density %, TVR Discharge Flow, TVR Density %) below the
   standard Status / Run Rate / Flow / Discharge rows. Result is a
   taller card that visually anchors the start of each P6 / P7 / P8
   line section, with the smaller SEP / HPP / DRY cards wrapping to its
   right at standard height.

   `grid-row: span 2` lets the EVP occupy two grid rows so two smaller
   cards can stack vertically alongside it without forcing the entire
   row to the EVP's height. `order: -1` floats the EVP visually to the
   start of the section regardless of its position in the data array
   (which mirrors process-flow order: SEP → EVP → HPP → DRY). */
.eq-card-evp {
  grid-row: span 2;
  order: -1;
}
.eq-card-evp .eq-evp-rows {
  border-top: 1px dashed var(--border-muted, #d8d8d8);
  margin-top: 8px;
  padding-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Tighter spacing on the EVP-specific rows so the card doesn't sprawl. */
.eq-card-evp .eq-evp-rows .eq-pph { padding: 2px 0; }

/* ── Avapac card (v2.9.0527.1) ────────────────────────────────────────
   PPM (lbs/min) renders as a regular .eq-pph row above the (shared)
   PPH row. No layout override — Avapacs stay at standard card height. */
.eq-card-avapac .eq-runrate-val { font-variant-numeric: tabular-nums; }

/* Section-level total PPH chip — sits inline with the section title on
   the Powder page. Gold pill against the page background so the
   running total reads at a glance. */
.section-flow-chip {
  display: inline-block; margin-left: 12px;
  background: rgba(255, 193, 7, 0.18);
  border: 1px solid rgba(255, 193, 7, 0.45);
  border-radius: 12px;
  padding: 2px 10px;
  font-size: var(--fs-xs);
  font-weight: 700; color: var(--cdi-gold);
  font-variant-numeric: tabular-nums;
}
[data-theme="light"] .section-flow-chip {
  background: rgba(255, 193, 7, 0.22);
  border-color: rgba(255, 152, 0, 0.5);
  color: #B45309;
}

/* Per-card accent colour driven by the admin-managed thresholds
   (v2.9.0524.5). Templates set `--eq-accent: <hex>` inline via
   :style on each article from DASH.styleFor("cluster", value). The
   fallback keeps the legacy eq-on / eq-cip / eq-off appearance
   when no inline style is supplied (e.g. older templates, kiosk
   widgets that haven't been migrated yet). */
.eq-on       { border-left-color: var(--eq-accent, var(--ok)); }
.eq-on       .eq-status { color: var(--eq-accent, var(--ok)); }
.eq-off      { border-left-color: var(--eq-accent, var(--bad)); }
.eq-off      .eq-status { color: var(--eq-accent, var(--bad)); }
.eq-cip      { border-left-color: var(--eq-accent, var(--warn)); }
.eq-cip      .eq-status { color: var(--eq-accent, var(--warn)); }
.eq-unknown  { border-left-color: var(--eq-accent, var(--n-500)); }
.eq-unknown  .eq-status { color: var(--eq-accent, var(--n-500)); }
.eq-missing  { border-left-color: var(--n-700); opacity: 0.5; }
.eq-missing  .eq-status { color: var(--n-500); font-size: var(--fs-xs); letter-spacing: 0.8px; }

/* Aggregate rollup tile (e.g. Churn Combined on /butter) — distinct
   gold left-edge and gold label so it visually reads as "this is the
   total of the cards next to it", not just another piece of equipment.
   Stacks on top of the eq-on/eq-missing colour, so both selectors apply. */
/* Drive the whole tile (left bar + value + any accent-tinted shadow) off one
   gold accent so the border, the "PPH" value, and the card's accent shadow
   all read as the same colour. Previously the stacked `eq-on` rule pushed the
   value green while the border stayed gold (a mismatch operators flagged).
   v2.9.0603.16. */
.eq-aggregate            { --eq-accent: var(--cdi-gold); border-left-color: var(--cdi-gold) !important; }
.eq-aggregate .eq-status { color: var(--cdi-gold); }
[data-theme="light"] .eq-aggregate            { --eq-accent: #B45309; border-left-color: #B45309 !important; }
[data-theme="light"] .eq-aggregate .eq-status { color: #B45309; }

.eq-clickable { cursor: pointer; }
.eq-clickable:hover {
  border-color: var(--n-600);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
/* "click for history" hover hint removed v2.9.0606.4 — it shared the
   top-right corner with the per-tile PLC label (.eq-pos, added .0606.3)
   and overran it on hover. Tiles already read as clickable, so the hint
   is redundant. Hidden here so the inert spans in butter.html / powder.html
   never render. */
.eq-card-history-hint { display: none; }

/* ── Power section (Utilities) ───────────────────────────────────────────── */
.power-row {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 14px;
}
@media (max-width: 900px) { .power-row { grid-template-columns: 1fr; } }
.power-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 22px; text-align: center;
  border-top: 3px solid var(--warn);
}
.power-num  { font-size: var(--fs-5xl); font-weight: 700; line-height: 1;
              font-variant-numeric: tabular-nums; letter-spacing: -0.04em; }
.power-unit { font-size: var(--fs-md); color: var(--n-500); margin-top: 4px; font-weight: 600; }
.power-sub  { font-size: var(--fs-xs); color: var(--n-500); margin-top: 14px; }
.power-ok       .power-num { color: var(--ok); }
.power-warn     .power-num { color: var(--warn); }
.power-high     .power-num { color: #FF9800; }
.power-critical .power-num { color: var(--bad); }
.power-unknown  .power-num { color: var(--n-500); }

.power-spark { display: flex; flex-direction: column; padding: 14px; }
.spark-head  {
  display: flex; justify-content: space-between;
  font-size: var(--fs-xs); color: var(--n-500); text-transform: uppercase;
  letter-spacing: 1px; margin-bottom: 8px;
}
.spark-min-max { color: var(--n-400); font-variant-numeric: tabular-nums; }
.spark-chart   { flex: 1; min-height: 140px; }

/* Grid-Power chart range selector (v2.9.0531.8) — small segmented pills in
   the sparkline header. Active range gets the CDI gold accent. */
.spark-range { display: flex; gap: 2px; flex-wrap: wrap; }
.spark-range-btn {
  font: inherit; font-size: 10px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase; cursor: pointer;
  padding: 2px 8px; border-radius: 4px;
  border: 1px solid var(--n-700); background: transparent; color: var(--n-400);
  line-height: 1.4;
}
.spark-range-btn:hover { border-color: var(--cdi-gold); color: var(--n-200); }
.spark-range-btn.is-active {
  background: var(--cdi-gold); border-color: var(--cdi-gold); color: #1a1a1a;
}
[data-theme="light"] .spark-range-btn { color: var(--n-500); border-color: var(--n-700); }
[data-theme="light"] .spark-range-btn.is-active { color: #1a1a1a; }

/* ── Receiving bays ──────────────────────────────────────────────────────── */
.bay-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.bay-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 20px 12px;
  border-top: 3px solid var(--info);
  text-align: center;
}
.bay-num   { font-size: var(--fs-md); font-weight: 700; color: var(--info); }
.bay-icon  {
  width: 72px; height: 72px; margin: 12px 0;
  background: rgba(96, 165, 250, 0.1); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;            /* clip the tanker illustration to the circle */
  /* Status RING: --eq-accent (set on the bay card from the live value) is the
     status colour, so the ring is green when running / red when off / grey
     while pending — the clear at-a-glance state cue now that the tanker art
     itself is a fixed-colour illustration. v2.9.0613.2. */
  border: 3px solid var(--eq-accent, var(--n-600));
  box-sizing: border-box;
  color: var(--info);
}
/* Milk-tanker illustration (v2.9.0612.3, replaced the box-truck emoji). It's a
   multi-colour SVG, so status is shown by the circle tint (.bay-on / .bay-off
   backgrounds below), not the icon colour. */
.bay-icon .bay-tanker { display: block; }
/* Wheels spin only while the bay is running. Each .tw group rotates about its
   own centre; respects the user's reduced-motion preference. */
.bay-icon .tw { transform-box: fill-box; transform-origin: center; }
@keyframes bayTankerSpin { to { transform: rotate(360deg); } }
.bay-on .bay-icon .tw { animation: bayTankerSpin 0.8s linear infinite; }
@media (prefers-reduced-motion: reduce) { .bay-on .bay-icon .tw { animation: none; } }
.bay-status {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.9px;
  color: var(--warn); line-height: 1.4;
}
/* "Time in current status" row on each bay card — small label above, larger
   tabular-numeric value below. Matches the BH eq-card metric pattern. */
.bay-tis {
  display: flex; flex-direction: column; align-items: center;
  margin-top: 10px; gap: 2px;
}
.bay-tis-lbl {
  font-size: 10px; font-weight: 700; letter-spacing: 0.6px;
  text-transform: uppercase; color: var(--n-500);
}
.bay-tis-val {
  font-size: var(--fs-md); font-weight: 700; color: var(--n-200);
  font-variant-numeric: tabular-nums;
}
.bay-foot  { font-size: var(--fs-xs); color: var(--n-500); margin-top: 10px; }

/* Live-state coloring for receiving bays. Pending = neutral (default);
   on = green; off = red. Plus a colored left-edge accent (4 px) to match
   the silo / butter / powder tile treatment so a wall of bays is easy
   to scan at a glance. */
.bay-card { border-left: 4px solid var(--n-700); }
/* Bay tiles use the same --eq-accent pattern as eq-card so admin
   thresholds on receiving.bays drive the colour (v2.9.0524.5). */
.bay-on  { border-top-color: var(--eq-accent, var(--ok));  border-left-color: var(--eq-accent, var(--ok)); }
.bay-on  .bay-status { color: var(--eq-accent, var(--ok)); }
.bay-on  .bay-icon   { background: rgba(76, 175, 80, 0.15); color: var(--eq-accent, var(--ok)); }
.bay-off { border-top-color: var(--eq-accent, var(--bad)); border-left-color: var(--eq-accent, var(--bad)); }
.bay-off .bay-status { color: var(--eq-accent, var(--bad)); }
.bay-off .bay-icon   { background: rgba(204, 0, 0, 0.10); color: var(--eq-accent, var(--bad)); }
.bay-pending { border-top-color: var(--n-600); border-left-color: var(--n-600); }

.rt-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.rt-card { padding: 14px; border-left: 3px solid var(--n-700); }
.rt-card header {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 8px;
}
.rt-tag  { font-size: var(--fs-base); font-weight: 700; color: var(--cdi-gold); }
.rt-plc  { font-size: var(--fs-xs); color: var(--n-500); }
.rt-body { display: flex; gap: 14px; align-items: stretch; height: 100px; }
.rt-bar  {
  width: 30px; background: rgba(255,255,255,0.03);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  position: relative; overflow: hidden;
  display: flex; align-items: flex-end;
}
.rt-bar-fill { width: 100%; transition: height 0.4s ease, background var(--t-fast); }
.rt-stats   { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 4px; }
.rt-lbs     { font-size: var(--fs-xl); font-weight: 700; color: var(--n-50); line-height: 1;
              font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.rt-unit    { font-size: var(--fs-xs); color: var(--n-500); margin-left: 4px; font-weight: 500; }
.rt-pct     { font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; }
.rt-label   { font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.7px; }
.rt-ok       { border-left-color: var(--n-500); }
.rt-ok       .rt-pct, .rt-ok       .rt-label { color: var(--n-500); }
.rt-low      { border-left-color: var(--warn); }
.rt-low      .rt-pct, .rt-low      .rt-label { color: var(--warn); }
.rt-empty    { border-left-color: var(--bad); }
.rt-empty    .rt-pct, .rt-empty    .rt-label { color: var(--bad); }
.rt-high     { border-left-color: #FFCC00; }
.rt-high     .rt-pct, .rt-high     .rt-label { color: #FFCC00; }
.rt-critical { border-left-color: var(--bad); }
.rt-critical .rt-pct, .rt-critical .rt-label { color: var(--bad); }

/* ── Trends ──────────────────────────────────────────────────────────────── */
.trends-layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 16px;
  align-items: flex-start;
}
@media (max-width: 1100px) {
  .trends-layout { grid-template-columns: 1fr; }
}

.trends-sidebar {
  position: sticky; top: 76px;
  max-height: calc(100vh - 100px);
  display: flex; flex-direction: column;
  padding: 14px;
  overflow: hidden;
}
@media (max-width: 1100px) {
  .trends-sidebar { position: relative; top: 0; max-height: none; }
}
.trends-sidebar-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 10px;
}
.trends-sidebar-head h3 {
  font-size: var(--fs-md); color: var(--n-100);
  display: flex; align-items: center; gap: 6px;
}
.trends-selected-count {
  font-size: var(--fs-xs); color: var(--n-500);
  background: var(--n-850); border-radius: 999px;
  padding: 2px 8px; font-weight: 600;
}
.trends-search {
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 8px 10px; font-size: var(--fs-sm); width: 100%;
  margin-bottom: 8px; font-family: inherit;
}
.trends-search:focus { outline: none; border-color: var(--cdi-gold); }

.trends-sidebar-actions {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-bottom: 10px;
  padding-bottom: 10px; border-bottom: 1px solid var(--n-800);
}
.btn-sm { padding: 5px 9px; font-size: var(--fs-xs); }

.trends-groups {
  flex: 1; overflow-y: auto;
  margin-right: -8px; padding-right: 8px;  /* breathing room for scrollbar */
}
.trends-group { margin-bottom: 6px; }
.trends-group-head {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 4px 6px 8px; cursor: pointer;
  user-select: none;
  border-radius: var(--r-sm);
  transition: background var(--t-fast);
  border-left: 3px solid transparent;
}
.trends-group-head:hover { background: var(--n-850); }
/* Active-selection accent on the group container. Visible whether the
   group is open or collapsed so operators can spot which categories
   have selections at a glance. */
.trends-group.has-selection > .trends-group-head {
  border-left-color: var(--cdi-green);
  background: rgba(76,175,80,0.06);
}
.trends-group-name  { flex: 1; font-size: var(--fs-sm); font-weight: 600; color: var(--n-100); }
.trends-group-selected {
  font-size: 10px; font-weight: 700; letter-spacing: 0.3px;
  color: #fff;
  background: var(--cdi-green);
  padding: 1px 7px; border-radius: 999px;
  white-space: nowrap;
}
[data-theme="light"] .trends-group-selected {
  background: var(--cdi-green); color: #fff;
}
.trends-group-count {
  font-size: 10px; color: var(--n-500);
  background: var(--n-800); padding: 1px 6px; border-radius: 999px;
}
.trends-group-all {
  font-size: 10px; font-weight: 700; letter-spacing: 0.4px;
  color: var(--cdi-green); background: transparent;
  border: 1px solid var(--cdi-green); border-radius: 999px;
  padding: 1px 8px; cursor: pointer; transition: all var(--t-fast);
  margin-right: 2px;
}
.trends-group-all:hover { background: var(--cdi-green); color: #fff; }
.trends-group-caret { color: var(--n-500); font-size: 12px; transition: transform var(--t-fast); }
.trends-group:not(.open) .trends-group-caret { transform: rotate(-90deg); }
.trends-group-list {
  list-style: none; margin: 0; padding: 2px 0 4px 4px;
}

.trends-tag-row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: var(--r-sm);
  cursor: pointer; transition: background var(--t-fast);
  font-size: var(--fs-sm);
}
.trends-tag-row:hover { background: var(--n-850); }
.trends-tag-row.selected {
  background: rgba(255, 193, 7, 0.08);
}
.trends-tag-row input[type="checkbox"] {
  margin: 0; cursor: pointer; accent-color: var(--cdi-gold);
}
.trends-tag-swatch {
  width: 10px; height: 10px; border-radius: 3px;
  border: 1px solid var(--n-700);
  flex-shrink: 0; transition: all var(--t-fast);
}
.trends-tag-label { flex: 1; color: var(--n-300); }
/* Attribute badge — small pill noting which variable of the equipment
   is being plotted (Pounds, Run Rate, Power Import, etc.). Today most
   equipment publishes a single graphable attribute, but the badge makes
   the multi-attribute concept visible so when extra attributes
   (Temperature, etc.) appear they fit visually as additional rows. */
.trends-tag-attr {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 1px 6px; border-radius: 8px;
  background: rgba(76,175,80,0.10);
  border: 1px solid rgba(76,175,80,0.35);
  color: #4caf50;
  white-space: nowrap;
}
[data-theme="light"] .trends-tag-attr {
  background: rgba(27,94,32,0.08);
  border-color: rgba(27,94,32,0.30);
  color: #1b5e20;
}
.trends-tag-unit  {
  font-size: 10px; color: var(--n-500); font-style: italic;
  margin-left: 6px;
}

/* Main panel */
.trends-main { display: flex; flex-direction: column; gap: 14px; }

.trends-toolbar {
  display: flex; flex-wrap: wrap; gap: 18px; align-items: center;
  padding: 14px 16px;
}
.trends-toolbar-section {
  display: flex; flex-direction: column; gap: 4px;
}
.trends-toolbar-section.trends-toolbar-actions {
  margin-left: auto; flex-direction: row; align-items: center; gap: 12px;
}
.trends-toolbar-label {
  font-size: 10px; color: var(--n-500);
  text-transform: uppercase; letter-spacing: 0.8px; font-weight: 700;
}
.trends-toolbar-toggle {
  font-size: var(--fs-sm); color: var(--n-400);
  display: flex; align-items: center; gap: 5px; cursor: pointer;
}
.trends-toolbar-toggle input { accent-color: var(--cdi-gold); }
.trends-bucket {
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 6px 10px; font-size: var(--fs-sm); min-width: 110px;
  font-family: inherit;
}
.btn-disabled { opacity: 0.4; pointer-events: none; }

/* Pill group (time-range, chart-type) */
.pill-group { display: flex; gap: 4px; }
.pill {
  background: transparent; border: 1px solid var(--n-700);
  color: var(--n-400); padding: 6px 12px;
  font-size: var(--fs-sm); font-weight: 600;
  border-radius: var(--r-sm); cursor: pointer;
  transition: all var(--t-fast); font-family: inherit;
  display: inline-flex; align-items: center; gap: 4px;
}
.pill:hover { color: var(--n-100); border-color: var(--n-600); }
.pill.active {
  background: var(--cdi-gold); color: var(--cdi-green);
  border-color: var(--cdi-gold); font-weight: 700;
}
/* Custom pill: faded when inactive, amber when active (user has zoomed). */
.pill-custom.active {
  background: rgba(255, 193, 7, 0.18) !important;
  color: var(--cdi-gold) !important;
  border-color: var(--cdi-gold) !important;
}
[data-theme="light"] .pill-custom.active {
  background: rgba(180, 83, 9, 0.12) !important;
  color: #B45309 !important;
  border-color: #B45309 !important;
}

/* Custom datetime range picker */
.trends-custom-picker {
  padding: 16px;
  border-left: 3px solid var(--cdi-gold);
  animation: picker-in 160ms ease-out;
}
@keyframes picker-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.custom-picker-row {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: 14px;
}
.custom-picker-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-xs); color: var(--n-500);
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px;
}
.custom-picker-field input {
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 7px 10px; font-size: var(--fs-base); min-width: 220px;
  font-family: inherit;
}
.custom-picker-field input:focus {
  outline: none; border-color: var(--cdi-gold);
}
.custom-picker-shortcuts {
  display: flex; gap: 4px; padding-bottom: 1px;
}
.custom-picker-actions {
  margin-left: auto; display: flex; gap: 8px;
}
.custom-picker-hint {
  margin: 12px 0 0; font-size: var(--fs-sm); color: var(--n-400);
}
.custom-picker-hint strong { color: var(--cdi-gold); font-variant-numeric: tabular-nums; }
[data-theme="light"] .custom-picker-field input {
  background: #FFFFFF; color: var(--n-50);
}
[data-theme="light"] .custom-picker-field input:focus { border-color: var(--cdi-green); }
[data-theme="light"] .custom-picker-hint strong { color: var(--cdi-green); }
[data-theme="light"] .trends-custom-picker { border-left-color: var(--cdi-green); }

/* Chart */
.trends-chart-wrap  { position: relative; padding: 16px; min-height: 480px; }
.trends-chart       { width: 100%; height: 460px; position: relative; z-index: 1; }
.trends-empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--n-500); font-style: italic;
  pointer-events: none;     /* never intercept mouse events */
  text-align: center;
  z-index: 0;
}
.trends-loading {
  position: absolute; top: 16px; right: 20px;
  font-size: var(--fs-xs); color: var(--cdi-gold);
  display: flex; align-items: center; gap: 4px;
  pointer-events: none;     /* never intercept mouse events */
  z-index: 2;
}

/* Stats strip */
.trends-stats {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.trends-stat-card { padding: 12px 14px; }
.trends-stat-card header {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 8px;
}
.trends-stat-swatch {
  width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0;
}
.trends-stat-label {
  font-size: var(--fs-sm); font-weight: 700; color: var(--n-100);
  flex: 1;
}
.trends-stat-remove {
  background: transparent; border: none; color: var(--n-500);
  cursor: pointer; padding: 2px; display: flex; align-items: center;
  border-radius: 3px;
}
.trends-stat-remove:hover { color: var(--bad); background: rgba(248,113,113,0.1); }
.trends-stat-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 4px 12px; margin: 6px 0; padding: 0;
}
.trends-stat-grid dt {
  font-size: 10px; color: var(--n-500);
  text-transform: uppercase; letter-spacing: 0.6px; font-weight: 700;
}
.trends-stat-grid dd {
  margin: 0; font-size: var(--fs-md); font-weight: 700;
  color: var(--n-50); font-variant-numeric: tabular-nums;
  text-align: right;
}
.trends-stat-divider {
  font-size: 10px; color: var(--n-500);
  text-transform: uppercase; letter-spacing: 0.8px; font-weight: 700;
  margin: 10px 0 4px;
  padding-top: 8px; padding-bottom: 2px;
  border-top: 1px solid var(--n-800);
  text-align: center;
}
[data-theme="light"] .trends-stat-divider {
  color: var(--n-500); border-top-color: var(--n-700);
}
.trends-stat-deltas dd { font-size: var(--fs-md); }
.delta-positive { color: var(--ok)      !important; }
.delta-negative { color: var(--bad)     !important; }
.delta-zero     { color: var(--n-500)   !important; }
.trends-stat-foot {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--n-800);
  font-size: 10px; color: var(--n-500);
}
.trends-stat-tag { font-size: 10px; word-break: break-all; }
.trends-stat-unit { font-style: italic; }

/* Light-theme overrides for the new components */
[data-theme="light"] .trends-search {
  background: var(--n-900); color: var(--n-50);
}
[data-theme="light"] .trends-search:focus { border-color: var(--cdi-green); }
[data-theme="light"] .trends-group-head:hover { background: var(--n-850); }
[data-theme="light"] .trends-tag-row:hover { background: var(--n-850); }
[data-theme="light"] .trends-tag-row.selected {
  background: rgba(27, 94, 32, 0.08);
}
[data-theme="light"] .trends-selected-count {
  background: rgba(27, 94, 32, 0.12); color: var(--cdi-green);
}
[data-theme="light"] .trends-group-count {
  background: var(--n-800); color: var(--n-500);
}
[data-theme="light"] .trends-bucket {
  background: var(--n-900); color: var(--n-50);
}
[data-theme="light"] .pill {
  background: #FFFFFF; border-color: var(--n-700); color: var(--n-400);
}
[data-theme="light"] .pill:hover {
  color: var(--cdi-green); border-color: var(--cdi-green);
}
[data-theme="light"] .pill.active {
  background: var(--cdi-green); color: #FFFFFF; border-color: var(--cdi-green);
}
[data-theme="light"] .trends-stat-foot { border-top-color: var(--n-700); }
[data-theme="light"] .trends-loading { color: var(--cdi-green); }

/* ── Reports ─────────────────────────────────────────────────────────────── */
.report-card { padding: 0; overflow: hidden; }
.report-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; gap: 12px;
  border-bottom: 1px solid var(--n-800); flex-wrap: wrap;
}
.report-head .subsection-title { margin: 0; }
.report-head .subsection-title::after { display: none; }
.report-table { width: 100%; border-collapse: collapse; font-size: var(--fs-base); }
.report-table th, .report-table td {
  padding: 11px 18px; text-align: left;
  border-bottom: 1px solid var(--n-800);
}
.report-table thead th {
  background: var(--n-850);
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.7px;
  color: var(--n-300); font-weight: 700;
  border-bottom: 2px solid var(--n-700);
}
.report-table td.num, .report-table th.num {
  text-align: right; font-variant-numeric: tabular-nums;
}
.report-table tr:hover td { background: rgba(255,193,7,0.04); }
.report-empty { text-align: center; padding: 30px; color: var(--n-500); font-style: italic; }

/* Recommended-report key-figure band (mirrors the DOCX gold stat band) */
.kpi-band {
  display: flex; flex-wrap: wrap; gap: 1px;
  background: rgba(199,119,56,0.18);
  border-top: 1px solid rgba(199,119,56,0.30);
  border-bottom: 1px solid rgba(199,119,56,0.30);
}
.kpi-band .kpi {
  flex: 1 1 0; min-width: 140px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 14px 12px;
  background: var(--card-bg, rgba(255,255,255,0.02));
}
.kpi-band .kpi-v { font-size: var(--fs-xl); font-weight: 700; color: var(--cdi-gold, #C77738); line-height: 1.1; }

/* Light-theme: give report chrome a defined (not washed-out) look. The gold
   #FFC107 ink and the muted grey table headers disappear on the light
   surface; pin them to the readable amber/slate the rest of the app uses.
   v2.9.0603.16. */
[data-theme="light"] .report-head {
  background: #F1F5F9;
  border-bottom: 2px solid var(--cdi-green);
}
[data-theme="light"] .report-table thead th {
  background: #E8EDF3;
  color: #334155;
  border-bottom: 2px solid rgba(27,94,32,0.45);
}
[data-theme="light"] .report-table th, [data-theme="light"] .report-table td {
  border-bottom-color: #E2E8F0;
}
[data-theme="light"] .kpi-band {
  background: rgba(180,83,9,0.12);
  border-top-color: rgba(180,83,9,0.30);
  border-bottom-color: rgba(180,83,9,0.30);
}
[data-theme="light"] .kpi-band .kpi { background: #FFFFFF; }
[data-theme="light"] .kpi-band .kpi-v { color: #B45309; }
[data-theme="light"] .kpi-band .kpi-l { color: var(--n-500); }
.kpi-band .kpi-l { font-size: var(--fs-xs); letter-spacing: .04em; text-transform: uppercase; color: var(--n-500); }
.report-table tr.row-flag td { background: rgba(199,119,56,0.10); }
.report-table tr.row-flag td:first-child { box-shadow: inset 3px 0 0 var(--cdi-gold, #C77738); }

/* On-screen report chart (ECharts) — a non-table view of the same report data,
   sized to read on screen and when filtered to a short period. v2.9.0603.16. */
.report-chart { width: 100%; height: 300px; padding: 8px 10px 4px; }
.report-chart-sm { height: 240px; }
.report-chart-wrap { border-bottom: 1px solid var(--n-800); }
[data-theme="light"] .report-chart-wrap { border-bottom-color: #E2E8F0; }
.report-viewtabs { display: inline-flex; gap: 4px; }
.report-viewtab {
  font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  padding: 4px 12px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--n-700); background: transparent; color: var(--n-400);
}
.report-viewtab.active { background: var(--cdi-green); color: #fff; border-color: var(--cdi-green); }
[data-theme="light"] .report-viewtab { border-color: #CBD5E1; color: var(--n-300); }
[data-theme="light"] .report-viewtab.active { background: var(--cdi-green); color: #fff; border-color: var(--cdi-green); }
.report-livechip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .4px;
  padding: 4px 10px; border-radius: 12px;
  color: var(--cdi-green); background: rgba(27,94,32,0.12);
  border: 1px solid rgba(27,94,32,0.35);
}

/* Drawer history "WINDOW OPENED" pseudo-row: marks the state the equipment
   was already in at window start. Strong top border + chip so it isn't
   mistaken for an in-window transition. */
.drawer-history-table tbody tr.drawer-history-window-row td {
  background: rgba(255, 193, 7, 0.06);
  border-top: 2px solid var(--cdi-yellow, #FFC107);
  color: var(--n-300);
}
.drawer-history-table tbody tr.drawer-history-window-row:hover td {
  background: rgba(255, 193, 7, 0.10);
}
.drawer-history-window-chip {
  display: inline-block;
  background: var(--cdi-yellow, #FFC107);
  color: #1a1a1a;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  padding: 2px 7px;
  border-radius: 3px;
  margin-right: 10px;
  vertical-align: middle;
}
[data-theme="light"] .drawer-history-table tbody tr.drawer-history-window-row td {
  background: rgba(255, 193, 7, 0.18);
  color: var(--n-200);
}

/* Compact local-users table: fits inside the narrow Settings card. The
   parent .local-users-scroll allows horizontal scroll if the row still
   exceeds the card width on very small viewports. */
.local-users-table th, .local-users-table td {
  padding: 6px 8px;
  font-size: var(--fs-sm);
}
.local-users-table th { white-space: nowrap; }
.local-users-table td .btn { margin-right: 4px; }
.local-users-table td .btn:last-child { margin-right: 0; }
.local-users-scroll { border: 1px solid var(--n-800); border-radius: var(--r-sm); }
[data-theme="light"] .local-users-scroll { border-color: var(--n-700); }

/* ── Environment strip (always-visible banner in UAT/staging) ─────────── */
.env-strip {
  background: linear-gradient(90deg, #f9a825 0%, #ef6c00 100%);
  color: #1a1a1a;
  text-align: center;
  padding: 6px 16px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.3px;
  border-bottom: 2px solid rgba(0, 0, 0, 0.15);
}
.env-strip strong {
  font-weight: 800;
  letter-spacing: 2px;
  background: rgba(0, 0, 0, 0.18);
  color: #fff;
  padding: 1px 8px;
  margin-right: 4px;
  border-radius: 3px;
}

/* ── Environment badge (UAT/staging marker in the brand area) ─────────── */
.env-badge {
  display: inline-block;
  margin-left: 10px;
  padding: 3px 10px;
  font-size: 10px; font-weight: 800; letter-spacing: 1.5px;
  background: #f9a825; color: #1a1a1a;
  border-radius: 4px;
  vertical-align: middle;
  box-shadow: 0 0 0 2px rgba(249, 168, 37, 0.25);
}
[data-theme="light"] .env-badge { background: #ef6c00; color: #fff; }

/* ── Audit log event chips ─────────────────────────────────────────────── */
.audit-event-chip {
  display: inline-block;
  font-size: 10px; font-weight: 700; letter-spacing: 0.4px;
  padding: 2px 7px; border-radius: 3px;
  font-family: inherit;
  border: 1px solid transparent;
}
.audit-event-login-success    { background: rgba(76,175,80,0.18);  color: #81c784; border-color: rgba(76,175,80,0.35); }
.audit-event-login-failure    { background: rgba(204,0,0,0.18);    color: #ef5350; border-color: rgba(204,0,0,0.35); }
.audit-event-login-ratelimited{ background: rgba(255,179,0,0.18);  color: #ffb74d; border-color: rgba(255,179,0,0.35); }
.audit-event-logout           { background: rgba(120,120,120,0.18);color: #bbb;     border-color: rgba(120,120,120,0.35); }
[data-theme="light"] .audit-event-login-success    { background: rgba(27,94,32,0.12);  color: #1b5e20; border-color: rgba(27,94,32,0.4); }
[data-theme="light"] .audit-event-login-failure    { background: rgba(183,28,28,0.10); color: #b71c1c; border-color: rgba(183,28,28,0.4); }
[data-theme="light"] .audit-event-login-ratelimited{ background: rgba(230,138,0,0.12); color: #b06b00; border-color: rgba(230,138,0,0.4); }
[data-theme="light"] .audit-event-logout           { background: rgba(80,80,80,0.10);  color: #555;    border-color: rgba(80,80,80,0.35); }
/* Navigation / activity trail (v2.9.06xx) — page.view (blue), user.action (teal). */
.audit-event-page-view        { background: rgba(0,107,255,0.16);  color: #64b5f6; border-color: rgba(0,107,255,0.35); }
.audit-event-user-action      { background: rgba(26,188,156,0.18); color: #4db6ac; border-color: rgba(26,188,156,0.35); }
[data-theme="light"] .audit-event-page-view        { background: rgba(0,86,179,0.10);  color: #0056b3; border-color: rgba(0,86,179,0.4); }
[data-theme="light"] .audit-event-user-action      { background: rgba(0,121,107,0.10); color: #00796b; border-color: rgba(0,121,107,0.4); }

/* ── Shared tile-drawer container (v2.9.0524.8) ──────────────────────────
   One drawer DOM tree per page (mounted in base.html). Hidden until any
   page calls DASH.openTileDrawer(...), which adds `.open`. */
#tile-drawer-root { display: none; }
#tile-drawer-root.open { display: block; }

/* ── Drawer (used by Butter history + universal tile drawer) ─────────── */
.drawer-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  z-index: 200; backdrop-filter: blur(4px);
  animation: fadein 0.18s ease;
}
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(640px, 100%);
  background: var(--n-900);
  border-left: 1px solid var(--n-700);
  box-shadow: var(--shadow-lg);
  z-index: 201;
  display: flex; flex-direction: column;
  animation: slidein 0.22s ease;
}
@keyframes slidein { from { transform: translateX(20px); opacity: 0.6; } to { transform: translateX(0); opacity: 1; } }
.drawer-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px 22px; border-bottom: 1px solid var(--n-800);
}
.drawer-title {
  font-size: var(--fs-lg); font-weight: 600; color: var(--n-50);
  display: flex; align-items: center; gap: 10px;
}
.drawer-close {
  background: transparent; border: 1px solid var(--n-700);
  color: var(--n-400); width: 32px; height: 32px;
  border-radius: var(--r-sm); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--t-fast);
}
.drawer-close:hover { background: var(--n-850); color: var(--n-50); }
.drawer-body { flex: 1; overflow-y: auto; padding: 22px; }

/* ── Settings page — vertical tab sidebar (v2.9) ─────────────────────────
   Tabs got too crowded across the top once we hit 11 of them and a 12th
   is on the way (Thresholds). Moved to a left-sidebar layout inside the
   /settings page only — main top-nav (Overview / Silos / Receiving /
   etc.) stays unchanged. The sidebar is sticky so it stays visible
   while the right-hand content panel scrolls. */
.settings-shell {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 20px;
  align-items: start;
}
.settings-tabs {
  display: flex; flex-direction: column; gap: 2px;
  position: sticky; top: 12px;
  padding: 6px;
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: 8px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}
[data-theme="light"] .settings-tabs {
  background: #fff;
  border-color: rgba(0,0,0,0.10);
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.settings-tab {
  background: transparent; border: none; cursor: pointer;
  padding: 10px 12px;
  font-size: var(--fs-sm); font-weight: 600; color: var(--n-400);
  display: flex; align-items: center; gap: 8px;
  font-family: inherit;
  text-align: left;
  border-radius: 6px;
  border-left: 3px solid transparent;
  transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.settings-tab:hover {
  color: var(--n-100);
  background: rgba(255,255,255,0.03);
}
[data-theme="light"] .settings-tab:hover { background: rgba(0,0,0,0.04); }
.settings-tab.active {
  color: var(--cdi-gold);
  border-left-color: var(--cdi-gold);
  background: rgba(255,193,7,0.06);
}
[data-theme="light"] .settings-tab.active {
  color: var(--cdi-green);
  border-left-color: var(--cdi-green);
  background: rgba(34,139,34,0.06);
}
.settings-tab svg { opacity: 0.9; flex-shrink: 0; }
.settings-content { min-width: 0; }   /* prevents grid blow-out */

/* Collapse to a stacked single column on narrow viewports — the sidebar
   sits above the content instead of beside it. */
@media (max-width: 900px) {
  .settings-shell { grid-template-columns: 1fr; }
  .settings-tabs {
    position: static; flex-direction: row; flex-wrap: wrap;
    max-height: none; overflow: visible;
  }
  .settings-tab { border-left: none; border-bottom: 3px solid transparent; }
  .settings-tab.active {
    border-left-color: transparent;
    border-bottom-color: var(--cdi-gold);
  }
}

/* ── Threshold editor — v2.9 ───────────────────────────────────────────────
   The threshold editor uses raw <input> elements in a table layout
   (not the .settings-field wrapper). Style them with the same dark
   theme + Inter font as the rest of /settings so they don't fall back
   to Times-New-Roman browser defaults. Scoped to .threshold-editor so
   the styles don't bleed into other settings tabs. */
.threshold-editor h3,
.threshold-editor p,
.threshold-editor label,
.threshold-editor table,
.threshold-editor button {
  font-family: inherit;
}
.threshold-editor table { font-size: var(--fs-sm); }
.threshold-editor th {
  color: var(--n-500);
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.6px;
  font-weight: 700;
  text-align: left;
  padding: 6px 4px;
}
.threshold-editor input[type="text"],
.threshold-editor input[type="number"] {
  background: var(--n-950);
  color: var(--n-100);
  border: 1px solid var(--n-700);
  border-radius: var(--r-sm);
  padding: 6px 9px;
  font-size: var(--fs-sm);
  font-family: inherit;
  width: 100%;
  transition: border-color var(--t-fast);
}
.threshold-editor input[type="text"]:focus,
.threshold-editor input[type="number"]:focus {
  outline: none; border-color: var(--cdi-gold);
}
/* Hex string input next to the colour swatch — uses the body font
   (v2.9.0524.5). Smaller size so the 7-char hex still reads tidily
   alongside the wider Label / Match columns. */
.threshold-editor input.thresh-hex {
  font-family: inherit;
  font-size: 11px;
}
/* Native colour-picker — strip the chrome browsers add and make it
   look like a clean swatch tile with the same rounded border the
   inputs use. */
.threshold-editor input[type="color"] {
  width: 34px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--n-700);
  border-radius: var(--r-sm);
  cursor: pointer;
  background: var(--n-950);
}
.threshold-editor input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; }
.threshold-editor input[type="color"]::-webkit-color-swatch {
  border: none; border-radius: 3px;
}
.threshold-editor input[type="color"]::-moz-color-swatch {
  border: none; border-radius: 3px;
}
/* Cluster-list nav on the editor's left side — match the settings-tab
   look so the inner cluster picker reads as a continuation of the
   outer settings sidebar, not a different design language. */
.threshold-editor .cluster-list {
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: 8px;
  padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  max-height: 70vh; overflow-y: auto;
}
.threshold-editor .cluster-unit {
  margin-left: auto;
  font-size: 10px;
  color: var(--n-500);
  font-weight: 600;
}
/* Light-theme overrides — the dark-default inputs above need to flip
   to white backgrounds. NOTE on the colour scale: this project's
   --n-* variables INVERT between themes (so --n-100 is dark on light,
   light on dark). That means `color: var(--n-100)` already does the
   right thing in both themes; we only need to override the *backgrounds*
   and borders for light mode. */
[data-theme="light"] .threshold-editor input[type="text"],
[data-theme="light"] .threshold-editor input[type="number"] {
  background: #fff;
  border-color: rgba(0,0,0,0.18);
}
[data-theme="light"] .threshold-editor input[type="color"] {
  background: #fff;
  border-color: rgba(0,0,0,0.18);
}
[data-theme="light"] .threshold-editor .cluster-list {
  background: #fff;
  border-color: rgba(0,0,0,0.10);
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
[data-theme="light"] .threshold-editor th { color: var(--n-500); }

/* Preview chips (v2.9.0524.3) — replaces the solid-fill pills with a
   subtle tinted background + coloured dot + theme-aware text. Reads
   as a chip rather than a screaming colour bar. The `--pv-color`
   custom property lets each chip tint its background from the
   per-bucket colour without inlining the rgba conversion. */
.thresh-pv-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border: 1px solid color-mix(in srgb, var(--pv-color) 50%, transparent);
  background: color-mix(in srgb, var(--pv-color) 14%, transparent);
  border-radius: 14px;
  font-size: 11px; font-weight: 600;
  /* --n-100 inverts between themes — light text on dark, dark text
     on light. Same trick the rest of the project uses. */
  color: var(--n-100);
  letter-spacing: 0.2px;
}
[data-theme="light"] .thresh-pv-chip {
  background: color-mix(in srgb, var(--pv-color) 18%, white);
  border-color: color-mix(in srgb, var(--pv-color) 55%, transparent);
}
.thresh-pv-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.10);
}
.thresh-pv-range { font-variant-numeric: tabular-nums; }
.thresh-pv-label {
  font-weight: 700;
  text-transform: uppercase; font-size: 10px; letter-spacing: 0.5px;
  opacity: 0.85;
}
.thresh-pv-label::before { content: "·  "; opacity: 0.5; font-weight: 400; }

/* ── Threshold editor — cluster groups (v2.9.0524.3) ──────────────────
   Cluster list groups (Receiving / Butter / Silos / Powder / Utilities
   / Waste). Each group header is a collapsible header with a chevron
   that rotates when expanded. */
.threshold-editor .cluster-group { margin-bottom: 4px; }
.threshold-editor .cluster-group-head {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  background: transparent; border: none;
  padding: 8px 10px 6px;
  color: var(--n-500);
  font-size: 10px; font-weight: 700; letter-spacing: 0.7px;
  text-transform: uppercase;
  cursor: pointer;
  font-family: inherit;
  border-radius: 4px;
  text-align: left;
}
.threshold-editor .cluster-group-head:hover {
  color: var(--n-100);
  background: rgba(255,255,255,0.03);
}
[data-theme="light"] .threshold-editor .cluster-group-head:hover {
  color: var(--n-900);
  background: rgba(0,0,0,0.04);
}
.threshold-editor .cluster-group-chev {
  display: inline-block;
  transition: transform var(--t-fast);
  font-size: 10px;
}
.threshold-editor .cluster-group.open .cluster-group-chev { transform: rotate(90deg); }
.threshold-editor .cluster-group-count {
  margin-left: auto; opacity: 0.6;
  font-size: 9px; font-weight: 600;
}
.threshold-editor .cluster-group-items {
  display: none; flex-direction: column; gap: 2px;
  padding-left: 4px;
}
.threshold-editor .cluster-group.open .cluster-group-items { display: flex; }

/* Inline warning banner inside the editor — shown when buckets overlap
   or categorical rules duplicate a match value. Soft amber, never red,
   so it reads as a hint, not an error. */
.threshold-editor .thresh-warn {
  margin: 10px 0;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--gold, #F39C12) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold, #F39C12) 45%, transparent);
  border-left: 3px solid var(--gold, #F39C12);
  border-radius: 6px;
  font-size: var(--fs-xs);
  color: var(--n-100);
  display: flex; gap: 8px; align-items: flex-start;
}
[data-theme="light"] .threshold-editor .thresh-warn {
  color: var(--n-800);
  background: #FFF8E1;
  border-color: #F9C46B;
  border-left-color: #B47600;
}
.threshold-editor .thresh-warn strong { color: var(--gold, #B47600); }
.threshold-editor .thresh-warn ul { margin: 4px 0 0 0; padding-left: 18px; }

/* ── Settings page — grids ───────────────────────────────────────────────── */
.settings-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
}
.settings-grid-wide { grid-template-columns: 1fr; }

/* Placeholder pane inside cards (for "Coming next" sections) */
.placeholder-pane {
  background: rgba(255, 193, 7, 0.05);
  border: 1px dashed rgba(255, 193, 7, 0.30);
  border-radius: var(--r-sm);
  padding: 18px;
  margin-top: 8px;
}
[data-theme="light"] .placeholder-pane {
  background: rgba(180, 83, 9, 0.05);
  border-color: rgba(180, 83, 9, 0.30);
}
.placeholder-title {
  font-size: var(--fs-xs); font-weight: 700;
  color: var(--cdi-gold); letter-spacing: 1px; text-transform: uppercase;
  margin: 0 0 8px;
}
[data-theme="light"] .placeholder-title { color: #B45309; }
.placeholder-pane p { margin: 0 0 8px; color: var(--n-400); font-size: var(--fs-sm); line-height: 1.55; }
.placeholder-pane p:last-child { margin-bottom: 0; }
.placeholder-hint { font-style: italic; color: var(--n-500) !important; }
.settings-card { padding: 20px; }
.settings-card-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 6px;
}
.settings-card-head h3 {
  font-size: var(--fs-md); color: var(--n-50); font-weight: 600;
}
.settings-card-head .icon { color: var(--cdi-gold); }
.settings-card-sub {
  font-size: var(--fs-xs); color: var(--n-500); margin: 0 0 16px;
}
.settings-card form { display: flex; flex-direction: column; gap: 12px; }
.settings-field {
  display: flex; flex-direction: column; gap: 4px;
}
.settings-field label {
  font-size: var(--fs-xs); color: var(--n-400); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.6px;
}
.settings-field input, .settings-field select, .settings-field textarea {
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 9px 11px; font-size: var(--fs-base);
  font-family: inherit;
  transition: border-color var(--t-fast);
}
.settings-field input:focus, .settings-field select:focus,
.settings-field textarea:focus {
  outline: none; border-color: var(--cdi-gold);
}
.settings-field input[readonly], .settings-field input[disabled] {
  background: var(--n-900); color: var(--n-500); cursor: not-allowed;
}
.settings-field .hint {
  font-size: var(--fs-xs); color: var(--n-500); margin-top: 2px;
}

/* ── General settings — 2-column grid + label:field rows (v2.9.0529.9) ─────
   Display & Plant + Shift schedule share the top row (50% each); Sibling
   plants (`.general-full`) spans the full width below. Cards lay their fields
   out as dense "label : field" rows (`.form-row`). */
.settings-grid--general {
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: start;            /* no equal-height stretch */
}
.settings-grid--general .general-full { grid-column: 1 / -1; }
.settings-grid--general .settings-card        { padding: 14px 18px; }
.settings-grid--general .settings-card-head   { margin-bottom: 8px; gap: 8px; }
.settings-grid--general .settings-card-head h3 { font-size: var(--fs-sm); }
.settings-grid--general .settings-card-sub    { margin: -4px 0 8px; font-size: 11px; line-height: 1.35; }

/* The label:field row. Label right-aligned in a fixed column, field fills
   the rest. Label tops align with the input (not the hint) via padding-top. */
.form-row {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 14px;
  align-items: start;
  padding: 7px 0;
  border-bottom: 1px solid var(--n-800);
}
.form-row:last-child { border-bottom: 0; }
.form-row > label {
  font-size: 12px; font-weight: 600; color: var(--n-300);
  text-align: right; padding-top: 7px; letter-spacing: 0.2px;
}
.form-row-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.form-row-field input,
.form-row-field select,
.form-row-field textarea {
  padding: 6px 10px; font-size: 13px; line-height: 1.3;
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  font-family: inherit; width: 100%; box-sizing: border-box;
}
.form-row-field input:focus,
.form-row-field select:focus { outline: none; border-color: var(--cdi-gold); }
.form-row-field input[readonly] { background: var(--n-900); color: var(--n-500); cursor: not-allowed; }
.form-row-field .hint { font-size: 10px; color: var(--n-500); line-height: 1.3; }

/* Shift + sibling editors keep their own inline grids; just tighten the
   field inputs + bottom margins so they match the density. */
.settings-grid--general .settings-field { gap: 2px; }
.settings-grid--general .settings-field label { font-size: 10px; letter-spacing: 0.5px; }
.settings-grid--general .settings-field input,
.settings-grid--general .settings-field select {
  padding: 5px 9px !important; font-size: 13px !important; line-height: 1.3 !important;
}
.settings-grid--general .settings-field .hint { font-size: 10px; }
.settings-grid--general .settings-card > [style*="margin-bottom"] { margin-bottom: 6px !important; }
/* Collapse to a single column (cards stack, labels above inputs) on narrow
   viewports so nothing gets cramped. */
@media (max-width: 900px) {
  .settings-grid--general { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .form-row { grid-template-columns: 1fr; gap: 3px; }
  .form-row > label { text-align: left; padding-top: 0; }
}

/* ── Authentication tab layout (v2.9.0529.9) ──────────────────────────────
   Tab access (AD group matrix) spans the full width as row 1 (`.auth-full`
   + order:-1); LDAP + Local fallback accounts share row 2 at 50% each. */
.settings-grid--auth {
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: start;
}
.settings-grid--auth .auth-full {
  grid-column: 1 / -1;
  order: -1;                     /* render the matrix first regardless of DOM order */
}
@media (max-width: 900px) {
  .settings-grid--auth { grid-template-columns: 1fr; }
}

/* ── AD permission matrix + live group picker (v2.9.0529.8) ────────────────
   Replaces the old chip-wall table. AD groups are rows, dashboard tabs are
   columns, a click-toggle ✓ cell at each intersection. The group CN column
   is sticky-left so it stays readable while scrolling the tab columns. */
.ad-picker {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin: 14px 0 10px;
}
.ad-picker-input {
  flex: 1 1 280px; min-width: 220px;
  display: flex; align-items: center; gap: 6px; padding: 0 10px;
  background: var(--n-900); border: 1px solid var(--n-700);
  border-radius: var(--r-sm); color: var(--n-500);
}
.ad-picker-input input {
  flex: 1; border: none; background: transparent; color: var(--n-100);
  font: inherit; padding: 8px 0; outline: none;
}
.ad-picker-spin { color: var(--cdi-gold); font-weight: 700; }
.ad-picker-results {
  position: absolute; top: calc(100% + 4px); left: 0;
  width: min(520px, 100%); max-height: 300px; overflow-y: auto;
  background: var(--n-900); border: 1px solid var(--n-700);
  border-radius: var(--r-sm); box-shadow: 0 6px 24px rgba(0,0,0,0.4);
  z-index: 1400; padding: 4px;
}
.ad-picker-result {
  display: flex; align-items: center; gap: 8px; width: 100%;
  text-align: left; padding: 7px 10px; border: none; background: none;
  color: var(--n-100); cursor: pointer; border-radius: 4px; font: inherit;
}
.ad-picker-result:hover { background: var(--n-800); }
.ad-picker-result .icon { color: var(--cdi-green-light); flex: 0 0 auto; }
.ad-picker-added { margin-left: auto; font-size: 10px; color: var(--n-500); font-style: italic; }
.ad-picker-msg { padding: 10px 12px; color: var(--n-500); font-size: var(--fs-sm); }

.perm-matrix-wrap {
  overflow-x: auto; margin-top: 6px;
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
}
.perm-matrix { border-collapse: collapse; width: 100%; font-size: 12px; }
.perm-matrix th, .perm-matrix td { border-bottom: 1px solid var(--n-800); }
.perm-matrix tbody tr:last-child td { border-bottom: 0; }
.perm-matrix thead th {
  position: sticky; top: 0; z-index: 1; background: var(--n-850);
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--n-400); font-weight: 700; padding: 8px 6px;
  text-align: center; white-space: nowrap;
}
.perm-cn-col {
  text-align: left !important; padding: 8px 12px !important;
  position: sticky; left: 0; background: var(--n-900); z-index: 1; min-width: 210px;
}
.perm-matrix thead .perm-cn-col { z-index: 3; background: var(--n-850); }
/* Display AD group CNs in Title Case regardless of how they're stored
   (matching stays case-insensitive; this is display-only). v2.9.0529.10 */
.perm-cn { font-weight: 600; color: var(--n-100); text-transform: capitalize; }
.perm-cn-input {
  width: 100%; box-sizing: border-box; font: inherit; padding: 5px 8px;
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: 4px;
}
.perm-cell {
  text-align: center; cursor: pointer; padding: 7px 6px; min-width: 42px;
  user-select: none;
}
.perm-cell:hover { background: var(--n-800); }
.perm-cell.perm-on { background: rgba(76,175,80,0.14); }
.perm-cell.perm-on .perm-check { color: var(--cdi-green-light); font-weight: 700; }
.perm-check { font-size: 13px; }
.perm-row-admin .perm-cn { color: var(--cdi-gold); }
.perm-rm-col { text-align: center; width: 34px; }
.perm-rm-btn {
  border: none; background: none; color: var(--n-500);
  cursor: pointer; font-size: 16px; line-height: 1; padding: 4px 8px;
}
.perm-rm-btn:hover { color: var(--bad); }

/* Light theme — sticky backgrounds + readable text. */
[data-theme="light"] .ad-picker-input,
[data-theme="light"] .ad-picker-results { background: #ffffff; border-color: var(--n-700); }
[data-theme="light"] .ad-picker-result { color: var(--n-100); }
[data-theme="light"] .ad-picker-result:hover { background: var(--n-800); }
[data-theme="light"] .perm-matrix thead th,
[data-theme="light"] .perm-matrix thead .perm-cn-col { background: var(--n-800); color: var(--n-300); }
[data-theme="light"] .perm-cn-col { background: var(--n-900); }
[data-theme="light"] .perm-cn { color: var(--n-100); }
[data-theme="light"] .perm-cell:hover { background: var(--n-800); }
[data-theme="light"] .perm-cell.perm-on { background: rgba(27,94,32,0.10); }
[data-theme="light"] .perm-cell.perm-on .perm-check { color: var(--cdi-green); }
[data-theme="light"] .perm-row-admin .perm-cn { color: #B45309; }
.settings-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--n-800);
}
.settings-banner {
  background: rgba(245, 158, 11, 0.12);
  border: 1px solid rgba(245, 158, 11, 0.3);
  color: var(--warn);
  padding: 10px 14px; border-radius: var(--r-sm);
  font-size: var(--fs-sm); margin-bottom: 16px;
  display: flex; align-items: center; gap: 8px;
}
.settings-success {
  background: rgba(74, 222, 128, 0.12);
  border: 1px solid rgba(74, 222, 128, 0.3);
  color: var(--ok);
  padding: 10px 14px; border-radius: var(--r-sm);
  font-size: var(--fs-sm); margin-bottom: 16px;
  display: flex; align-items: center; gap: 8px;
}
.role-badge {
  font-size: 10px; font-weight: 700; letter-spacing: 0.7px;
  padding: 2px 8px; border-radius: 4px; text-transform: uppercase;
}
.role-admin  { background: rgba(102, 187, 106, 0.18); color: var(--cdi-green-light); }
.role-viewer { background: rgba(96, 165, 250, 0.15); color: var(--info); }

/* ── Login ───────────────────────────────────────────────────────────────── */
.login-wrap {
  min-height: 86vh;
  display: flex; align-items: center; justify-content: center;
  padding: 40px 20px;
}
.login-card {
  background: linear-gradient(170deg, var(--n-900) 0%, var(--n-850) 100%);
  border: 1px solid var(--n-700);
  border-top: 3px solid var(--cdi-gold);
  border-radius: var(--r-lg);
  padding: 36px; width: 100%; max-width: 400px;
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; gap: 16px;
}
.login-logo { height: 64px; align-self: center; }
.login-card h1 { text-align: center; font-size: var(--fs-xl); color: var(--cdi-gold); }
.login-sub { text-align: center; color: var(--n-400); font-size: var(--fs-sm); margin: 0; }
.login-card label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-xs); color: var(--n-400);
  text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600;
}
.login-card input {
  background: var(--n-950);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 11px 13px; font-size: var(--fs-base); color: var(--n-50);
  font-family: inherit;
}
.login-card input:focus { outline: none; border-color: var(--cdi-gold); }
.login-btn {
  background: var(--cdi-gold); color: var(--cdi-green);
  border: none; border-radius: var(--r-sm);
  padding: 13px; font-size: var(--fs-md); font-weight: 700;
  cursor: pointer; letter-spacing: 0.5px;
  transition: background var(--t-fast);
  font-family: inherit;
}
.login-btn:hover { background: var(--cdi-gold-hover); }
.login-error {
  background: rgba(248, 113, 113, 0.12);
  border: 1px solid rgba(248, 113, 113, 0.3);
  border-radius: var(--r-sm); padding: 10px 12px;
  color: var(--bad); font-size: var(--fs-sm); text-align: center;
}
.login-hint {
  font-size: var(--fs-xs); color: var(--n-500); text-align: center;
  margin: 8px 0 0;
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.footer {
  position: fixed; bottom: 0; left: 0; right: 0;
  background: rgba(7, 9, 11, 0.92);
  border-top: 1px solid var(--n-800);
  padding: 8px 24px; font-size: var(--fs-xs); color: var(--n-500);
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  backdrop-filter: blur(8px);
  z-index: 50;
}
.footer-brand { font-weight: 600; letter-spacing: 0.4px; }
.footer-user  { display: flex; align-items: center; gap: 8px; }
.footer-sep   { color: var(--n-700); }
.footer-link  {
  color: var(--n-400); display: inline-flex; align-items: center; gap: 4px;
}
.footer-link:hover { color: var(--cdi-gold); text-decoration: none; }

/* ── Plant Switcher (v2.9.0529.2) ─────────────────────────────────────────
   In-footer popover that lists sibling-plant dashboards. The trigger is a
   plain <button> styled to match `.footer-link` (lives next to About). The
   popover panel is `position: absolute` and anchored above the trigger via
   `bottom: 100%` — wrapper is `position: relative` to make that work.
   Plant names only, sans-serif everywhere (no monospace), no live status
   indicators. Suppressed entirely when no sibling plants are configured. */
.plant-switcher {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.plant-switcher-trigger {
  /* Match .footer-link cosmetics but reset the button defaults. */
  background: none; border: none; cursor: pointer;
  padding: 0; margin: 0; font: inherit; letter-spacing: inherit;
  color: var(--n-400);
  display: inline-flex; align-items: center; gap: 4px;
}
.plant-switcher-trigger:hover { color: var(--cdi-gold); }
.plant-switcher-chevron {
  font-size: 0.7em;
  transition: transform var(--t-fast, 150ms) ease;
  display: inline-block;
}
.plant-switcher-chevron--open { transform: rotate(180deg); }

.plant-switcher-panel {
  /* Anchored above the trigger so the popover floats up out of the footer.
     Tightened in v2.9.0529.5 — the prior version had too much vertical
     padding and the sibling rows used a token that inverted to near-white
     on the light theme, making the names invisible. */
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  min-width: 200px;
  max-width: 300px;
  background: var(--n-900);
  border: 1px solid var(--n-700);
  border-radius: 6px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.35);
  padding: 4px 0;
  z-index: 1500;             /* above the footer, below modals */
  font-family: inherit;      /* sans-serif — explicitly no monospace */
}
.plant-switcher-section {
  /* Tighter header — small, mid-grey, minimal padding. */
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--n-500);
  font-weight: 700;
  padding: 6px 12px 2px;
}
.plant-switcher-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 12px;
  /* --n-100 auto-inverts: light text on the dark popover, dark text on the
     light-theme white popover. Always readable against --n-900 surface. */
  color: var(--n-100);
  text-decoration: none;
  cursor: pointer;
  font-weight: 600;
  font-size: var(--fs-sm, 13px);
}
.plant-switcher-row:hover,
.plant-switcher-row:focus {
  /* --n-800 is the standard hover surface (dark in dark theme, light-grey
     in light theme). Keep the text readable — don't recolor to gold which
     was hard to read on the light hover surface. */
  background: var(--n-800);
  outline: none;
}
.plant-switcher-row--current {
  cursor: default;
  background: rgba(102, 187, 106, 0.16);
  color: var(--cdi-green-light);
  font-weight: 700;
  border-left: 3px solid var(--cdi-green-light);
  padding-left: 9px;   /* 12px - 3px accent bar, keeps name aligned */
}
.plant-switcher-row--current:hover { background: rgba(102, 187, 106, 0.16); }

/* Other plants - gold, obviously different from the green current row. */
.plant-switcher-row:not(.plant-switcher-row--current) { color: var(--cdi-gold); }
.plant-switcher-row:not(.plant-switcher-row--current):hover,
.plant-switcher-row:not(.plant-switcher-row--current):focus {
  background: var(--n-800);
  color: var(--cdi-gold-hover);
}

.plant-switcher-name { font-size: inherit; font-weight: inherit; }
.plant-switcher-check { color: var(--cdi-green-light, var(--cdi-green)); font-weight: 700; }

/* Light theme - keep both states readable on the white popover. */
[data-theme="light"] .plant-switcher-panel {
  background: #ffffff;
  border: 1px solid var(--n-700);
  box-shadow: 0 4px 20px rgba(0,0,0,0.12);
}
[data-theme="light"] .plant-switcher-row--current {
  color: var(--cdi-green);
  border-left-color: var(--cdi-green);
}
[data-theme="light"] .plant-switcher-check { color: var(--cdi-green); }
[data-theme="light"] .plant-switcher-row:not(.plant-switcher-row--current)       { color: #8a6d00; }
[data-theme="light"] .plant-switcher-row:not(.plant-switcher-row--current):hover { color: #6f5600; }
[data-theme="light"] .plant-switcher-trigger       { color: var(--n-500); }
[data-theme="light"] .plant-switcher-trigger:hover { color: var(--cdi-green); }

.last-refresh {
  text-align: right;
  font-size: var(--fs-xs); color: var(--n-500); font-style: italic;
  margin: 10px 0 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   Theme toggle (top-right of nav)
   ────────────────────────────────────────────────────────────────────────── */
.theme-toggle {
  background: transparent;
  border: 1px solid var(--n-700);
  color: var(--n-400);
  width: 34px; height: 34px;
  border-radius: var(--r-sm);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--t-fast);
  margin-left: 8px;
  font-family: inherit;
}
.theme-toggle:hover {
  background: var(--n-850);
  color: var(--cdi-gold);
  border-color: var(--n-600);
}
.theme-toggle svg { display: block; }

/* CSS-driven visibility: only the icon matching the current mode is shown.
   `<html data-theme-mode="...">` is set by the init script in <head>. */
.theme-toggle .theme-icon {
  display: none; align-items: center; gap: 6px;
}
html[data-theme-mode="system"] .theme-toggle .theme-icon[data-mode="system"],
html[data-theme-mode="light"]  .theme-toggle .theme-icon[data-mode="light"],
html[data-theme-mode="dark"]   .theme-toggle .theme-icon[data-mode="dark"] {
  display: inline-flex;
}
.theme-toggle .theme-mode-label { display: none; }
@media (min-width: 1200px) {
  .theme-toggle {
    width: auto; padding: 6px 10px;
  }
  .theme-toggle .theme-mode-label {
    display: inline-block; font-size: var(--fs-xs);
    text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600;
  }
}

/* ──────────────────────────────────────────────────────────────────────────
   LIGHT THEME
   Goal: warm, paper-like background with clearly defined elevation between
   page → cards → controls. White cards pop against a slate-tinted page
   instead of disappearing.
   ────────────────────────────────────────────────────────────────────────── */
[data-theme="light"] {
  /* Neutral scale — page is a warm slate, cards are bright white */
  --n-950:  #E2E8F0;   /* page bg — strong gray-blue tint                */
  --n-900:  #FFFFFF;   /* card surface — pure white pops on the slate    */
  --n-850:  #F1F5F9;   /* table head, raised surfaces                    */
  --n-800:  #E1E7EE;   /* hover, code chips, inset                       */
  --n-700:  #B8C2CF;   /* border-default — visible, not aggressive       */
  --n-600:  #94A1B1;   /* border-strong                                  */
  --n-500:  #5A6573;   /* muted text                                     */
  --n-400:  #404B58;   /* secondary text                                 */
  --n-300:  #1F2933;   /* body text                                      */
  --n-100:  #0B1118;   /* heading text                                   */
  --n-50:   #050A0F;   /* highest contrast                               */

  /* Semantic — darker shades for adequate contrast on white */
  --ok:        #15803D;
  --warn:      #B45309;
  --bad:       #B91C1C;
  --info:      #1D4ED8;
  --neutral:   #475569;

  /* Shadows that actually read on light surfaces */
  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.10), 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 6px 18px rgba(15, 23, 42, 0.10), 0 2px 6px rgba(15, 23, 42, 0.06);
  --shadow-lg: 0 18px 40px rgba(15, 23, 42, 0.18), 0 4px 12px rgba(15, 23, 42, 0.10);
}
[data-theme="light"] body {
  background:
    radial-gradient(ellipse 1200px 600px at 50% -200px, rgba(102, 187, 106, 0.10), transparent 60%),
    var(--n-950);
  color: var(--n-300);
}

/* ── Top nav — gives the page a clear brand bar ─────────────────────────── */
[data-theme="light"] .topnav {
  background: linear-gradient(180deg, #FFFFFF 0%, #F8FAFD 100%);
  border-bottom: 3px solid var(--cdi-green);
  box-shadow: 0 1px 8px rgba(15, 23, 42, 0.08);
}
[data-theme="light"] .brand           { border-right-color: var(--n-700); }
[data-theme="light"] .brand-line-1    { color: var(--cdi-green); font-weight: 800; }
[data-theme="light"] .brand-line-2    { color: var(--n-500); }
[data-theme="light"] .nav-tabs li a   { color: var(--n-400); }
[data-theme="light"] .nav-tabs li a:hover {
  background: rgba(102, 187, 106, 0.10); color: var(--cdi-green);
  border-color: rgba(102, 187, 106, 0.25);
}
[data-theme="light"] .nav-tabs li a.active {
  background: var(--cdi-green); color: #FFFFFF;
  border-color: var(--cdi-green); font-weight: 700;
  box-shadow: 0 2px 8px rgba(27, 94, 32, 0.25);
}
[data-theme="light"] .nav-tabs li a.active .icon { color: var(--cdi-gold); }
[data-theme="light"] .nav-tabs li a.admin             { color: var(--cdi-green); }
[data-theme="light"] .nav-tabs li a.admin:hover       {
  background: rgba(27, 94, 32, 0.10);
}
[data-theme="light"] .nav-tabs li a.admin.active      {
  background: var(--cdi-green); color: #FFFFFF; border-color: var(--cdi-green);
}
[data-theme="light"] .nav-right { border-left-color: var(--n-700); }
[data-theme="light"] .nav-more-btn { color: var(--n-400); }
[data-theme="light"] .nav-more-btn:hover {
  background: rgba(102, 187, 106, 0.10); color: var(--cdi-green);
  border-color: rgba(102, 187, 106, 0.25);
}
[data-theme="light"] .nav-more-btn.active {
  background: var(--cdi-green); color: #FFFFFF;
  border-color: var(--cdi-green); font-weight: 700;
}
[data-theme="light"] .nav-more-menu {
  background: #FFFFFF; border-color: var(--n-700);
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.18);
}
[data-theme="light"] .nav-more-menu li a { color: var(--n-400); }
[data-theme="light"] .nav-more-menu li a:hover {
  background: rgba(102, 187, 106, 0.10); color: var(--cdi-green);
  border-color: rgba(102, 187, 106, 0.25);
}
[data-theme="light"] .nav-more-menu li a.active {
  background: var(--cdi-green); color: #FFFFFF; border-color: var(--cdi-green);
}
[data-theme="light"] .nav-more-menu li a.admin { color: var(--cdi-green); }
[data-theme="light"] .nav-more-menu li a.admin.active {
  background: var(--cdi-green); color: #FFFFFF; border-color: var(--cdi-green);
}
[data-theme="light"] .nav-help-icon { color: var(--cdi-green); }
[data-theme="light"] .nav-help-icon:hover { background: rgba(27, 94, 32, 0.10); }
[data-theme="light"] .nav-help-icon.active {
  background: var(--cdi-green); color: #FFFFFF; border-color: var(--cdi-green);
}
[data-theme="light"] .live-label { color: var(--ok); }
[data-theme="light"] .live-pulse { background: var(--ok); }
[data-theme="light"] .theme-toggle {
  background: #FFFFFF; border-color: var(--n-700); color: var(--n-400);
}
[data-theme="light"] .theme-toggle:hover {
  background: var(--n-850); color: var(--cdi-green); border-color: var(--cdi-green);
}

/* ── Page header — bottom border becomes a brand gradient ───────────────── */
[data-theme="light"] .page-header {
  border-bottom: 2px solid transparent;
  border-image: linear-gradient(to right, var(--cdi-green), var(--cdi-gold), transparent) 1;
  padding-bottom: 22px;
}
[data-theme="light"] .page-eyebrow  { color: var(--cdi-green); font-weight: 700; }
[data-theme="light"] .page-title    { color: var(--n-50); }
[data-theme="light"] .page-title .icon { color: var(--cdi-green); }
[data-theme="light"] .page-subtitle { color: var(--n-400); }

/* ── Section / subsection titles get a stronger visual weight ───────────── */
[data-theme="light"] .section-title       { color: var(--n-50); }
[data-theme="light"] .section-title .icon { color: var(--cdi-green); }
[data-theme="light"] .subsection-title {
  color: var(--n-50);
  padding-left: 10px;
  border-left: 3px solid var(--cdi-gold);
  border-bottom: none;
}
[data-theme="light"] .subsection-title::after {
  background: linear-gradient(to right, var(--n-700), transparent);
}

/* ── Cards — visible borders, real shadows, hover lift ──────────────────── */
[data-theme="light"] .card {
  background: var(--n-900);
  border: 1px solid var(--n-700);
  box-shadow: var(--shadow-sm);
}
[data-theme="light"] .card-raised { background: var(--n-850); }
[data-theme="light"] .section-card:hover {
  border-color: var(--cdi-green);
  box-shadow: 0 12px 28px rgba(27, 94, 32, 0.15);
}
[data-theme="light"] .card-clickable:hover {
  border-color: var(--cdi-green);
  box-shadow: var(--shadow-md);
}
[data-theme="light"] .product-icon { background: transparent; }
[data-theme="light"] .silo-tag, [data-theme="light"] .rt-tag,
[data-theme="light"] .eq-label  { color: var(--cdi-green); font-weight: 700; }
[data-theme="light"] .product-name {
  filter: brightness(0.7) saturate(1.3);
}
[data-theme="light"] .product-value-num { color: var(--n-50); }
[data-theme="light"] .section-big       { color: var(--n-50); }
[data-theme="light"] .silo-lbs-num,
[data-theme="light"] .rt-lbs            { color: var(--n-50); }

/* Section status cards — colored left bar per type for at-a-glance routing */
[data-theme="light"] .section-card           { border-left-width: 4px; }
[data-theme="light"] .section-card.silos     { border-left-color: var(--info); }
[data-theme="light"] .section-card.powder    { border-left-color: var(--warn); }
[data-theme="light"] .section-card.utilities { border-left-color: var(--cdi-gold); }
[data-theme="light"] .section-card.butter    { border-left-color: #B45309; }
/* Generic (un-typed) section-card headers — e.g. the Powder summary band's
   Stopped / In CIP / PPH tiles. Base color is --cdi-gold (#FFC107) which is
   washed out on the light surface; pin to the readable amber that the Raw
   Milk Inventory / butter tiles already use. v2.9.0603.16. */
[data-theme="light"] .section-card           header { color: var(--warn); }
[data-theme="light"] .section-card.silos     header { color: var(--info); }
[data-theme="light"] .section-card.powder    header { color: var(--warn); }
[data-theme="light"] .section-card.utilities header { color: #B45309; }
[data-theme="light"] .section-card.butter    header { color: #B45309; }
/* Plant Section Status row matches Powder tiles in light theme too. */
[data-theme="light"] .plant-status-grid > .section-card        { border-left-width: 4px; border-left-color: var(--warn); }
[data-theme="light"] .plant-status-grid > .section-card header { color: var(--warn); }

/* ── Code chips ─────────────────────────────────────────────────────────── */
[data-theme="light"] code {
  background: transparent;
  color: inherit;
  border: 0;
  font-weight: 700;
}
[data-theme="light"] pre { background: rgba(127, 127, 127, 0.10); }
[data-theme="light"] pre code { color: inherit; }

/* ── Links ──────────────────────────────────────────────────────────────── */
[data-theme="light"] a              { color: var(--cdi-green); }
[data-theme="light"] a:hover        { color: #2E7D32; }
[data-theme="light"] .footer-link   { color: var(--n-400); }
[data-theme="light"] .footer-link:hover { color: var(--cdi-green); }

/* ── Buttons — primary uses CDI green, ghosts get more presence ─────────── */
[data-theme="light"] .btn {
  background: var(--cdi-green); color: #FFFFFF;
  box-shadow: 0 2px 6px rgba(27, 94, 32, 0.25);
}
[data-theme="light"] .btn:hover {
  background: #2E7D32; color: #FFFFFF;
  box-shadow: 0 4px 10px rgba(27, 94, 32, 0.30);
}
[data-theme="light"] .btn-ghost {
  background: #FFFFFF; color: var(--n-300); border-color: var(--n-700);
  box-shadow: var(--shadow-sm);
}
[data-theme="light"] .btn-ghost:hover {
  background: var(--n-850); color: var(--cdi-green);
  border-color: var(--cdi-green);
}
[data-theme="light"] .btn-danger {
  background: rgba(185, 28, 28, 0.10); color: var(--bad);
  border-color: rgba(185, 28, 28, 0.40);
}

/* ── Form fields ────────────────────────────────────────────────────────── */
[data-theme="light"] .filters select, [data-theme="light"] .filters input,
[data-theme="light"] .settings-field input, [data-theme="light"] .settings-field select,
[data-theme="light"] .settings-field textarea,
[data-theme="light"] .login-card input {
  background: var(--n-900); color: var(--n-50);
  border: 1px solid var(--n-700);
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.04);
}
[data-theme="light"] .filters select:focus, [data-theme="light"] .filters input:focus,
[data-theme="light"] .settings-field input:focus,
[data-theme="light"] .settings-field select:focus,
[data-theme="light"] .settings-field textarea:focus,
[data-theme="light"] .login-card input:focus {
  border-color: var(--cdi-green);
  box-shadow: 0 0 0 3px rgba(27, 94, 32, 0.15);
  outline: none;
}
[data-theme="light"] .filters label { color: var(--n-500); }
[data-theme="light"] .settings-field label { color: var(--n-400); }
[data-theme="light"] .settings-field input[readonly],
[data-theme="light"] .settings-field input[disabled] {
  background: var(--n-850); color: var(--n-500); cursor: not-allowed;
}
[data-theme="light"] .settings-field .hint { color: var(--n-500); }

/* ── Login card ─────────────────────────────────────────────────────────── */
[data-theme="light"] .login-card {
  background: #FFFFFF;
  border: 1px solid var(--n-700);
  border-top: 4px solid var(--cdi-green);
}
[data-theme="light"] .login-card h1 { color: var(--cdi-green); }
[data-theme="light"] .login-sub     { color: var(--n-400); }
[data-theme="light"] .login-card label { color: var(--n-500); }
[data-theme="light"] .login-btn {
  background: var(--cdi-green); color: #FFFFFF;
  box-shadow: 0 2px 8px rgba(27, 94, 32, 0.30);
}
[data-theme="light"] .login-btn:hover { background: #2E7D32; }
[data-theme="light"] .login-error {
  background: rgba(185, 28, 28, 0.08);
  border-color: rgba(185, 28, 28, 0.30);
  color: var(--bad);
}
[data-theme="light"] .login-hint { color: var(--n-500); }

/* ── Equipment cards — bolder left-bar, status legibility on white ──────── */
[data-theme="light"] .eq-card        { border-left-width: 4px; }
[data-theme="light"] .eq-on          { border-left-color: var(--eq-accent, var(--ok)); }
[data-theme="light"] .eq-off         { border-left-color: var(--eq-accent, var(--bad)); }
[data-theme="light"] .eq-cip         { border-left-color: var(--eq-accent, var(--warn)); }
[data-theme="light"] .eq-unknown     { border-left-color: var(--eq-accent, var(--n-600)); }
[data-theme="light"] .eq-missing     { border-left-color: var(--n-700); opacity: 0.7; }
[data-theme="light"] .eq-on .eq-status  { color: var(--eq-accent, var(--ok)); }
[data-theme="light"] .eq-off .eq-status { color: var(--eq-accent, var(--bad)); }
[data-theme="light"] .eq-cip .eq-status { color: var(--eq-accent, var(--warn)); }
[data-theme="light"] .eq-metric-label   { color: var(--n-500); }
[data-theme="light"] .eq-metric-value   { color: var(--n-50); }
[data-theme="light"] .eq-foot           {
  border-top-color: var(--n-700);
  color: var(--n-500);
}

/* ── RT receiving / silo cards ──────────────────────────────────────────── */
[data-theme="light"] .rt-card { border-left-width: 4px; }
[data-theme="light"] .rt-bar  {
  background: var(--n-850); border-color: var(--n-700);
}
[data-theme="light"] .rt-ok .rt-pct, [data-theme="light"] .rt-ok .rt-label,
[data-theme="light"] .silo-ok .silo-pct, [data-theme="light"] .silo-ok .silo-status {
  color: var(--n-500);
}
[data-theme="light"] .rt-tag, [data-theme="light"] .silo-tag {
  color: var(--cdi-green);
}
[data-theme="light"] .rt-plc, [data-theme="light"] .silo-plc {
  color: var(--n-500);
}

/* Bay placeholder cards. We re-apply the `border-left` width here at
   `[data-theme="light"]`-level specificity because `[data-theme="light"] .card`
   above uses the `border` shorthand, which would otherwise reset all
   four sides back to 1 px on light mode. Same fix for silo cards
   immediately below. */
[data-theme="light"] .bay-card  { border-top-width: 4px; border-left-width: 4px; }
[data-theme="light"] .bay-on    { border-left-color: var(--eq-accent, var(--ok));  }
[data-theme="light"] .bay-off   { border-left-color: var(--eq-accent, var(--bad)); }
[data-theme="light"] .bay-pending { border-left-color: var(--n-600); }
[data-theme="light"] .silo-card           { border-left-width: 4px; border-left-color: var(--n-700); }
[data-theme="light"] .silo-card.silo-ok       { border-left-color: var(--ok);   }
[data-theme="light"] .silo-card.silo-low      { border-left-color: var(--warn); }
[data-theme="light"] .silo-card.silo-empty    { border-left-color: var(--n-600); }
[data-theme="light"] .silo-card.silo-high     { border-left-color: #FFCC00; }
[data-theme="light"] .silo-card.silo-critical { border-left-color: var(--bad);  }
[data-theme="light"] .silo-card.silo-unknown  { border-left-color: var(--n-600); }

[data-theme="light"] .bay-num  { color: var(--info); font-weight: 700; }
/* Only the PENDING (awaiting) bays get the neutral blue tint in light theme —
   the running/off bays keep their green/red status tints (.bay-on/.bay-off
   .bay-icon). The old blanket `.bay-icon` rule here clobbered those, so every
   circle showed blue regardless of status (v2.9.0613.2). */
[data-theme="light"] .bay-pending .bay-icon { background: rgba(29, 78, 216, 0.10); }
/* Light-theme bay status — pending only (warn-style). Live states
   (.bay-on, .bay-off) take precedence via the explicit class selectors
   below so they're not overridden to amber. */
[data-theme="light"] .bay-pending .bay-status { color: var(--warn); }
[data-theme="light"] .bay-on  .bay-status     { color: var(--eq-accent, var(--ok)); }
[data-theme="light"] .bay-off .bay-status     { color: var(--eq-accent, var(--bad)); }

/* ── Drawer (Butter history) ────────────────────────────────────────────── */
[data-theme="light"] .drawer {
  background: var(--n-900); border-left: 2px solid var(--cdi-green);
}
[data-theme="light"] .drawer-backdrop { background: rgba(15, 23, 42, 0.45); }
[data-theme="light"] .drawer-head     { border-bottom-color: var(--n-700); }
[data-theme="light"] .drawer-title    { color: var(--n-50); }
[data-theme="light"] .drawer-close    {
  background: #FFFFFF; color: var(--n-400); border-color: var(--n-700);
}
[data-theme="light"] .drawer-close:hover {
  background: var(--n-850); color: var(--cdi-green); border-color: var(--cdi-green);
}

/* ── Tables / Reports ───────────────────────────────────────────────────── */
[data-theme="light"] .report-card { border: 1px solid var(--n-700); }
[data-theme="light"] .report-head { border-bottom-color: var(--n-700); }
[data-theme="light"] .report-table thead th {
  background: var(--n-850); color: var(--n-400);
  border-bottom: 2px solid var(--cdi-green);
}
[data-theme="light"] .report-table td        { border-bottom-color: var(--n-800); }
[data-theme="light"] .report-table tr:hover td {
  background: rgba(27, 94, 32, 0.06);
}

/* ── Role badges ────────────────────────────────────────────────────────── */
[data-theme="light"] .role-admin {
  background: rgba(27, 94, 32, 0.14); color: var(--cdi-green);
  border: 1px solid rgba(27, 94, 32, 0.30);
}
[data-theme="light"] .role-viewer {
  background: rgba(29, 78, 216, 0.10); color: var(--info);
  border: 1px solid rgba(29, 78, 216, 0.28);
}

/* ── BenHill pip strip on overview ──────────────────────────────────────── */
[data-theme="light"] .benhill-pip { color: #FFFFFF; }
[data-theme="light"] .benhill-pip.off { background: var(--bad); }
[data-theme="light"] .benhill-pip.on  { background: var(--ok); }

/* ── Settings banners ───────────────────────────────────────────────────── */
[data-theme="light"] .settings-banner {
  background: rgba(180, 83, 9, 0.10); color: var(--warn);
  border-color: rgba(180, 83, 9, 0.30);
}
[data-theme="light"] .settings-success {
  background: rgba(21, 128, 61, 0.10); color: var(--ok);
  border-color: rgba(21, 128, 61, 0.30);
}
[data-theme="light"] .settings-card-head h3 { color: var(--n-50); }
[data-theme="light"] .settings-card-head .icon { color: var(--cdi-green); }
[data-theme="light"] .settings-actions       { border-top-color: var(--n-700); }

/* ── Filter labels / hint text ──────────────────────────────────────────── */
[data-theme="light"] .section-sub-line { color: var(--n-500); }

/* ── Footer ─────────────────────────────────────────────────────────────── */
[data-theme="light"] .footer {
  background: rgba(255, 255, 255, 0.92);
  border-top: 1px solid var(--n-700);
}
[data-theme="light"] .footer-brand { color: var(--n-400); font-weight: 600; }
[data-theme="light"] .footer-sep   { color: var(--n-600); }

/* ── Power section (utilities) ──────────────────────────────────────────── */
[data-theme="light"] .power-card { border-top: 4px solid var(--cdi-gold); }
[data-theme="light"] .spark-head { color: var(--n-500); }
[data-theme="light"] .spark-min-max { color: var(--n-400); }

/* ── Empty state ────────────────────────────────────────────────────────── */
[data-theme="light"] .empty { color: var(--n-500); }
[data-theme="light"] .report-empty { color: var(--n-500); }

/* ── Last refresh ───────────────────────────────────────────────────────── */
[data-theme="light"] .last-refresh { color: var(--n-500); }

/* ────────────────────────────────────────────────────────────────────────
   Statistics widgets + Kiosk pages
   Used by /stats/<id> (admin) and /k/<slug>/page/<id> (public kiosk).
   ──────────────────────────────────────────────────────────────────────── */
.widget-grid {
  display: grid; gap: 12px;
  /* 12-col base so fractional widths compose exactly: 1/4=3, 1/3=4, 1/2=6,
     2/3=8, 3/4=9, full=12. Lets three 1/3 tiles fill a row with no gap. */
  grid-template-columns: repeat(12, 1fr);
}
.widget-slot {
  background: var(--n-900); border: 1px solid var(--n-700);
  border-radius: var(--r-md); padding: 12px;
  position: relative; min-height: 120px;
  display: flex; flex-direction: column;
}
/* Fractional width spans (shared by widget slots and editor cards) */
.widget-slot.size-1-4,  .widget-edit-card.size-1-4  { grid-column: span 3; }
.widget-slot.size-1-3,  .widget-edit-card.size-1-3  { grid-column: span 4; }
.widget-slot.size-1-2,  .widget-edit-card.size-1-2  { grid-column: span 6; }
.widget-slot.size-2-3,  .widget-edit-card.size-2-3  { grid-column: span 8; }
.widget-slot.size-3-4,  .widget-edit-card.size-3-4  { grid-column: span 9; }
.widget-slot.size-full, .widget-edit-card.size-full { grid-column: 1 / -1; }
/* Legacy tokens (pages saved before the fractional model) */
.widget-slot.size-small,  .widget-edit-card.size-small  { grid-column: span 3; }
.widget-slot.size-medium, .widget-edit-card.size-medium { grid-column: span 6; }
.widget-slot.size-large,  .widget-edit-card.size-large  { grid-column: span 9; }
@media (max-width: 1100px) {
  /* Stack everything on narrow screens (the editor on a laptop; kiosks/TVs
     stay wide and keep the 12-col layout). */
  .widget-slot.size-1-4, .widget-slot.size-1-3, .widget-slot.size-1-2,
  .widget-slot.size-2-3, .widget-slot.size-3-4,
  .widget-slot.size-small, .widget-slot.size-medium, .widget-slot.size-large,
  .widget-edit-card.size-1-4, .widget-edit-card.size-1-3, .widget-edit-card.size-1-2,
  .widget-edit-card.size-2-3, .widget-edit-card.size-3-4,
  .widget-edit-card.size-small, .widget-edit-card.size-medium, .widget-edit-card.size-large {
    grid-column: 1 / -1;
  }
}
.widget-slot.size-tall   { min-height: 320px; }
/* Uniform Stats/kiosk tile-title colour. Every widget title (KPI, pip,
   gauge, status grid, chart) renders in this single colour so a page reads
   uniform; only product-totals tiles (per-product brand colours) and the
   Plant-Inventory summary KPI are exempt. Values/states still vary by
   threshold. Operator request 2026-06-03. */
:root { --stats-title: #C77738; }
.widget-title { font-size: var(--fs-sm); font-weight: 700;
                color: var(--stats-title); margin: 0 0 8px; }

/* KPI */
.widget-kpi { display: flex; flex-direction: column; align-items: center;
              justify-content: center; gap: 4px; flex: 1; padding: 8px 0; }
.widget-kpi-title { font-size: var(--fs-xs); color: var(--n-500);
                    text-transform: uppercase; letter-spacing: 1px;
                    font-weight: 700; }
.widget-kpi-value { font-size: var(--fs-3xl); font-weight: 700;
                    color: var(--n-50); font-variant-numeric: tabular-nums;
                    letter-spacing: -0.02em; line-height: 1; }
.widget-kpi-suffix{ font-size: var(--fs-md); color: var(--n-400); margin-left: 4px; }
.widget-kpi-sub   { font-size: var(--fs-xs); color: var(--n-500); }

/* Text */
.widget-text h3 { font-size: var(--fs-lg); color: var(--n-100);
                  font-weight: 700; margin: 0 0 6px; }
.widget-text-body { font-size: var(--fs-sm); color: var(--n-300);
                    line-height: 1.5; }

/* Product tiles */
.widget-product-grid { display: grid; gap: 8px;
                       grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
                       flex: 1; align-items: stretch; }
.widget-product-tile { background: var(--n-850); border: 1px solid var(--n-700);
                       border-top: 3px solid var(--accent); border-radius: 6px;
                       padding: 8px 10px; text-align: center;
                       display: flex; flex-direction: column; gap: 4px; }
.widget-product-tile header { display: flex; align-items: center;
                              justify-content: center; gap: 6px; }
.widget-product-icon { font-size: 18px; }
.widget-product-name { font-size: var(--fs-xs); font-weight: 700;
                       color: var(--accent); text-transform: uppercase;
                       letter-spacing: 1px; }
.widget-product-num  { font-size: var(--fs-2xl); font-weight: 700;
                       color: var(--n-50); font-variant-numeric: tabular-nums; }
.widget-product-unit { font-size: var(--fs-xs); color: var(--n-500);
                       margin-left: 4px; }

/* Charts */
.widget-chart-host { width: 100%; flex: 1; min-height: 240px; }

/* Status grid */
.widget-stat-grid { display: grid; gap: 6px;
                    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); }
.widget-stat-cell { background: var(--n-850);
                    border: 1px solid var(--n-700);
                    border-left: 3px solid var(--state-c, var(--n-500));
                    border-radius: 6px; padding: 6px 8px;
                    display: flex; flex-direction: column; gap: 1px; }
.widget-stat-label { font-size: var(--fs-xs); color: var(--n-300);
                     font-weight: 600; }
.widget-stat-state { font-size: var(--fs-sm); color: var(--state-c, var(--n-50));
                     font-weight: 700; letter-spacing: 0.4px; }
.widget-stat-sub   { font-size: 10px; color: var(--n-500); }

/* Error / empty */
.widget-error { color: var(--bad); font-size: var(--fs-xs); }
.widget-error pre { white-space: pre-wrap; word-break: break-all;
                    background: rgba(248,113,113,0.08); padding: 6px;
                    border-radius: 4px; margin: 4px 0 0; font-size: 10px; }
.widget-empty { color: var(--n-500); font-size: var(--fs-sm);
                text-align: center; padding: 16px; }

/* Kiosk shell — strips chrome, full-bleed, hides interactive affordances */
.kiosk-shell { background: var(--n-950); min-height: 100vh;
               padding: 16px; box-sizing: border-box; }
.kiosk-shell .widget-slot { background: var(--n-850); }
.kiosk-banner { position: fixed; top: 0; left: 0; right: 0;
                background: var(--cdi-green); color: var(--n-50);
                padding: 6px 14px; font-size: var(--fs-xs);
                font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
                z-index: 100; display: flex; justify-content: space-between;
                align-items: center; }
.kiosk-progress { height: 3px; background: var(--cdi-gold);
                  width: 0%; transition: width 1s linear;
                  position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; }
.kiosk-iframe { width: 100%; height: 100vh; border: 0; display: block; }

/* Stats list (admin) */
.stats-list-row { display: flex; align-items: center; justify-content: space-between;
                  padding: 10px 12px; border-bottom: 1px solid var(--n-800);
                  gap: 12px; }
.stats-list-row:last-child { border-bottom: none; }
.stats-list-name { font-weight: 600; color: var(--n-100); }
.stats-list-meta { font-size: var(--fs-xs); color: var(--n-500); }

/* Editor */
.widget-editor-row { display: grid; grid-template-columns: 1fr auto auto auto auto;
                     gap: 8px; padding: 8px 10px; align-items: center;
                     background: var(--n-850); border: 1px solid var(--n-700);
                     border-radius: 6px; margin-bottom: 6px; }
.widget-editor-row select, .widget-editor-row input { font-size: var(--fs-xs); }
.widget-editor-config { display: grid; grid-template-columns: auto 1fr;
                        gap: 4px 8px; align-items: center; font-size: var(--fs-xs);
                        padding: 6px 10px; background: var(--n-900);
                        border: 1px solid var(--n-700); border-radius: 6px;
                        margin: -4px 0 8px; }
.widget-editor-config label { color: var(--n-400); font-weight: 600; }

/* Light theme overrides */
[data-theme="light"] .widget-slot          { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .widget-product-tile  { background: #F8FAFC; border-color: #E2E8F0; }
[data-theme="light"] .widget-stat-cell     { background: #F8FAFC; border-color: #E2E8F0; }
[data-theme="light"] .widget-editor-row    { background: #F8FAFC; border-color: #E2E8F0; }
[data-theme="light"] .widget-editor-config { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .kiosk-shell          { background: #F1F5F9; }
[data-theme="light"] .kiosk-shell .widget-slot { background: #FFFFFF; }
[data-theme="light"] .widget-product-name  { color: var(--accent); }
[data-theme="light"] .widget-product-num,
[data-theme="light"] .widget-kpi-value     { color: var(--n-50); }

/* Tab-access table — group CN appears as a non-editable label so the AD
   group string stays untouched. Uses the same font as the surrounding
   body text (no monospace) so the table reads uniformly. */
.tab-access-cn {
  display: inline-block;
  font: inherit;
  font-weight: 600;
  /* AD stores the CN in whatever case the admin originally typed it; the
     server normalises to lowercase for case-insensitive matching. Show
     the visual label in title case so "Visalia Plant Dashboard - Admin"
     reads naturally without changing the stored value. */
  text-transform: capitalize;
  color: var(--n-100);
  padding: 6px 0;
  word-break: break-all;
}
[data-theme="light"] .tab-access-cn { color: var(--n-50); }

/* ────────────────────────────────────────────────────────────────────────
   Stats editor v2 — instance cards, widget tile-picker, inline preview
   ──────────────────────────────────────────────────────────────────────── */
.widget-edit-card {
  background: var(--n-850); border: 1px solid var(--n-700);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 10px;
}
.widget-edit-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-bottom: 8px;
}
.widget-edit-meta { display: flex; align-items: center; gap: 10px; }
.widget-edit-icon { font-size: 22px; line-height: 1; }
.widget-edit-title { font-weight: 700; color: var(--n-100); font-size: var(--fs-sm); }
.widget-edit-area  { font-size: 10px; color: var(--n-500);
                     text-transform: uppercase; letter-spacing: 0.7px; }
.widget-edit-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.widget-edit-size { padding: 4px 6px; font-size: var(--fs-xs); }
.widget-edit-preview {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--n-700);
}
.widget-edit-preview-label {
  font-size: 10px; color: var(--cdi-gold); letter-spacing: 1px;
  text-transform: uppercase; font-weight: 700; margin-bottom: 6px;
}

/* Tile-picker modal — widget cards grouped by area */
.widget-picker-area {
  font-size: var(--fs-xs); color: var(--cdi-gold); font-weight: 700;
  letter-spacing: 1px; margin: 4px 0 8px;
}
.widget-picker-grid {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.widget-picker-card {
  background: var(--n-850); border: 1px solid var(--n-700);
  border-radius: 8px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 4px;
  text-align: left; cursor: pointer;
  transition: all var(--t-fast);
  color: var(--n-100); font: inherit;
}
.widget-picker-card:hover {
  border-color: var(--cdi-gold);
  background: var(--n-800);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.widget-picker-emoji { font-size: 22px; line-height: 1; }
.widget-picker-title { font-weight: 700; color: var(--n-100); font-size: var(--fs-sm); }
.widget-picker-desc  { font-size: var(--fs-xs); color: var(--n-400); line-height: 1.4; }

[data-theme="light"] .widget-edit-card    { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .widget-picker-card  { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .widget-picker-card:hover { background: #F8FAFC; border-color: var(--cdi-green); }

/* Stats editor — title field that looks identical to the view-mode h1.
   Removing the secondary "Page name" card was a deliberate simplification:
   what you type IS what shows up at the top of the kiosk page. */
.page-title-edit {
  background: transparent; border: 0;
  padding: 0; margin: 0;
  width: auto; min-width: 280px;
  font: inherit; font-size: var(--fs-xl); line-height: 1;
  color: inherit;
}
.page-title-edit:focus {
  outline: none;
  /* Subtle underline cue that this is editable */
  box-shadow: 0 1px 0 0 var(--cdi-gold);
}
.page-title-edit::placeholder { color: var(--n-500); font-style: italic; }
.stats-edit-header { align-items: center; }

/* Tighter widget picker — denser cards, smaller minmax, less margin */
.widget-picker-grid {
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)) !important;
}
.widget-picker-card {
  padding: 8px 10px !important; gap: 2px !important;
}
.widget-picker-emoji { font-size: 18px; }
.widget-picker-title { font-size: var(--fs-xs); line-height: 1.2; }
.widget-picker-desc  { font-size: 10px; line-height: 1.35; color: var(--n-400); }
.widget-picker-area  {
  margin: 0 0 4px !important;
  font-size: 10px !important;
}

/* Pick-a-widget modal sections need very little vertical breathing room
   between them — admins scan; they're not reading. */
.app-confirm-card .widget-picker-grid + section,
.app-confirm-card section + section { margin-top: 6px; }

/* When the confirm-modal body hosts structured markup instead of plain
   prose (widget picker, tag picker, the new-page form), the inherited
   `white-space: pre-wrap` renders every source newline as a visible
   blank line. Bodies that opt-in via `has-structured` get a hard reset
   to normal whitespace handling for every descendant. */
.app-confirm-body.has-structured,
.app-confirm-body.has-structured * { white-space: normal; }

/* Widget editor config form — uniform input styling matching the rest of
   the dashboard. Replaces the browser-default look that made the row of
   labels + inputs feel raw and out of theme. */
.widget-editor-config {
  padding: 8px 12px;
  font-size: var(--fs-xs);
}
.widget-editor-config label {
  color: var(--n-400); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.6px;
  font-size: 10px;
}
/* All inputs inside the config block — text, number, select, textarea —
   share a single look. Caps width so a 2000-px viewport doesn't render a
   2000-px-wide text input. */
.widget-editor-config input[type="text"],
.widget-editor-config input[type="number"],
.widget-editor-config select,
.widget-editor-config textarea,
.widget-cfg-input {
  background: var(--n-900); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 6px 8px; font: inherit; font-size: var(--fs-xs);
  max-width: 460px; width: 100%;
}
.widget-editor-config input[type="number"] { max-width: 120px; }
.widget-editor-config select { max-width: 260px; }
.widget-editor-config textarea { min-height: 60px; max-width: 600px;
                                  resize: vertical; }
.widget-editor-config input:focus,
.widget-editor-config select:focus,
.widget-editor-config textarea:focus,
.widget-cfg-input:focus {
  outline: none; border-color: var(--cdi-gold);
}

/* Pill group inside the config (Time window 1/4/12/24h selector) */
.widget-editor-config .pill-group { display: flex; gap: 4px; flex-wrap: wrap; }

/* Inline hint under the Metric Chart controls — explains the window/agg combo */
.widget-cfg-hint { font-size: 11px; color: var(--cdi-gold); font-style: italic;
                   padding: 2px 0; }

/* Tag chips below the Pick tags button — visible at a glance, soft style */
.widget-cfg-tag-chips {
  margin-top: 6px; display: flex; flex-wrap: wrap; gap: 4px;
}
.widget-cfg-tag-chip {
  background: var(--n-850); border: 1px solid var(--n-700);
  border-radius: 4px; padding: 2px 6px;
  font-size: 10px; color: var(--n-300); font-family: inherit;
}

/* Light-theme overrides */
[data-theme="light"] .widget-editor-config input,
[data-theme="light"] .widget-editor-config select,
[data-theme="light"] .widget-editor-config textarea,
[data-theme="light"] .widget-cfg-input {
  background: #FFFFFF; color: var(--n-50); border-color: #E2E8F0;
}
[data-theme="light"] .widget-cfg-tag-chip {
  background: #F1F5F9; border-color: #E2E8F0; color: var(--n-50);
}

/* Editor v2.2 — widget cards laid out in a 4-col grid that mirrors the
   actual viewer/kiosk layout. The size pills set grid-column spans so the
   admin literally sees what they're about to ship. */
.widget-edit-grid {
  display: grid; gap: 10px;
  /* 12-col to mirror the kiosk/viewer grid; per-size spans are defined in
     the shared .widget-slot/.widget-edit-card size rules above. */
  grid-template-columns: repeat(12, 1fr);
}

/* Size selector — themed pill row */
.widget-edit-size-group { display: flex; gap: 2px; }
.widget-edit-size-pill {
  padding: 4px 8px !important;
  font-size: 10px !important;
  font-weight: 700;
  letter-spacing: 0.3px;
}

/* Line-break widget — full-width horizontal rule. Functions as a visual
   section divider AND a grid layout helper: grid-column 1/-1 forces a
   fresh row, and the gold gradient mirrors the brand accent so the
   section change is obvious to operators glancing at the kiosk. */
.widget-linebreak {
  grid-column: 1 / -1;
  background: transparent !important; border: 0 !important;
  padding: 0 !important; min-height: 0 !important;
  display: flex; align-items: center; height: 14px;
}
.widget-linebreak::before {
  content: ""; display: block; width: 100%; height: 2px;
  background: linear-gradient(to right,
    transparent, var(--cdi-gold) 10%, var(--cdi-gold) 90%, transparent);
  opacity: 0.6; border-radius: 1px;
}
/* Light hairline so admins can see the break in the editor */
.widget-edit-card.kind-line_break {
  background: transparent !important;
  border: 0; border-top: 1px dashed var(--n-700);
  padding: 6px 0; min-height: 0;
}
.widget-edit-card.kind-line_break .widget-edit-meta { opacity: 0.6; }
.widget-edit-card.kind-line_break .widget-edit-area { color: var(--cdi-gold); }

/* Preview mini-grid — fixed at 4 cols so size classes have the same
   semantics as the production widget-grid. */
.widget-edit-preview-grid {
  display: grid; gap: 8px;
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 1100px) {
  .widget-edit-preview-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Pip-grid widget — Overview-style "running / total" headline + numbered
   green/red dots. Reuses .benhill-strip / .benhill-pip so it's identical to
   the Overview page tiles. */
.widget-pips { display: flex; flex-direction: column; align-items: center;
               justify-content: center; gap: 4px; flex: 1; padding: 6px 0; }
.widget-pips .benhill-strip { margin-top: 8px; max-width: 100%; }

/* Header row above the widget list: title + "Preview page" button */
.stats-widgets-head { display: flex; align-items: center; justify-content: space-between;
                      gap: 12px; margin-bottom: 10px; }

/* Full-page preview overlay */
.stats-pagepreview-card {
  position: relative; z-index: 1; margin: 3vh auto; width: min(1280px, 94vw);
  max-height: 92vh; display: flex; flex-direction: column;
  background: var(--n-950, #07090B); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: 12px; overflow: hidden;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
}
.stats-pagepreview-card[data-theme="light"] { background: #EEF2F6; color: #0F172A; }
.stats-pagepreview-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 18px; border-bottom: 1px solid var(--n-800);
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--page-accent, #FFB300) 16%, transparent), transparent);
}
.stats-pagepreview-head h3 { margin: 2px 0 0; font-size: var(--fs-lg); }
.stats-pagepreview-eyebrow { font-size: 10px; font-weight: 700; letter-spacing: 1px;
  color: var(--page-accent, var(--cdi-gold)); text-transform: uppercase; }
.stats-pagepreview-body { padding: 16px 18px 22px; overflow-y: auto; }
.stats-pagepreview-card[data-theme="light"] .widget-slot {
  background: #FFFFFF; border-color: #E2E8F0; }
.stats-pagepreview-card .widget-slot { border-top: 2px solid
  color-mix(in srgb, var(--page-accent, #FFB300) 70%, transparent); }

/* When the page's kiosk theme is DARK but the admin's app is in LIGHT mode,
   the global `[data-theme="light"] …` rules (matching <html>) would leak in
   and render white cards + faint text inside the preview. Re-assert the dark
   look, scoped to the preview card, with enough specificity to win. */
.stats-pagepreview-card[data-theme="dark"] { background: var(--n-950); color: var(--n-100); }
.stats-pagepreview-card[data-theme="dark"] .widget-slot {
  background: var(--n-900); border-color: var(--n-700); }
.stats-pagepreview-card[data-theme="dark"] .widget-text h3 { color: var(--n-100); }
.stats-pagepreview-card[data-theme="dark"] .widget-title,
.stats-pagepreview-card[data-theme="dark"] .widget-gauge-title { color: var(--stats-title); }
.stats-pagepreview-card[data-theme="dark"] .widget-kpi-host .widget-kpi-value { color: var(--accent, #F5F7FA); }
.stats-pagepreview-card[data-theme="dark"] .widget-kpi-title { color: var(--stats-title); }
.stats-pagepreview-card[data-theme="dark"] .widget-kpi-host.widget-kpi-summary .widget-kpi-title { color: var(--accent, var(--n-400)); }
.stats-pagepreview-card[data-theme="dark"] .widget-kpi-sub,
.stats-pagepreview-card[data-theme="dark"] .widget-gauge-sub { color: var(--n-400); }
.stats-pagepreview-card[data-theme="dark"] .widget-product-tile { background: var(--n-850); border-color: var(--n-700); }
.stats-pagepreview-card[data-theme="dark"] .widget-product-num { color: var(--n-50); }
.stats-pagepreview-card[data-theme="dark"] .widget-stat-cell { background: var(--n-850); border-color: var(--n-700); }
.stats-pagepreview-card[data-theme="dark"] .widget-stat-state { color: var(--state-c, var(--n-50)); }
.stats-pagepreview-card[data-theme="dark"] .widget-stat-label { color: var(--n-300); }

/* Editor preview slot — full card width (the edit card already conveys the
   size via its own grid span; nesting a sized slot inside shrank Medium to
   a Small footprint). Fixed, generous height so charts/gauges render
   legibly. */
.widget-slot-preview { width: 100%; min-height: 240px; }

/* Accent picker in the editor options row */
.stats-accent-field { display: inline-flex; align-items: center; gap: 6px;
                      flex-wrap: wrap; }
.stats-accent-field input[type="color"] {
  width: 34px; height: 26px; padding: 0; border: 1px solid var(--n-700);
  border-radius: 6px; background: var(--n-900); cursor: pointer;
}
.stats-accent-swatch {
  width: 22px; height: 22px; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; box-shadow: 0 0 0 1px var(--n-700) inset;
  padding: 0;
}
.stats-accent-swatch.active { border-color: var(--n-50);
                              box-shadow: 0 0 0 2px var(--n-900),
                                          0 0 0 4px currentColor; }
.stats-accent-clear { padding: 2px 8px !important; font-size: 11px !important; }

/* ════════════════════════════════════════════════════════════════════════
   KIOSK GLAMOUR — premium, glanceable, room-display styling (v2.9.0603)
   A kiosk hangs on a wall and is read from 10 ft away, so: big type, strong
   contrast, accent-tinted chrome, subtle depth. Driven by --page-accent
   (admin-chosen, falls back to brand gold).
   ════════════════════════════════════════════════════════════════════════ */
:root { --page-accent: var(--cdi-gold, #FFB300); }

.kiosk-page-shell {
  min-height: 100vh; box-sizing: border-box; padding: 22px 26px 30px;
  background-color: #07090B;   /* fallback if gradient/color-mix unsupported */
  background:
    radial-gradient(1200px 500px at 12% -8%,
      color-mix(in srgb, var(--page-accent) 12%, transparent), transparent 60%),
    radial-gradient(900px 480px at 110% 0%,
      rgba(56,189,248,0.08), transparent 55%),
    linear-gradient(180deg, #0A0E12 0%, #07090B 60%);
  color: #E5E7EB;
}
[data-theme="light"] .kiosk-page-shell {
  background-color: #EEF2F6;
  background:
    radial-gradient(1200px 500px at 12% -8%,
      color-mix(in srgb, var(--page-accent) 16%, transparent), transparent 60%),
    linear-gradient(180deg, #F8FAFC 0%, #EEF2F6 100%);
  color: #0F172A;
}

/* Header: title + accent bar on the left, live clock + freshness on right */
.kiosk-page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; margin-bottom: 18px;
}
.kiosk-page-titlewrap { min-width: 0; }
.kiosk-title {
  font-size: clamp(26px, 3.2vw, 44px); font-weight: 800; margin: 0;
  letter-spacing: -0.02em; line-height: 1.05;
  color: #F8FAFC;
  text-shadow: 0 2px 18px rgba(0,0,0,0.45);
}
[data-theme="light"] .kiosk-title { color: #0F172A; text-shadow: none; }
.kiosk-page-accentbar {
  height: 5px; width: 96px; margin-top: 10px; border-radius: 3px;
  background: linear-gradient(90deg, var(--page-accent),
              color-mix(in srgb, var(--page-accent) 30%, transparent));
  box-shadow: 0 0 18px color-mix(in srgb, var(--page-accent) 55%, transparent);
}
.kiosk-page-status { text-align: right; flex: none; }
.kiosk-page-clock {
  font-size: clamp(18px, 2vw, 30px); font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em; color: #F1F5F9;
}
[data-theme="light"] .kiosk-page-clock { color: #0F172A; }
.kiosk-page-updated {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 4px;
  font-size: 12px; color: #8E99A6; text-transform: uppercase;
  letter-spacing: 0.6px; font-weight: 600;
}
.kiosk-live-dot {
  width: 9px; height: 9px; border-radius: 50%; background: #10B981;
  box-shadow: 0 0 0 0 rgba(16,185,129,0.6);
  animation: kioskPulse 2s infinite;
}
@keyframes kioskPulse {
  0%   { box-shadow: 0 0 0 0 rgba(16,185,129,0.55); }
  70%  { box-shadow: 0 0 0 9px rgba(16,185,129,0); }
  100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); }
}
/* Stale state — network down, data aging: dot goes amber, header dims */
.kiosk-stale .kiosk-live-dot { background: #F59E0B; animation: none; }
.kiosk-stale .kiosk-page-updated { color: #F59E0B; }

/* Premium widget slots on the kiosk: gentle gradient, accent top hairline,
   real depth. Bigger min-height so a wall display fills out. */
.kiosk-page-shell .widget-grid { gap: 16px; }
.kiosk-page-shell .widget-slot {
  background:
    linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0)) ,
    var(--n-850, #11161B);
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 14px; padding: 16px 18px; min-height: 150px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.04);
  overflow: hidden; position: relative;
}
.kiosk-page-shell .widget-slot::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--page-accent),
              color-mix(in srgb, var(--page-accent) 25%, transparent));
  opacity: 0.85;
}
.kiosk-page-shell .widget-slot.size-tall { min-height: 360px; }
.kiosk-page-shell .widget-linebreak { box-shadow: none; border: 0; }
.kiosk-page-shell .widget-linebreak::before { position: static; height: 2px; }
[data-theme="light"] .kiosk-page-shell .widget-slot {
  background: linear-gradient(180deg, #FFFFFF, #FBFDFF);
  border-color: #E2E8F0;
  box-shadow: 0 8px 24px rgba(15,23,42,0.08);
}

/* Bigger KPI typography on the kiosk so numbers carry across a room */
.kiosk-page-shell .widget-kpi-value { font-size: clamp(34px, 4.4vw, 60px); }
.kiosk-page-shell .widget-kpi-title { font-size: 13px; }
.kiosk-page-shell .widget-kpi-sub   { font-size: 13px; }

/* KPI accent — the per-metric (or page) accent paints the value + a glow */
.widget-kpi-host .widget-kpi-value {
  color: var(--accent, var(--n-50));
  text-shadow: 0 0 26px color-mix(in srgb, var(--accent, #34D399) 35%, transparent);
}
[data-theme="light"] .widget-kpi-host .widget-kpi-value {
  color: color-mix(in srgb, var(--accent, #0F172A) 78%, #0F172A);
  text-shadow: none;
}
/* KPI title is the uniform stats-title colour; the VALUE keeps its accent.
   Summary tiles (Plant Inventory) are the exception — accent-coloured title. */
.widget-kpi-host .widget-kpi-title { color: var(--stats-title); opacity: 1; }
.widget-kpi-host.widget-kpi-summary .widget-kpi-title { color: var(--accent, var(--n-500)); }

/* Gauge widget */
.widget-gauge-title { text-align: center; margin: 0 0 2px; color: var(--stats-title); }
.widget-gauge-host  { min-height: 180px; }
.kiosk-page-shell .widget-gauge-host { min-height: 220px; }
.widget-gauge-sub   { text-align: center; font-size: var(--fs-xs);
                      color: var(--n-500); margin-top: 2px; }

/* Status grid cells on the kiosk — slightly larger, soft glow on the state */
.kiosk-page-shell .widget-stat-grid {
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 8px;
}
.kiosk-page-shell .widget-stat-cell {
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  border-left: 3px solid var(--state-c, var(--n-500));
  border-radius: 10px; padding: 9px 11px;
}
.kiosk-page-shell .widget-stat-state { font-size: var(--fs-md); }
[data-theme="light"] .kiosk-page-shell .widget-stat-cell {
  background: #F8FAFC; border-color: #E2E8F0;
  border-left-color: var(--state-c, var(--n-500));
}

/* Page accent tint for the stats VIEW page (non-kiosk) — title rule only,
   keeps the in-app look subtle. */
.section[style*="--page-accent"] .widget-slot { border-top: 2px solid
  color-mix(in srgb, var(--page-accent) 70%, transparent); }

/* ────────────────────────────────────────────────────────────────────────
   Stats pages tile grid (admin /stats list)
   ──────────────────────────────────────────────────────────────────────── */
.stats-tile-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.stats-tile {
  background: var(--n-900); border: 1px solid var(--n-700);
  border-radius: 10px; padding: 14px; display: flex; flex-direction: column;
  gap: 8px; min-height: 130px;
  transition: border-color var(--t-fast), transform var(--t-fast);
}
.stats-tile:hover { border-color: var(--cdi-gold); transform: translateY(-1px); }
.stats-tile-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.stats-tile-name { font-weight: 700; color: var(--n-100); font-size: var(--fs-md);
                   line-height: 1.2; }
.stats-tile-count { font-size: 10px; color: var(--n-500); text-transform: uppercase;
                    letter-spacing: 0.7px; white-space: nowrap; }
.stats-tile-chips { display: flex; flex-wrap: wrap; gap: 4px; min-height: 28px; flex: 1; }
.stats-tile-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 6px; font-size: 16px;
  background: var(--n-850); border: 1px solid var(--n-700);
}
.stats-tile-chip-overflow {
  display: inline-flex; align-items: center; justify-content: center;
  height: 28px; padding: 0 8px; border-radius: 6px;
  background: var(--n-850); border: 1px solid var(--n-700);
  font-size: var(--fs-xs); color: var(--n-400); font-weight: 700;
}
.stats-tile-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; border-top: 1px solid var(--n-800); padding-top: 8px;
}
.stats-tile-byline { font-size: var(--fs-xs); color: var(--n-500); }
.stats-tile-actions { display: flex; gap: 4px; }
.btn-sm { padding: 4px 8px !important; font-size: var(--fs-xs) !important; }

[data-theme="light"] .stats-tile          { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .stats-tile-chip,
[data-theme="light"] .stats-tile-chip-overflow {
  background: #F1F5F9; border-color: #E2E8F0; }
[data-theme="light"] .stats-tile-foot     { border-top-color: #E2E8F0; }

/* ────────────────────────────────────────────────────────────────────────
   Kiosk Access Denied — animated, friendlier than a wall of red text
   ──────────────────────────────────────────────────────────────────────── */
.kiosk-denied {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at center, #1a0a0a 0%, #07090B 70%);
  font-family: "Inter", system-ui, sans-serif;
}
.kiosk-denied-card {
  text-align: center; padding: 40px; max-width: 560px;
}
.kiosk-denied-lock {
  display: inline-block; font-size: 92px; line-height: 1;
  filter: drop-shadow(0 0 24px rgba(248, 113, 113, 0.55));
  animation: kioskShake 1.6s ease-in-out infinite;
  margin-bottom: 14px;
}
.kiosk-denied-title {
  font-size: 38px; font-weight: 800; color: #F87171;
  letter-spacing: 2px; text-transform: uppercase;
  margin: 0 0 12px; text-shadow: 0 0 14px rgba(248,113,113,0.4);
  animation: kioskPulse 2s ease-in-out infinite;
}
.kiosk-denied-msg  { font-size: 16px; color: #E5E7EB; line-height: 1.5; margin: 0 0 8px; }
.kiosk-denied-hint { font-size: 12px; color: #8E99A6; margin: 16px 0 0;
                     letter-spacing: 0.4px; }
.kiosk-denied-bar  {
  margin-top: 22px; height: 6px; width: 100%;
  background: linear-gradient(90deg, transparent, #F87171, transparent);
  background-size: 200% 100%;
  animation: kioskScan 2.4s linear infinite;
  border-radius: 3px; opacity: 0.7;
}
@keyframes kioskShake {
  0%, 100% { transform: translateX(0) rotate(0); }
  20%      { transform: translateX(-4px) rotate(-3deg); }
  40%      { transform: translateX(4px)  rotate(3deg);  }
  60%      { transform: translateX(-3px) rotate(-2deg); }
  80%      { transform: translateX(3px)  rotate(2deg);  }
}
@keyframes kioskPulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.7; transform: scale(0.97); }
}
@keyframes kioskScan {
  0%   { background-position: -100% 0; }
  100% { background-position: 100% 0;  }
}

/* Stats page editor — small inline options strip (theme override) */
.stats-page-options {
  display: flex; gap: 14px; margin-bottom: 12px; flex-wrap: wrap;
}
.stats-page-options label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--fs-xs); color: var(--n-500);
  text-transform: uppercase; letter-spacing: 0.7px; font-weight: 700;
}
.stats-page-options select {
  background: var(--n-900); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 6px 8px; font: inherit; font-size: var(--fs-xs);
  min-width: 240px;
}
[data-theme="light"] .stats-page-options select {
  background: #FFFFFF; color: var(--n-50); border-color: #E2E8F0;
}

/* ────────────────────────────────────────────────────────────────────────
   Easter eggs — strictly visual sugar, all opt-in via the egg engine.
   Nothing here should affect the production look unless a class is
   explicitly added by easter-eggs.js.
   ──────────────────────────────────────────────────────────────────────── */

/* Toast notification when an egg is discovered */
.egg-toast {
  position: fixed; top: 80px; left: 50%; transform: translateX(-50%) translateY(-20px);
  background: var(--cdi-green); color: var(--n-50);
  padding: 12px 22px; border-radius: 28px;
  font-weight: 700; font-size: var(--fs-md);
  box-shadow: 0 12px 36px rgba(0,0,0,0.4);
  opacity: 0; transition: opacity 0.3s, transform 0.3s;
  z-index: 99999; pointer-events: none;
}
.egg-toast.egg-toast-in {
  opacity: 1; transform: translateX(-50%) translateY(0);
}

/* Confetti */
.egg-confetti-wrap {
  position: fixed; inset: 0; pointer-events: none; z-index: 99990;
  overflow: hidden;
}
.egg-confetti {
  position: absolute; top: -20px; width: 10px; height: 14px;
  border-radius: 2px;
  animation: egg-confetti-fall linear forwards;
}
@keyframes egg-confetti-fall {
  to { transform: translateY(110vh) rotate(720deg); }
}

/* Cow stampede */
.egg-cow-wrap {
  position: fixed; inset: 0; pointer-events: none; z-index: 99988;
  overflow: hidden;
}
.egg-cow {
  position: absolute; left: -80px;
  animation: egg-cow-walk 6.5s linear forwards;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3));
}
@keyframes egg-cow-walk {
  0%   { transform: translateX(0)      translateY(0); }
  25%  { transform: translateX(30vw)   translateY(-4px); }
  50%  { transform: translateX(60vw)   translateY(0); }
  75%  { transform: translateX(90vw)   translateY(-4px); }
  100% { transform: translateX(120vw)  translateY(0); }
}
.egg-cow-sign {
  position: absolute; left: 50%; bottom: 18%;
  transform: translateX(-50%) scale(0.6);
  background: var(--cdi-gold); color: var(--cdi-green);
  padding: 12px 28px; border-radius: 12px; font-size: 26px; font-weight: 900;
  box-shadow: 0 12px 32px rgba(0,0,0,0.35);
  animation: egg-sign-pop 6.5s ease-in-out forwards;
}
@keyframes egg-sign-pop {
  0%, 100% { opacity: 0; transform: translateX(-50%) scale(0.6); }
  15%, 85% { opacity: 1; transform: translateX(-50%) scale(1); }
}

/* Disco mode — color-cycle background + tile bounce */
@keyframes egg-disco-bg {
  0%   { background: #1B5E20; }
  20%  { background: #FFC107; }
  40%  { background: #60A5FA; }
  60%  { background: #F87171; }
  80%  { background: #A78BFA; }
  100% { background: #1B5E20; }
}
@keyframes egg-disco-bounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.egg-disco { animation: egg-disco-bg 1.6s linear infinite; }
.egg-disco .card,
.egg-disco .section-card,
.egg-disco .product-card,
.egg-disco .widget-slot {
  animation: egg-disco-bounce 0.6s ease-in-out infinite;
}

/* Matrix rain */
.egg-matrix {
  position: fixed; inset: 0; z-index: 99987; pointer-events: none;
  opacity: 1; transition: opacity 0.7s ease-out;
}
.egg-matrix.egg-matrix-fade { opacity: 0; }

/* Credits modal */
.egg-credits-root {
  position: fixed; inset: 0; z-index: 99995;
  display: flex; align-items: center; justify-content: center;
  animation: appConfirmIn 0.2s ease-out;
}
.egg-credits-backdrop {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.6); backdrop-filter: blur(4px);
}
.egg-credits-card {
  position: relative; max-width: 460px; padding: 28px 32px; text-align: center;
  background: var(--n-900); color: var(--n-50);
  border: 1px solid var(--cdi-gold); border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
}
.egg-credits-emoji {
  font-size: 64px; line-height: 1; margin-bottom: 10px;
  filter: drop-shadow(0 0 20px rgba(255, 193, 7, 0.6));
  animation: egg-credits-spin 6s linear infinite;
}
@keyframes egg-credits-spin {
  to { transform: rotate(360deg); }
}
.egg-credits-card h2 {
  margin: 0 0 12px; color: var(--cdi-gold); font-size: 22px;
}
.egg-credits-card p { margin: 6px 0; color: var(--n-200); font-size: 14px; }
.egg-credits-tag {
  margin-top: 14px !important; font-style: italic; color: var(--n-400) !important;
}
[data-theme="light"] .egg-credits-card {
  background: #FFFFFF; color: var(--n-50);
}
[data-theme="light"] .egg-credits-card p { color: var(--n-100); }

/* Plant pulse */
@keyframes egg-pulse {
  0%, 100% { transform: scale(1);    color: inherit; }
  50%      { transform: scale(1.18); color: var(--cdi-gold);
             text-shadow: 0 0 20px rgba(255, 193, 7, 0.8); }
}
.egg-pulse {
  animation: egg-pulse 1.6s ease-in-out 2;
  display: inline-block;
}

/* Secret-egg icon revealed after 10 copyright clicks */
.about-secret-egg {
  display: none; margin-left: 12px;
  font-size: 22px; cursor: pointer; vertical-align: middle;
  text-decoration: none; opacity: 0; transition: opacity 0.6s ease;
}
.about-secret-egg.egg-secret-in {
  opacity: 1; animation: egg-secret-bob 1.4s ease-in-out infinite;
}
@keyframes egg-secret-bob {
  0%, 100% { transform: translateY(0)   rotate(-4deg); }
  50%      { transform: translateY(-3px) rotate(4deg); }
}

/* Easter Egg page tile grid */
.eggs-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.egg-card {
  background: var(--n-900); border: 1px solid var(--n-700);
  border-left: 4px solid var(--n-700);
  border-radius: 10px; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px;
}
.egg-card.discovered { border-left-color: var(--cdi-gold); }
.egg-card-head { display: flex; align-items: baseline; justify-content: space-between; }
.egg-card-name { font-weight: 700; color: var(--n-100); font-size: var(--fs-md); }
.egg-card-state {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.7px;
  font-weight: 700;
}
.egg-card-state.discovered { color: var(--cdi-gold); }
.egg-card-state.hidden     { color: var(--n-500); }
.egg-card-hint    { font-size: var(--fs-xs); color: var(--n-300); line-height: 1.4; }
.egg-card-trigger { font-size: 10px; color: var(--n-500);
                    font-family: inherit; }
.egg-card-actions { display: flex; gap: 6px; margin-top: 4px; }
[data-theme="light"] .egg-card { background: #FFFFFF; border-color: #E2E8F0; }

/* Matrix-rain countdown overlay */
.egg-matrix-timer {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  font-family: "JetBrains Mono", monospace;
  font-size: 120px; font-weight: 800;
  color: #4ADE80; opacity: 0.85;
  text-shadow: 0 0 20px rgba(74, 222, 128, 0.6);
  pointer-events: none; z-index: 99988;
  transition: opacity 0.7s ease-out;
  font-variant-numeric: tabular-nums;
}
.egg-matrix-timer.egg-matrix-fade { opacity: 0; }

/* Credits modal — team columns + late-hours props */
.egg-credits-team {
  display: flex; justify-content: center; gap: 60px;
  margin: 16px 0 8px;
}
.egg-credits-team-col { text-align: center; }
.egg-credits-team-label {
  font-size: 11px; font-weight: 800; color: var(--cdi-gold);
  text-transform: uppercase; letter-spacing: 2px;
  margin-bottom: 2px;
}
.egg-credits-team-name {
  font-size: 11px; color: var(--n-400); font-style: italic;
}
.egg-credits-pit {
  display: flex; justify-content: center; gap: 18px;
  font-size: 38px; line-height: 1; margin: 12px 0 4px;
  filter: drop-shadow(0 0 14px rgba(255, 152, 0, 0.45));
}
.egg-credits-pit-icon {
  display: inline-block;
  animation: egg-credits-flicker 2.4s ease-in-out infinite;
}
.egg-credits-pit-icon:nth-child(2) { animation-delay: 0.6s; }
@keyframes egg-credits-flicker {
  0%, 100% { transform: translateY(0) scale(1);   opacity: 1; }
  50%      { transform: translateY(-3px) scale(1.06); opacity: 0.92; }
}
[data-theme="light"] .egg-credits-team-name { color: var(--n-100); }

/* ────────────────────────────────────────────────────────────────────────
   About page — version banner, support cards, tech-stack tile grid.
   Layout inspired by polished enterprise app About pages.
   ──────────────────────────────────────────────────────────────────────── */
.about-page { display: flex; flex-direction: column; gap: 16px; max-width: 1280px; }

/* Banner */
.about-hero {
  display: flex; gap: 18px; align-items: center;
  background: linear-gradient(135deg, #0B3D14 0%, #1B5E20 55%, #2E7D32 100%);
  /* Literal white — `var(--n-50)` becomes near-black in light theme
     which is invisible on the dark-green banner. Hard-pin to white
     since the banner gradient is dark regardless of OS theme. */
  color: #FFFFFF; border-radius: 14px; padding: 22px 28px;
  position: relative; overflow: hidden;
}
.about-hero::after {
  content: ""; position: absolute; right: -60px; top: -60px;
  width: 240px; height: 240px; border-radius: 50%;
  background: radial-gradient(circle at center,
              rgba(255, 193, 7, 0.18), transparent 70%);
  pointer-events: none;
}
.about-hero-icon {
  flex-shrink: 0; width: 72px; height: 72px; border-radius: 14px;
  background: rgba(255, 255, 255, 0.12); padding: 10px;
  display: flex; align-items: center; justify-content: center;
}
.about-hero-icon img { max-width: 100%; max-height: 100%; }
.about-hero-body { flex: 1; min-width: 0; position: relative; z-index: 1; }
.about-hero-body h2 {
  font-size: 26px; font-weight: 800; margin: 0 0 4px;
  color: #FFFFFF; letter-spacing: -0.01em;
}
.about-hero-sub {
  margin: 0 0 14px; font-size: var(--fs-sm); color: rgba(255,255,255,0.85);
  line-height: 1.5;
}
.about-hero-pills { display: flex; gap: 8px; flex-wrap: wrap; }
.about-pill {
  background: rgba(0, 0, 0, 0.28); border: 1px solid rgba(255,255,255,0.18);
  border-radius: 8px; padding: 6px 12px;
}
.about-pill-label {
  font-size: 10px; font-weight: 700; letter-spacing: 1.4px;
  color: rgba(255, 255, 255, 0.65); text-transform: uppercase;
}
.about-pill-value {
  /* Hard-pinned white — banner is always dark-green; theme tokens swap
     this colour with the page background in light mode and the value
     becomes unreadable on green. */
  font-size: var(--fs-sm); font-weight: 700; color: #FFFFFF;
  font-variant-numeric: tabular-nums;
}

/* Two-up row: IT Support card + Release/Roadmap stack */
.about-cols {
  display: grid; gap: 16px;
  grid-template-columns: 1fr 1fr;
}
@media (max-width: 900px) {
  .about-cols { grid-template-columns: 1fr; }
}
.about-col-stack { display: flex; flex-direction: column; gap: 12px; }

/* Cards (matches the .card baseline but with tighter padding + a label) */
.about-card {
  background: var(--n-900); border: 1px solid var(--n-700);
  border-radius: 12px; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 10px;
}
.about-card-label {
  font-size: 10px; color: var(--n-500); font-weight: 700;
  letter-spacing: 1.2px; text-transform: uppercase; margin-bottom: 4px;
}
.about-link {
  display: flex; align-items: center; gap: 12px;
  background: var(--n-850); border: 1px solid var(--n-700);
  border-radius: 8px; padding: 10px 14px;
  text-decoration: none; color: inherit;
  transition: border-color var(--t-fast), transform var(--t-fast);
}
.about-link:hover { border-color: var(--cdi-gold);
                    transform: translateY(-1px); text-decoration: none; }
.about-link svg, .about-link .icon { color: var(--info); flex-shrink: 0; }
.about-link-name { font-weight: 700; color: var(--n-100); font-size: var(--fs-sm); }
.about-link-sub  { font-size: var(--fs-xs); color: var(--n-500); }

.about-card-link {
  flex-direction: row; align-items: center; gap: 14px;
  text-decoration: none; color: inherit;
  transition: border-color var(--t-fast), transform var(--t-fast);
}
.about-card-link:hover { border-color: var(--cdi-gold);
                          transform: translateY(-1px); text-decoration: none; }
.about-card-icon {
  width: 36px; height: 36px; border-radius: 8px;
  background: rgba(96, 165, 250, 0.12); color: var(--info);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.about-card-arrow {
  margin-left: auto; color: var(--n-500); font-size: 22px;
  transition: transform var(--t-fast);
}
.about-card-link:hover .about-card-arrow { transform: translateX(4px); color: var(--cdi-gold); }

/* Technology stack */
.about-stack-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.about-stack-tile {
  background: var(--n-850); border: 1px solid var(--n-700);
  border-radius: 10px; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 4px;
}
.about-stack-icon {
  width: 30px; height: 30px; border-radius: 6px;
  background: rgba(96, 165, 250, 0.12); color: var(--info);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; margin-bottom: 4px;
}
.about-stack-cat {
  font-size: 10px; color: var(--n-500); font-weight: 700;
  letter-spacing: 1.2px; text-transform: uppercase;
}
.about-stack-name {
  font-weight: 700; color: var(--n-100); font-size: var(--fs-sm);
  line-height: 1.3;
}
.about-stack-desc {
  margin: 4px 0 0; font-size: var(--fs-xs); color: var(--n-300);
  line-height: 1.5;
}

/* Copyright footer with secret-egg trigger */
.about-foot {
  text-align: center; padding: 20px 0; color: var(--n-500);
  font-size: var(--fs-xs);
}

/* Light-theme overrides */
[data-theme="light"] .about-card        { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .about-link        { background: #F8FAFC; border-color: #E2E8F0; }
[data-theme="light"] .about-stack-tile  { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .about-stack-name  { color: var(--n-50); }
[data-theme="light"] .about-link-name   { color: var(--n-50); }
[data-theme="light"] .about-stack-desc  { color: var(--n-100); }

/* About → two-column row when only Release Notes + Roadmap remain */
.about-cols-2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 900px) { .about-cols-2 { grid-template-columns: 1fr; } }

/* ────────────────────────────────────────────────────────────────────────
   Roadmap page — phase cards with shipped / in-progress / planned counts
   ──────────────────────────────────────────────────────────────────────── */
.rm-summary {
  font-size: var(--fs-sm); color: var(--n-300); margin: 0 0 12px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.rm-banner {
  background: rgba(255, 193, 7, 0.10);
  border: 1px solid rgba(255, 193, 7, 0.35);
  border-left: 3px solid var(--cdi-gold);
  border-radius: 10px; padding: 14px 18px;
  display: flex; gap: 12px; font-size: var(--fs-sm); color: var(--n-200);
  line-height: 1.5;
}
.rm-banner-icon { font-size: 22px; line-height: 1; flex-shrink: 0; }
.rm-phases {
  display: grid; gap: 14px;
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 1100px) { .rm-phases { grid-template-columns: 1fr; } }

.rm-phase {
  background: var(--n-900); border: 1px solid var(--n-700);
  border-top: 4px solid var(--n-600);
  border-radius: 12px; padding: 16px 18px;
  display: flex; flex-direction: column; gap: 10px;
}
.rm-phase-1 { border-top-color: var(--info);   }
.rm-phase-2 { border-top-color: #A78BFA;       }
.rm-phase-3 { border-top-color: var(--cdi-green-light); }
.rm-phase header h2 {
  font-size: 22px; margin: 4px 0 2px; color: var(--n-100); font-weight: 800;
}
.rm-phase-eyebrow {
  font-size: 10px; color: var(--info); font-weight: 800;
  letter-spacing: 1.4px; text-transform: uppercase;
}
.rm-phase-2 .rm-phase-eyebrow { color: #A78BFA; }
.rm-phase-3 .rm-phase-eyebrow { color: var(--cdi-green-light); }
.rm-phase-when {
  font-size: var(--fs-xs); color: var(--n-400); margin: 0;
}
.rm-phase-counts { display: flex; gap: 6px; flex-wrap: wrap; }

.rm-pill {
  display: inline-flex; align-items: center;
  padding: 3px 8px; border-radius: 12px;
  font-size: 11px; font-weight: 700;
  border: 1px solid transparent;
}
.rm-pill-shipped    { background: rgba(74, 222, 128, 0.15);
                      border-color: rgba(74, 222, 128, 0.4);
                      color: #A3E9B7; }
.rm-pill-inprogress { background: rgba(167, 139, 250, 0.18);
                      border-color: rgba(167, 139, 250, 0.4);
                      color: #C8B6FF; }
.rm-pill-planned    { background: rgba(96, 165, 250, 0.14);
                      border-color: rgba(96, 165, 250, 0.4);
                      color: #93C5FD; }

.rm-feature-list { list-style: none; padding: 0; margin: 4px 0 0;
                   display: flex; flex-direction: column; gap: 6px; }
.rm-feature-list li {
  font-size: var(--fs-xs); line-height: 1.5; color: var(--n-300);
  padding-left: 22px; position: relative;
}
.rm-feature-list li::before {
  position: absolute; left: 0; top: 0; font-size: 12px; line-height: 1.4;
}
.rm-feature-list li.rm-shipped::before    { content: "★"; color: #A3E9B7; }
.rm-feature-list li.rm-inprogress::before { content: "⚙"; color: #C8B6FF; }
.rm-feature-list li.rm-planned::before    { content: "○"; color: #93C5FD; }

/* ────────────────────────────────────────────────────────────────────────
   Release Notes page
   ──────────────────────────────────────────────────────────────────────── */
.rn-summary {
  font-size: var(--fs-sm); color: var(--n-300); margin: 0 0 14px;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
/* Release-notes summary pills + per-version badges (v2.9.0524.5 —
   bumped saturation: previous pale chips disappeared against the dark
   card. Now reads with proper colour weight in both themes. */
.rn-pill {
  display: inline-block; padding: 4px 11px; border-radius: 12px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  border: 1px solid transparent;
}
.rn-pill-feat { background: #0C8442; border-color: #0C8442; color: #FFFFFF; }
.rn-pill-fix  { background: #006BFF; border-color: #006BFF; color: #FFFFFF; }
.rn-pill-sec  { background: #CC0000; border-color: #CC0000; color: #FFFFFF; }
[data-theme="light"] .rn-pill-feat,
[data-theme="light"] .rn-pill-fix,
[data-theme="light"] .rn-pill-sec { color: #FFFFFF; }

/* Top-of-page disclaimer that build timestamps are UTC (v2.9.0524.6 —
   added after admins noticed the dates drift vs. PST). v2.9.0524.7 —
   light-mode contrast bumped: previous `var(--n-700)` text colour
   resolved to the border tint #B8C2CF in light theme (palette is
   inverted — see ops runbook on theme palette), leaving the note nearly invisible
   on the pale-yellow background. */
.rn-note {
  margin: 8px 0 16px;
  padding: 10px 14px;
  font-size: var(--fs-sm);
  color: var(--n-300);
  background: rgba(255, 193, 7, 0.06);
  border: 1px solid rgba(255, 193, 7, 0.30);
  border-left: 3px solid var(--cdi-gold);
  border-radius: 6px;
  line-height: 1.5;
}
[data-theme="light"] .rn-note {
  color: #3A2A05;            /* near-black warm brown — high contrast on #FFF3CD */
  background: #FFF3CD;
  border-color: #E0A800;
  border-left-color: #8A5A00;
}
[data-theme="light"] .rn-note strong { color: #1F1300; }

/* Subtle italic interjections that live between release-note cards.
   Reads as a developer comment that "leaked" into the user-facing page —
   intentional easter-egg vibe. Muted enough to skip while scanning but
   visible to anyone reading carefully. Wrapped in // // to feel like a
   code comment. */
.rn-aside {
  margin: 6px auto;
  padding: 4px 14px;
  max-width: 70%;
  font-size: 11px;
  font-style: italic;
  text-align: center;
  color: var(--n-500);
  opacity: 0.55;
  letter-spacing: 0.01em;
}
.rn-aside::before { content: "// "; opacity: 0.6; }
.rn-aside::after  { content: " //"; opacity: 0.6; }
[data-theme="light"] .rn-aside { color: var(--n-500); opacity: 0.6; }

.rn-list { display: flex; flex-direction: column; gap: 12px; }
/* Era headers — separate the release notes into the per-session arcs that
   built this dashboard (v1 Grafana → v2 HTML rewrite → v2.1 UAT → etc.).
   Larger than a card head, smaller than a page title, with a thin gold
   underline so it reads as a real section divider. */
.rn-era {
  font-size: var(--fs-lg); color: var(--n-100); font-weight: 700;
  letter-spacing: -0.01em; margin: 24px 0 4px;
  padding-bottom: 6px; border-bottom: 1px solid rgba(255, 193, 7, 0.35);
}
[data-theme="light"] .rn-era { color: var(--n-50);
  border-bottom-color: rgba(255, 152, 0, 0.4); }
/* Era subtitle — short paragraph beneath each minor-version heading
   explaining what drove the bump (v2.9.0524.6). */
.rn-era-sub {
  margin: 0 0 14px;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--n-400);
  max-width: 80ch;
}
[data-theme="light"] .rn-era-sub { color: var(--n-600); }
.rn-card {
  background: var(--n-900); border: 1px solid var(--n-700);
  border-left: 3px solid var(--n-600);
  border-radius: 10px; padding: 16px 20px;
}
.rn-card.rn-current { border-left-color: var(--cdi-gold);
                      box-shadow: 0 0 0 1px rgba(255, 193, 7, 0.15); }
.rn-card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; margin-bottom: 8px;
}
.rn-version {
  font-size: 16px; font-weight: 800; color: var(--n-100);
  font-family: inherit; letter-spacing: -0.02em;
}
.rn-date { font-size: var(--fs-xs); color: var(--n-500); }
/* Per-version badge — v2.9.0524.7 softened: previous 800-weight all-caps
   with 0.7px letter-spacing read as harsh / shouty against the muted
   card type. Now matches the calmer body weight + Title Case casing
   used elsewhere on the page. */
.rn-badge {
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.01em; text-transform: none;
  padding: 4px 10px; border-radius: 12px;
  border: 1px solid transparent; white-space: nowrap;
}
.rn-badge-feat { background: #0C8442; border-color: #0C8442; color: #FFFFFF; }
.rn-badge-fix  { background: #006BFF; border-color: #006BFF; color: #FFFFFF; }
.rn-badge-sec  { background: #CC0000; border-color: #CC0000; color: #FFFFFF; }
[data-theme="light"] .rn-badge-feat,
[data-theme="light"] .rn-badge-fix,
[data-theme="light"] .rn-badge-sec { color: #FFFFFF; }
.rn-card ul { margin: 0; padding-left: 22px; }
.rn-card li { font-size: var(--fs-sm); line-height: 1.55; color: var(--n-300);
              margin-bottom: 4px; }
.rn-card li:last-child { margin-bottom: 0; }
/* Release-notes inline code: blend with surrounding body text instead of
   rendering as gold-on-dark chips. Operators reading the release notes
   want to scan the narrative, not pick out implementation tokens. */
.rn-card code {
  background: transparent;
  padding: 0;
  border: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
}

/* Light-theme tweaks */
[data-theme="light"] .rm-phase,
[data-theme="light"] .rn-card { background: #FFFFFF; border-color: #E2E8F0; }
[data-theme="light"] .rm-phase header h2,
[data-theme="light"] .rn-version { color: var(--n-50); }
[data-theme="light"] .rm-feature-list li,
[data-theme="light"] .rn-card li { color: var(--n-100); }
[data-theme="light"] .rn-card code { background: transparent; color: inherit; }
[data-theme="light"] .rm-banner {
  background: rgba(255, 193, 7, 0.18);
  border-color: rgba(255, 152, 0, 0.4);
  color: var(--n-50);
}

/* Combined Avapac tile (Overview Powder Lines row).
   Two cells side-by-side inside one section-card so both Avapac values
   show independently but the tile is the same size as P6/P7/P8 next to it. */
.avapac-pair {
  display: flex; gap: 8px; flex: 1; align-items: center;
  justify-content: center; padding: 4px 0;
}
.avapac-cell {
  flex: 1; min-width: 0; text-align: center;
  border: 1px solid var(--n-700); border-radius: 6px;
  padding: 6px 4px;
  display: flex; flex-direction: column; gap: 2px;
}
.avapac-cell-label {
  font-size: 9px; color: var(--n-500);
  text-transform: uppercase; letter-spacing: 0.7px; font-weight: 700;
}
.avapac-cell-value {
  font-size: var(--fs-2xl); font-weight: 700; line-height: 1;
  color: var(--n-50); font-variant-numeric: tabular-nums;
}
[data-theme="light"] .avapac-cell        { border-color: #E2E8F0; background: #F8FAFC; }
[data-theme="light"] .avapac-cell-value  { color: var(--n-50); }

/* ── Overview · Powder Lines dedicated grid (v2.9.0531.17) ─────────────────
   5 columns × 2 rows. Each P6/P7/P8 line tile is half-height (row 1) with its
   own Σ Separator sum stacked directly under it (row 2). Avapacs span both
   rows (tall, detailed). PPH (row 1) + Dryer Feed (row 2) fill the last
   column. Explicit grid-area placement keeps each line paired with its sum
   regardless of DOM order. */
.powder-overview-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: auto auto;
  gap: 10px;
  /* Row 1: Σ Separator sums; Row 2: EVP tiles. The per-line equipment-running
     pip tiles (areas p6/p7/p8) were removed at the Visalia Site Manager's
     request (v2.9.0612.2), so the Sep + EVP rows moved up to fill the section. */
  grid-template-areas:
    "p6s  p7s  p8s  avp  pph"
    "p6e  p7e  p8e  avp  dry";
}
.po-sep-1   { grid-area: p6s; }
.po-sep-2   { grid-area: p7s; }
.po-sep-3   { grid-area: p8s; }
.po-avapac  { grid-area: avp; }
.po-pph     { grid-area: pph; }
.po-dryer   { grid-area: dry; }

/* Half-height line tile: compact padding, smaller headline, pip strip kept.
   Content is vertically centred (header pinned top); the count + "equipment
   running" line + pip strip sit as a centred group with a gap above the
   pips so the dots are clearly separated from the text. v2.9.0531.18. */
.powder-overview-grid .po-line {
  padding: 8px 12px;
  display: flex; flex-direction: column;
}
.powder-overview-grid .po-line .po-line-body {
  flex: 1; display: flex; flex-direction: column;
  justify-content: center; align-items: center;
}
.po-line-big {
  font-size: var(--fs-2xl); font-weight: 700; line-height: 1.0;
  color: var(--n-50); text-align: center; font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em; margin: 2px 0;
}
.powder-overview-grid .po-line .section-sub { text-align: center; }
.powder-overview-grid .po-line .benhill-strip { margin-top: 10px; }
.powder-overview-grid .po-sep { min-height: 0; }

/* EVP row (v2.9.0602.1) — one compact tile per line, column-aligned under
   its P6/P7/P8 separator sum. Status word centred, then a small two-row
   key:value block (Run rate / In Status). Border-left colour comes from the
   powder.status cluster (eq-on / eq-off / eq-unknown), matching the line
   pip colours. */
.powder-overview-grid .po-evp { min-height: 0; padding: 8px 12px; }
.po-evp-status {
  font-size: var(--fs-lg); font-weight: 800; text-align: center;
  letter-spacing: 0.2px; margin: 2px 0 4px;
  color: var(--n-100);
}
/* Status text colour by state (v2.9.0602.3) — matches the Powder page's
   .eq-status treatment: red = off/stopped, green = running/product, gold =
   CIP, grey = unknown. The eq-on/off/cip/unknown class comes from
   colorFor(); the --eq-accent set by styleFor() lets an admin's custom
   threshold hex override the class fallback. */
.po-evp.eq-on      .po-evp-status { color: var(--eq-accent, var(--ok)); }
.po-evp.eq-off     .po-evp-status { color: var(--eq-accent, var(--bad)); }
.po-evp.eq-cip     .po-evp-status { color: var(--eq-accent, var(--warn)); }
.po-evp.eq-unknown .po-evp-status { color: var(--eq-accent, var(--n-500)); }
.po-evp-rows { display: flex; flex-direction: column; gap: 2px; }
.po-evp-line {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
}
.po-evp-k {
  font-size: 9px; color: var(--n-500); text-transform: uppercase;
  letter-spacing: 0.5px; font-weight: 700;
}
.po-evp-v {
  font-size: var(--fs-sm); font-weight: 700; color: var(--n-50);
  font-variant-numeric: tabular-nums;
}
[data-theme="light"] .po-evp-v { color: var(--n-50); }
/* Σ Separator + PPH compact tiles: centre the big number vertically. */
.powder-overview-grid .po-sep,
.powder-overview-grid .po-pph { justify-content: center; }
.powder-overview-grid .po-sep .section-big,
.powder-overview-grid .po-pph .section-big { flex: 1; }

/* Avapacs — tall card, two columns side by side (Avapac 1 | Avapac 2). */
.po-avapac { padding: 10px 12px; }
.po-avapac-pair { display: flex; flex-direction: row; gap: 8px; flex: 1; }
.po-avapac-cell {
  flex: 1; min-width: 0;
  border: 1px solid var(--n-700); border-radius: 6px;
  padding: 8px 10px;
  display: flex; flex-direction: column; gap: 6px;
  justify-content: center;
}
/* Machine name = simple heading above the stats — bold but unobtrusive,
   no highlight, so it blends with the rest of the Overview cards.
   v2.9.0602.1 (gold banner removed). */
.po-avapac-name {
  font-size: var(--fs-sm); font-weight: 700; letter-spacing: 0.3px;
  color: var(--n-100); text-align: center;
  padding-bottom: 4px; border-bottom: 1px solid var(--n-800);
}
.po-avapac-rows {
  display: flex; flex-direction: column; gap: 4px;
  flex: 1; justify-content: center;
}
/* Each line: short key (1H:/4H:/PPH) + value, no separate label row. */
.po-avapac-line {
  display: flex; align-items: baseline; gap: 6px; justify-content: center;
}
.po-avapac-k {
  font-size: var(--fs-md); font-weight: 700; color: var(--n-500);
  font-variant-numeric: tabular-nums;
}
.po-avapac-v {
  font-size: var(--fs-md); font-weight: 700; color: var(--n-50);
  font-variant-numeric: tabular-nums;
}
/* "Soon" stays the SAME size as a real value so the layout previews
   accurately — just italic so it reads as a placeholder. */
.po-avapac-v.po-avapac-soon {
  color: var(--n-400); font-style: italic;
}
[data-theme="light"] .po-avapac-cell { border-color: #E2E8F0; background: #F8FAFC; }
[data-theme="light"] .po-avapac-name { color: var(--n-100); border-bottom-color: #E2E8F0; }
[data-theme="light"] .po-avapac-v    { color: var(--n-50); }

/* Responsive: drop to 3 cols (Σ Separator row over EVP row; Avapacs/PPH/Dryer
   reflow), then 1 col on phones. (Equipment-running tiles removed v2.9.0612.2.) */
@media (max-width: 1100px) {
  .powder-overview-grid {
    grid-template-columns: repeat(3, 1fr);
    grid-template-areas:
      "p6s  p7s  p8s"
      "p6e  p7e  p8e"
      "avp  pph  dry";
  }
}
@media (max-width: 640px) {
  .powder-overview-grid {
    grid-template-columns: 1fr;
    grid-template-areas:
      "p6s" "p6e" "p7s" "p7e" "p8s" "p8e" "avp" "pph" "dry";
  }
}

/* ── Service accounts: cleaned-up table + API-usage panel (v2.9.0530.1) ──── */
.sa-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  margin-bottom: 18px;
}
.sa-table { border-collapse: collapse; width: 100%; font-size: var(--fs-sm); }
.sa-table thead th {
  background: var(--n-850); color: var(--n-400);
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
  font-weight: 700; text-align: left; padding: 9px 12px;
  white-space: nowrap; border-bottom: 1px solid var(--n-700);
}
.sa-table tbody td {
  padding: 10px 12px; border-bottom: 1px solid var(--n-800);
  vertical-align: middle; color: var(--n-200, var(--n-300));
}
.sa-table tbody tr:last-child td { border-bottom: 0; }
.sa-table tbody tr:hover { background: var(--n-850); }
.sa-num    { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sa-center { text-align: center; }
.sa-name { font-weight: 700; color: var(--n-100); }
.sa-desc { font-size: var(--fs-xs); color: var(--n-500); margin-top: 1px; }
.sa-key  { font-size: var(--fs-xs); color: var(--n-400); letter-spacing: 0.2px; word-break: break-all; }
.sa-ip   { font-size: var(--fs-xs); color: var(--n-300); font-variant-numeric: tabular-nums; }
.sa-muted { color: var(--n-500); }
.sa-badge {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.3px;
}
.sa-badge-on  { background: rgba(76,175,80,0.18);  color: var(--cdi-green-light, #2e7d32); }
.sa-badge-off { background: rgba(204,0,0,0.16);     color: var(--bad); }
.sa-actions-col { width: 1%; white-space: nowrap; }
.sa-actions { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: nowrap; }
.sa-table .btn-sm { padding: 4px 10px; font-size: var(--fs-xs); }
.sa-del { color: var(--bad); border-color: rgba(204,0,0,0.35); }
.sa-del:hover { border-color: var(--bad); }

.sa-usage {
  border: 1px solid var(--n-700); border-radius: var(--r-md);
  padding: 16px 18px; background: var(--n-900);
}
.sa-usage-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.sa-usage-controls { display: flex; gap: 8px; align-items: center; }
.sa-usage-range {
  background: var(--n-950); color: var(--n-100);
  border: 1px solid var(--n-700); border-radius: var(--r-sm);
  padding: 5px 8px; font: inherit; font-size: var(--fs-sm);
}
.sa-usage-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 14px; }
.sa-stat { background: var(--n-850); border: 1px solid var(--n-700); border-radius: var(--r-sm); padding: 10px 12px; text-align: center; }
.sa-stat-num { font-size: var(--fs-xl); font-weight: 700; color: var(--n-50); font-variant-numeric: tabular-nums; line-height: 1.1; }
.sa-stat-lbl { font-size: var(--fs-xs); color: var(--n-500); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; }
.sa-usage-chart { width: 100%; height: 200px; margin-bottom: 14px; }
.sa-usage-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.sa-usage-card { border: 1px solid var(--n-700); border-radius: var(--r-sm); padding: 10px 12px; background: var(--n-850); }
.sa-usage-card-h { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.5px; color: var(--n-400); font-weight: 700; margin-bottom: 8px; }
.sa-usage-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 3px 0; font-size: var(--fs-sm); }
.sa-usage-count { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--n-100); }
.sa-recent { font-size: var(--fs-xs); }

@media (max-width: 700px) { .sa-usage-stats { grid-template-columns: repeat(2, 1fr); } }

[data-theme="light"] .sa-table thead th { background: var(--n-850); color: var(--n-400); }
[data-theme="light"] .sa-table tbody tr:hover { background: var(--n-850); }
[data-theme="light"] .sa-usage,
[data-theme="light"] .sa-usage-range { background: #ffffff; }
[data-theme="light"] .sa-stat,
[data-theme="light"] .sa-usage-card { background: var(--n-900); }

/* ── Service accounts redesign: overview/detail/modal (v2.9.0530.3) ───────── */
.sa-head-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.sa-head-title { display: flex; align-items: center; gap: 10px; }
.sa-head-title h3 { margin: 0; }
.sa-error { color: #CC0000; margin-top: 12px; }

/* clickable overview rows */
.sa-table-click tbody tr.sa-row { cursor: pointer; transition: background 0.08s; }
.sa-table-click tbody tr.sa-row:hover { background: var(--n-850); }
.sa-table-click tbody tr.sa-row:focus-visible { outline: 2px solid var(--cdi-green, #2e7d32); outline-offset: -2px; }
.sa-row-arrow { color: var(--n-500); font-size: 18px; font-weight: 700; }

/* pagination */
.sa-pager { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 12px 10px; }
.sa-pager-info { font-size: var(--fs-xs); color: var(--n-400); font-variant-numeric: tabular-nums; }

/* detail view */
.sa-detail-bar { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.sa-detail-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.sa-detail-title-row { display: flex; align-items: center; gap: 10px; }
.sa-detail-title { margin: 0; }
.sa-detail-desc { color: var(--n-400); margin: 4px 0 14px; }
.sa-detail-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 6px; }
.sa-meta { border: 1px solid var(--n-700); border-radius: var(--r-sm); padding: 8px 11px; background: var(--n-850); }
.sa-meta-lbl { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.5px; color: var(--n-500); margin-bottom: 3px; }
.sa-scope-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.sa-scope-chip { font-size: 10px; padding: 1px 7px; border-radius: 9px; background: var(--n-800); color: var(--n-300); border: 1px solid var(--n-700); white-space: nowrap; }
.sa-usage-lbl { font-size: var(--fs-xs); color: var(--n-400); text-transform: uppercase; letter-spacing: 0.5px; }

/* create/edit modal */
.sa-modal-root { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: flex-start; justify-content: center; padding: 40px 16px; overflow-y: auto; }
.sa-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.55); }
.sa-modal-card { position: relative; background: var(--n-900); border: 1px solid var(--n-700); border-radius: var(--r-md); width: min(780px, 100%); max-height: calc(100vh - 80px); display: flex; flex-direction: column; box-shadow: 0 18px 50px rgba(0,0,0,0.5); }
.sa-modal-head { display: flex; justify-content: space-between; align-items: center; padding: 14px 18px; border-bottom: 1px solid var(--n-700); }
.sa-modal-head h3 { margin: 0; }
.sa-modal-x { background: none; border: 0; color: var(--n-400); font-size: 18px; line-height: 1; cursor: pointer; padding: 4px 6px; border-radius: var(--r-sm); }
.sa-modal-x:hover { color: var(--n-100); background: var(--n-800); }
.sa-modal-body { padding: 18px; overflow-y: auto; }
.sa-modal-foot { display: flex; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--n-700); }

[data-theme="light"] .sa-modal-card { background: #ffffff; }
[data-theme="light"] .sa-meta { background: var(--n-900); }
[data-theme="light"] .sa-table-click tbody tr.sa-row:hover { background: var(--n-850); }
[data-theme="light"] .sa-scope-chip { background: var(--n-900); }
