/* =====================================================================
   Enter EMS - Enter Technikwelt Solothurn brand system

   Tokens below are taken verbatim from
   docs/2026-08-05-enter-ems-auth-and-brand-design.md section 3 (itself
   read from the live enter.ch stylesheet). All three pages (login,
   dashboard, visitor display) draw from this single :root block so the
   palette can be changed in one place.

   Font note: 'ABC Diatype Rounded' / 'ABC Diatype Rounded Medium' are
   licensed Dinamo faces this project does not hold a license for, so no
   font file is embedded. The name is listed first in each stack purely
   so the site self-upgrades the moment Enter installs the real face; the
   Helvetica/Arial fallback (the same fallback enter.ch itself declares)
   is what actually renders today. If a license is obtained later, drop
   the woff2 files into web/fonts/ and add @font-face rules above this
   block, referencing web/fonts/*.woff2 - no other change is needed.
   ===================================================================== */

:root {
  /* ---- Brand core ---- */
  --brand-yellow: #FFE173;
  --brand-yellow-selection: rgba(210, 168, 41, 0.3);
  --near-black: #1A1A1A;
  --off-white: #FAFAFA;

  /* ---- Gray ramp (darkest to lightest) ---- */
  --gray-050: #050505;
  --gray-100: #121212;
  --gray-200: #262626;
  --gray-300: #333333;
  --gray-400: #4D4D4D;
  --gray-500: #666666;
  --gray-600: #999999;
  --gray-700: #B3B3B3;
  --gray-800: #CCCCCC;
  --gray-900: #D9D9D9;
  --gray-950: #E6E6E6;
  --gray-975: #EDEDED;

  /* ---- Warm accent set: data series identity + card accents ---- */
  --warm-orange: #FFA347;
  --warm-coral: #FF5A5B;
  --warm-pink: #FFB2FF;
  --warm-peach: #FFD3A6;
  --warm-blush: #FFB8B8;
  --warm-pale: #FFF2A3;

  /* Functional status colors. Not part of the brand identity palette
     (the brand system has no "system state" hues) so these reuse the two
     most saturated warm accents already in the set for warning/critical,
     plus one small addition (a plain green) for "good", the one state
     the brand palette has no candidate for at all. */
  --status-good: #2F9E44;
  --status-warning: var(--warm-orange);
  --status-critical: var(--warm-coral);

  /* ---- Type ---- */
  --font-heading: 'ABC Diatype Rounded Medium', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-body: 'ABC Diatype Rounded', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  /* ---- Light surface roles: login + internal dashboard ---- */
  --surface-page: var(--off-white);
  --surface-card: #FFFFFF;
  --surface-card-alt: var(--gray-975);
  --border-subtle: var(--gray-950);
  --border-strong: var(--gray-900);
  --ink-primary: var(--near-black);
  --ink-secondary: var(--gray-400);
  --ink-muted: var(--gray-600);

  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 22px;
  --radius-pill: 100px;

  color-scheme: light;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--surface-page);
  color: var(--ink-primary);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 500;
  text-transform: none;
}

::selection {
  background: var(--brand-yellow-selection);
  color: var(--near-black);
}

a {
  color: var(--ink-primary);
}

:focus-visible {
  outline: 2px solid var(--near-black);
  outline-offset: 2px;
  border-radius: 4px;
}

/* A quiet, repeatable brand device: a small dot-grid field evoking a
   circuit board or perforated instrument panel, a nod to the museum's
   technology-history collection without illustrating anything literal.
   Used at very low opacity so it reads as texture, not decoration. */
.grid-motif {
  background-image: radial-gradient(circle, var(--gray-900) 1px, transparent 1px);
  background-size: 26px 26px;
}

/* =====================================================================
   Login page
   ===================================================================== */

body.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  position: relative;
  overflow-x: hidden;
}

body.login-page::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: radial-gradient(circle, var(--gray-900) 1px, transparent 1px);
  background-size: 30px 30px;
  opacity: 0.5;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 42%, #000 0%, transparent 72%);
  mask-image: radial-gradient(ellipse 70% 60% at 50% 42%, #000 0%, transparent 72%);
  pointer-events: none;
}

.login-shell {
  position: relative;
  width: 100%;
  min-width: 0;
  max-width: 408px;
}

.login-card {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 44px 40px 40px;
  box-shadow: 0 1px 2px rgba(26, 26, 26, 0.04), 0 12px 32px rgba(26, 26, 26, 0.05);
}

.login-mark {
  display: flex;
  align-items: baseline;
  gap: 2px;
  margin-bottom: 2px;
}

.login-mark-dot {
  width: 9px;
  height: 9px;
  min-width: 9px;
  border-radius: 3px;
  background: var(--brand-yellow);
  border: 1px solid rgba(26, 26, 26, 0.12);
  margin-right: 9px;
  transform: translateY(-3px);
}

.login-wordmark {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 30px;
  letter-spacing: -0.01em;
  color: var(--ink-primary);
}

.login-wordmark-light {
  font-weight: 400;
  color: var(--ink-muted);
  margin-left: 0.14em;
}

.login-tagline {
  margin: 8px 0 32px;
  font-size: 13.5px;
  color: var(--ink-muted);
  padding-bottom: 24px;
  border-bottom: 1px solid var(--border-subtle);
}

.login-form {
  display: flex;
  flex-direction: column;
}

.login-label {
  font-size: 12.5px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  margin-bottom: 8px;
}

.login-input {
  font: inherit;
  font-size: 16px;
  color: var(--ink-primary);
  background: var(--surface-page);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 13px 14px;
  width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.login-input:focus-visible {
  outline: none;
  border-color: #D2A829;
  box-shadow: 0 0 0 4px var(--brand-yellow-selection);
}

/* Reserved-height error area: always present in the DOM and the a11y
   tree so role="alert" is announced, and always occupying the same
   vertical space so an incorrect-password message never shifts the
   button beneath it. */
.login-error {
  min-height: 34px;
  margin: 10px 0 0;
  padding: 0 2px;
  display: flex;
  align-items: center;
  font-size: 13px;
  color: var(--warm-coral);
  font-weight: 550;
}

.login-error:empty::before {
  content: "\00a0";
}

.login-button {
  font: inherit;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 15.5px;
  color: var(--near-black);
  background: var(--brand-yellow);
  border: none;
  border-radius: var(--radius-sm);
  padding: 14px 18px;
  margin-top: 6px;
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.05s ease;
}

.login-button:hover {
  filter: brightness(0.96);
}

.login-button:active {
  transform: translateY(1px);
}

.login-button:disabled {
  opacity: 0.6;
  cursor: default;
}

@media (max-width: 480px) {
  .login-card {
    padding: 36px 26px 32px;
  }
  .login-wordmark {
    font-size: 26px;
  }
}

/* =====================================================================
   Internal dashboard (index.html)
   ===================================================================== */

.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 24px 64px;
}

/* ---------- Header ---------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 26px 0 22px;
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: 30px;
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: 0;
}

.wordmark-dot {
  width: 8px;
  height: 8px;
  min-width: 8px;
  border-radius: 2.5px;
  background: var(--brand-yellow);
  border: 1px solid rgba(26, 26, 26, 0.12);
  margin-right: 9px;
  transform: translateY(-2px);
}

.wordmark-text {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 19px;
  letter-spacing: -0.01em;
  color: var(--ink-primary);
}

.wordmark-text .light {
  font-weight: 400;
  color: var(--ink-muted);
  margin-left: 0.14em;
}

.status-cluster {
  display: flex;
  align-items: center;
  gap: 16px;
}

.status-live {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: var(--ink-secondary);
}

.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--status-good);
  box-shadow: 0 0 0 3px rgba(47, 158, 68, 0.16);
  animation: pulse 2.4s ease-in-out infinite;
}

.live-dot.is-offline {
  background: var(--ink-muted);
  box-shadow: 0 0 0 3px rgba(153, 153, 153, 0.16);
  animation: none;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .live-dot { animation: none; }
}

.updated-at {
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.logout-button {
  font: inherit;
  font-size: 13px;
  font-weight: 550;
  color: var(--ink-secondary);
  background: transparent;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-pill);
  padding: 7px 16px;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.logout-button:hover {
  border-color: var(--ink-primary);
  color: var(--ink-primary);
}

a.wordmark {
  text-decoration: none;
  align-items: center;
  gap: 10px;
}

.wordmark-logo {
  height: 30px;
  display: block;
}

/* ---------- Stale banner ----------
   Stays in the DOM and in the accessibility tree at all times (never
   display:none) so its role="status" live region is announced by screen
   readers when its content becomes relevant; visibility toggles via
   opacity + a collapsed max-height instead. */

.stale-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #FFF6E9;
  border: 1px solid rgba(255, 163, 71, 0.4);
  border-width: 0;
  color: #8A4B0F;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  padding: 0 14px;
  margin-bottom: 0;
  transition: max-height 0.2s ease, opacity 0.2s ease, padding 0.2s ease,
    margin-bottom 0.2s ease;
}

.stale-banner.is-visible {
  border-width: 1px;
  max-height: 60px;
  opacity: 1;
  padding: 10px 14px;
  margin-bottom: 26px;
}

@media (prefers-reduced-motion: reduce) {
  .stale-banner {
    transition: none;
  }
}

.stale-banner .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--status-warning);
  flex: none;
}

/* ---------- Section labels ---------- */

.section-label {
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-muted);
  margin: 0 0 12px;
}

section + section {
  margin-top: 38px;
}

/* ---------- Live power flow schematic ----------
   A compact single-line diagram, not a copy of the kiosk's illustrated
   scene: three flat node chips (Solar, Building, Grid) plus three arrows,
   all abstract shapes and small LED-style dots rather than illustration.
   Two hand-authored inline SVGs cover the layout (a landscape triangle
   for wide screens, a vertical stack for narrow ones) because scaling a
   single viewBox from ~1130px down to a phone's ~340px would shrink text
   past legibility; both variants are driven by the same JS via shared
   value/state classes, and only one is ever displayed at a time. */

.flow-wrap {
  position: relative;
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 20px;
}

.flow-svg {
  display: block;
  width: 100%;
  height: auto;
}

.flow-svg-narrow {
  display: none;
}

@media (max-width: 640px) {
  .flow-svg-wide { display: none; }
  .flow-svg-narrow { display: block; }
}

.flow-node-box {
  fill: var(--surface-card-alt);
  stroke: var(--border-strong);
  stroke-width: 1.5;
}

.flow-node-dot {
  stroke: none;
}

.dot-solar { fill: #D2A829; }
.dot-building { fill: var(--gray-600); }
.dot-grid { fill: var(--gray-600); transition: fill 0.3s ease; }

.node-grid.is-export .dot-grid { fill: var(--warm-orange); }
.node-grid.is-import .dot-grid { fill: var(--warm-coral); }

.flow-node-label {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  fill: var(--ink-muted);
}

.flow-node-label-solo {
  dominant-baseline: middle;
}

.flow-node-value {
  font-family: var(--font-heading);
  font-size: 27px;
  font-weight: 500;
  fill: var(--ink-primary);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.flow-node-value .flow-unit {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  fill: var(--ink-muted);
}

/* Arrows: a single path per hop, always present (dormant = thin, gray,
   low opacity) so the topology reads at a glance even with zero flow;
   JS raises stroke-width with magnitude and swaps in the accent color
   and marker when a hop is active, clamped between a floor (always
   visible) and a ceiling (never blows out the layout). */

.flow-arrow-line {
  fill: none;
  stroke: var(--gray-800);
  stroke-width: 2.5;
  stroke-linecap: round;
  opacity: 0.55;
  transition: stroke 0.35s ease, stroke-width 0.35s ease, opacity 0.35s ease;
}

.arrow-selfuse.is-active .flow-arrow-line { stroke: #D2A829; opacity: 1; }
.arrow-export.is-active .flow-arrow-line { stroke: var(--warm-orange); opacity: 1; }
.arrow-import.is-active .flow-arrow-line { stroke: var(--warm-coral); opacity: 1; }

marker path {
  fill: var(--gray-700);
}

#fa-gold-w path, #fa-gold-n path { fill: #D2A829; }
#fa-orange-w path, #fa-orange-n path { fill: var(--warm-orange); }
#fa-coral-w path, #fa-coral-n path { fill: var(--warm-coral); }

/* Restrained directional motion: one small dot per active hop, travelling
   the same path the line follows via CSS motion path. The line itself
   stays a plain solid stroke; only this dot moves, and slowly. Off
   entirely under prefers-reduced-motion below. */
.flow-particle {
  r: 3;
  opacity: 0;
  animation: flow-travel 2.6s linear infinite;
  transition: opacity 0.3s ease;
}

.arrow-selfuse .flow-particle { fill: #D2A829; }
.arrow-export .flow-particle { fill: var(--warm-orange); }
.arrow-import .flow-particle { fill: var(--warm-coral); }

.flow-arrow.is-active .flow-particle {
  opacity: 0.85;
}

@keyframes flow-travel {
  from { offset-distance: 0%; }
  to { offset-distance: 100%; }
}

.flow-label-bg {
  fill: var(--surface-card);
  stroke: var(--border-subtle);
  stroke-width: 1;
  transition: stroke 0.35s ease;
}

.arrow-selfuse.is-active .flow-label-bg { stroke: #D2A829; }
.arrow-export.is-active .flow-label-bg { stroke: var(--warm-orange); }
.arrow-import.is-active .flow-label-bg { stroke: var(--warm-coral); }

.flow-label-dot {
  fill: var(--gray-600);
  transition: fill 0.35s ease;
}

.arrow-selfuse.is-active .flow-label-dot { fill: #D2A829; }
.arrow-export.is-active .flow-label-dot { fill: var(--warm-orange); }
.arrow-import.is-active .flow-label-dot { fill: var(--warm-coral); }

.flow-label-text {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 500;
  fill: var(--ink-primary);
  font-variant-numeric: tabular-nums;
}

.flow-label-text .flow-unit {
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 500;
  fill: var(--ink-muted);
}

.flow-offline-note {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  padding: 9px 20px;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--ink-primary);
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  box-shadow: 0 4px 16px rgba(26, 26, 26, 0.08);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  transition: opacity 0.3s ease;
}

.flow-wrap.is-offline .flow-offline-note {
  opacity: 1;
}

.flow-wrap.is-offline .flow-svg {
  filter: grayscale(0.9) opacity(0.4);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .flow-arrow-line { transition: none; }
  .flow-particle {
    animation: none !important;
    opacity: 0 !important;
  }
  .flow-node-dot, .flow-label-dot, .flow-label-bg, .flow-offline-note, .flow-svg {
    transition: none;
  }
}

@media (max-width: 520px) {
  .flow-wrap {
    padding: 14px;
  }
}

/* ---------- Economics cards ---------- */

.econ-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.econ-card {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 20px 22px;
}

.econ-card h3 {
  margin: 0 0 14px;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-primary);
}

.econ-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 6px 0;
  color: var(--ink-secondary);
  font-size: 13.5px;
}

.econ-line .value {
  font-variant-numeric: tabular-nums;
  color: var(--ink-primary);
}

.econ-line.is-total {
  margin-top: 8px;
  padding: 12px 0 0 12px;
  border-top: 1px solid var(--border-subtle);
  border-left: 3px solid var(--brand-yellow);
}

.econ-line.is-total .label {
  color: var(--ink-primary);
  font-weight: 550;
}

.econ-line.is-total .value {
  font-size: 21px;
  font-weight: 650;
}

/* ---------- Peak card ---------- */

.peak-card {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 20px 22px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 26px;
}

.peak-figure {
  display: flex;
  align-items: center;
}

/* The single headline benefit figure permitted a brand-yellow treatment:
   a compact pill of solid yellow with near-black text, never a page-wide
   wash, reserved for this one number on the whole dashboard. */
.peak-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  background: var(--brand-yellow);
  color: var(--near-black);
  border-radius: var(--radius-pill);
  padding: 10px 20px;
}

.peak-value {
  font-family: var(--font-heading);
  font-size: 26px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.peak-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: var(--ink-secondary);
  font-size: 13px;
}

.peak-meta .peak-when {
  color: var(--ink-muted);
}

.peak-cost {
  margin-left: auto;
  text-align: right;
}

.peak-cost .stat-label {
  font-size: 12.5px;
  color: var(--ink-secondary);
  margin: 0 0 6px;
}

.peak-cost .value {
  font-size: 22px;
  font-weight: 650;
  color: var(--ink-primary);
  font-variant-numeric: tabular-nums;
}

/* ---------- Charts ---------- */

.chart-row {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: 12px;
  align-items: start;
}

.chart-card {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 20px 22px 14px;
}

.chart-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}

.chart-card-head h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-primary);
}

.chart-toggle {
  background: none;
  border: 1px solid var(--border-strong);
  color: var(--ink-secondary);
  font: inherit;
  font-size: 12px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.chart-toggle:hover {
  border-color: var(--ink-primary);
  color: var(--ink-primary);
}

.chart-canvas-wrap {
  position: relative;
  height: 260px;
  margin-top: 8px;
}

.chart-data-table {
  display: none;
  width: 100%;
  border-collapse: collapse;
  margin-top: 10px;
  font-size: 12.5px;
}

.chart-data-table.is-visible {
  display: table;
}

.is-hidden {
  display: none;
}

.chart-data-table th,
.chart-data-table td {
  text-align: right;
  padding: 5px 8px;
  border-bottom: 1px solid var(--border-subtle);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink-secondary);
}

.chart-data-table td:not(:first-child) {
  color: var(--ink-primary);
}

.chart-data-table th:first-child,
.chart-data-table td:first-child {
  text-align: left;
}

.chart-data-table thead th {
  color: var(--ink-muted);
  font-weight: 550;
  border-bottom: 1px solid var(--border-strong);
}

/* ---------- CSV export ---------- */

.export-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

.button {
  font: inherit;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 13.5px;
  color: var(--near-black);
  background: var(--brand-yellow);
  border: none;
  padding: 11px 18px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: filter 0.15s ease;
}

.button:hover {
  filter: brightness(0.96);
}

.button:disabled {
  opacity: 0.55;
  cursor: default;
}

.export-hint {
  color: var(--ink-muted);
  font-size: 12.5px;
}

/* ---------- Footer ---------- */

.site-footer {
  margin-top: 46px;
  padding-top: 22px;
  border-top: 1px solid var(--border-subtle);
  color: var(--ink-muted);
  font-size: 12.5px;
  line-height: 1.6;
}

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
  .econ-row {
    grid-template-columns: 1fr;
  }
  .chart-row {
    grid-template-columns: 1fr;
  }
  .peak-cost {
    margin-left: 0;
    text-align: left;
  }
}

@media (max-width: 520px) {
  .wrap {
    padding: 0 16px 48px;
  }
  .site-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  .status-cluster {
    width: 100%;
    justify-content: space-between;
  }
}

/* =====================================================================
   Visitor display (kiosk view, display.html)

   Full-bleed, non-interactive, no-scroll energy-monitor layout: a light
   dashboard with stat columns left and right, an isometric scene of the
   site in the middle, and today's energy curve along the bottom. All of
   it is scoped under html.kiosk / body.kiosk so nothing leaks onto the
   login page or the internal dashboard. Sizing uses vh/vw throughout:
   1920x1080 and 1280x720 share the same 16:9 aspect ratio, so viewport
   units scale the whole layout identically without breakpoints.
   ===================================================================== */

html.kiosk,
body.kiosk {
  height: 100%;
  overflow: hidden;
}

body.kiosk {
  display: block;
  background: #EEF2F7;
  color: #1E293B;
  position: relative;

  --m-card-bg: #FFFFFF;
  --m-card-border: #E4EAF1;
  --m-ink: #1E293B;
  --m-ink-soft: #64748B;
  --m-ink-muted: #94A3B8;
  --m-solar: #F59E0B;
  --m-cons: #3B82F6;
  --m-export: #10B981;
  --m-import: #E4572E;
  --m-grid: #94A3B8;
  --m-good: #16A34A;
  --m-warn: #F59E0B;
  color-scheme: light;
}

.kiosk-shell {
  height: 100vh;
  width: 100vw;
  display: grid;
  grid-template-columns: 21.5vw minmax(0, 1fr) 21.5vw;
  grid-template-rows: auto minmax(0, 1fr) 26vh;
  gap: 1.4vh 0.9vw;
  padding: 1.6vh 1.2vw 1.8vh;
  grid-template-areas:
    "header header header"
    "left   scene  right"
    "left   chart  right";
  position: relative;
}

/* ---------- Stale banner: overlay pill, top center ---------- */

.kiosk-stale-banner {
  position: absolute;
  top: 9vh;
  left: 50%;
  transform: translate(-50%, -1vh);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 1vh;
  background: #FFF6E9;
  border: 1px solid rgba(245, 158, 11, 0.5);
  color: #8A4B0F;
  border-radius: var(--radius-pill);
  font-size: 1.9vh;
  padding: 1.2vh 2.2vh;
  box-shadow: 0 8px 24px rgba(30, 41, 59, 0.12);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.kiosk-stale-banner.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

.kiosk-stale-banner .dot {
  width: 1.2vh;
  height: 1.2vh;
  min-width: 9px;
  min-height: 9px;
  border-radius: 50%;
  background: var(--m-warn);
  flex: none;
}

.kiosk-stale-banner strong {
  color: #6B3A0A;
  font-weight: 650;
  margin-right: 0.35em;
}

@media (prefers-reduced-motion: reduce) {
  .kiosk-stale-banner { transition: none; }
}

/* ---------- Header ---------- */

.kiosk-header {
  grid-area: header;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2vw;
  padding: 0 0.2vw;
}

.kiosk-brand {
  display: flex;
  align-items: center;
  gap: 0;
}

.kiosk-brand .brand-dot {
  width: 1.5vh;
  height: 1.5vh;
  min-width: 10px;
  min-height: 10px;
  border-radius: 0.45vh;
  background: var(--brand-yellow);
  border: 1px solid rgba(26, 26, 26, 0.14);
  margin-right: 1.1vh;
}

.kiosk-brand h1 {
  margin: 0;
  line-height: 1;
  transform: translateY(0.15vh);
  font-family: var(--font-heading);
  font-size: 3.1vh;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--m-ink);
}

.kiosk-brand h1 .light {
  font-weight: 400;
  color: var(--m-ink-soft);
  margin-left: 0.16em;
}

.kiosk-subtitle {
  margin: 0.4vh 0 0;
  font-size: 1.8vh;
  color: var(--m-ink-muted);
}

.live-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.9vh;
  margin-left: 1.6vw;
  padding: 0.7vh 1.5vh;
  border-radius: var(--radius-pill);
  background: var(--m-card-bg);
  border: 1px solid var(--m-card-border);
  font-size: 1.8vh;
  font-weight: 550;
  color: var(--m-ink-soft);
}

.live-pill .live-dot {
  width: 1.1vh;
  height: 1.1vh;
  min-width: 8px;
  min-height: 8px;
  border-radius: 50%;
  background: var(--m-good);
  animation: pulse 2.4s ease-in-out infinite;
}

.live-pill .live-dot.is-offline {
  background: var(--m-ink-muted);
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .live-pill .live-dot { animation: none; }
}

.kiosk-chips {
  display: flex;
  align-items: center;
  gap: 0.8vw;
}

.chip {
  background: var(--m-card-bg);
  border: 1px solid var(--m-card-border);
  border-radius: var(--radius-pill);
  padding: 1vh 1.8vh;
  font-size: 1.9vh;
  color: var(--m-ink-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* discreet staff login link on the public kiosk header */
a.chip-login {
  text-decoration: none;
  color: var(--m-ink-soft);
  opacity: 0.75;
  transition: opacity 120ms ease;
}
a.chip-login:hover,
a.chip-login:focus-visible {
  opacity: 1;
}

.chip-time {
  font-family: var(--font-heading);
  font-weight: 500;
  color: var(--m-ink);
  font-size: 2.1vh;
}

/* ---------- Cards ---------- */

.col-left,
.col-right {
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 1.4vh;
}

.col-left { grid-area: left; }
.col-right { grid-area: right; }

.col-left .m-card,
.col-right .m-card {
  flex: 1 1 0;
  min-height: 0;
}

.m-card {
  background: var(--m-card-bg);
  border: 1px solid var(--m-card-border);
  border-radius: 1.8vh;
  padding: 2vh 1.1vw;
  box-shadow: 0 1px 2px rgba(30, 41, 59, 0.04), 0 8px 20px rgba(30, 41, 59, 0.04);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.m-card-head {
  display: flex;
  align-items: center;
  gap: 1.3vh;
}

.m-card-head h2 {
  margin: 0;
  font-size: 1.75vh;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--m-ink-soft);
}

.m-ic {
  width: 4.4vh;
  height: 4.4vh;
  min-width: 30px;
  min-height: 30px;
  border-radius: 1.2vh;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}

.m-ic svg {
  width: 62%;
  height: 62%;
}

.ic-solar { background: rgba(245, 158, 11, 0.14); color: var(--m-solar); }
.ic-cons  { background: rgba(59, 130, 246, 0.12); color: var(--m-cons); }
.ic-grid  { background: rgba(100, 116, 139, 0.12); color: #64748B; }

.m-big {
  margin: 0.6vh 0 0;
  font-family: var(--font-heading);
  font-size: 6vh;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  color: var(--m-ink);
}

.m-big-sm {
  font-size: 4.6vh;
}

.m-unit {
  font-size: 0.42em;
  font-weight: 400;
  color: var(--m-ink-muted);
  margin-left: 0.35em;
}

.m-dir {
  margin: 0.6vh 0 -0.6vh;
  font-size: 1.8vh;
  font-weight: 650;
  color: var(--m-ink-muted);
}

.m-dir.is-export { color: var(--m-export); }
.m-dir.is-import { color: var(--m-import); }

.m-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1vw;
  margin-top: 1vh;
}

.m-foot-text { min-width: 0; }

.m-foot-label {
  margin: 0;
  font-size: 1.6vh;
  color: var(--m-ink-muted);
}

.m-foot-value {
  margin: 0.2vh 0 0;
  font-size: 2.2vh;
  font-weight: 650;
  color: var(--m-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.m-spark {
  position: relative;
  flex: 1 1 auto;
  max-width: 55%;
  height: 7.5vh;
  min-height: 40px;
}

.m-spark canvas {
  position: absolute;
  inset: 0;
}

/* ---------- Right column ---------- */

.m-label {
  margin: 0;
  font-size: 1.65vh;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--m-ink-soft);
}

.m-card-status {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 1.4vh;
}

.status-ic {
  width: 6vh;
  height: 6vh;
  min-width: 40px;
  min-height: 40px;
  color: var(--m-good);
  flex: none;
}

.status-ic svg { width: 100%; height: 100%; }

body.is-status-warn .status-ic { color: var(--m-warn); }

.status-title {
  margin: 0.5vh 0 0;
  font-family: var(--font-heading);
  font-size: 2.6vh;
  font-weight: 500;
  color: var(--m-ink);
}

.status-sub {
  margin: 0.2vh 0 0;
  font-size: 1.7vh;
  color: var(--m-ink-muted);
  font-variant-numeric: tabular-nums;
}

.m-meter { margin-top: 1vh; }

.m-meter-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1vh;
  font-size: 1.7vh;
  color: var(--m-ink-soft);
  margin-bottom: 0.7vh;
  font-variant-numeric: tabular-nums;
}

.m-meter-head span:last-child {
  font-weight: 650;
  color: var(--m-ink);
  white-space: nowrap;
  font-size: 1.6vh;
}

.m-bar {
  height: 1.2vh;
  min-height: 8px;
  border-radius: var(--radius-pill);
  background: #E9EEF4;
  overflow: hidden;
}

.m-bar i {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: var(--radius-pill);
  transition: width 0.6s ease;
}

.bar-selfuse { background: var(--m-cons); }
.bar-autarkie { background: var(--m-export); }

/* explainer notes on the metric cards */
.m-note {
  margin: 0.8vh 0 0;
  font-size: 1.5vh;
  line-height: 1.3;
  color: #64748B;
}
.m-note b { color: #1E293B; font-weight: 650; }
.m-note-dim { color: #94A3B8; }

/* donut cards (mix + autarky) */
.mix-wrap {
  display: flex;
  align-items: center;
  gap: 1.8vh;
  margin-top: 0.8vh;
}
.donut { width: 11vh; height: 11vh; flex: none; }
.donut-track { fill: none; stroke: #EDF1F6; stroke-width: 13; }
.donut-seg {
  fill: none;
  stroke-width: 13;
  transform: rotate(-90deg);
  transform-origin: 60px 60px;
  transition: stroke-dasharray 0.6s ease, stroke-dashoffset 0.6s ease;
}
.seg-solarmix { stroke: var(--m-solar); }
.seg-gridmix { stroke: var(--m-grid); }
.seg-use-museum { stroke: var(--m-cons); }
.seg-use-grid { stroke: var(--m-export); }
.donut-big { font-size: 25px; font-weight: 650; fill: #1E293B; font-family: var(--font-heading); }
.donut-sub { font-size: 12px; fill: #64748B; }
.mix-legend { flex: 1; min-width: 0; }
.leg-row {
  display: flex;
  align-items: center;
  gap: 1vh;
  margin: 0.5vh 0;
  font-size: 1.75vh;
  color: #475569;
}
.leg-row b {
  margin-left: auto;
  color: #1E293B;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  white-space: nowrap;
}
.leg-dot { width: 1.3vh; height: 1.3vh; border-radius: 50%; flex: none; }
.dot-mix-solar { background: var(--m-solar); }
.dot-mix-grid { background: var(--m-grid); }
.dot-use-museum { background: var(--m-cons); }
.dot-use-grid { background: var(--m-export); }

.kiosk-logo {
  height: 4.2vh;
  width: auto;
  align-self: center;
  margin-right: 0.7vw;
}

/* explainer under the day chart header */
.chart-note {
  margin: 0.2vh 0 0.8vh;
  font-size: 1.62vh;
  line-height: 1.35;
  color: #64748B;
}
.chart-note b { font-weight: 650; color: #334155; }

@media (prefers-reduced-motion: reduce) {
  .m-bar i { transition: none; }
}

.m-card-benefit {
  background: linear-gradient(135deg, #FFF3C2, #FFE99B);
  border-color: rgba(210, 168, 41, 0.45);
}

.m-card-benefit .m-label { color: #7A5C10; }
.m-card-benefit .m-big { color: var(--near-black); }
.m-card-benefit .m-unit { color: rgba(26, 26, 26, 0.55); }

.m-note {
  margin: 0.6vh 0 0;
  font-size: 1.7vh;
  color: rgba(26, 26, 26, 0.6);
}

/* ---------- Scene ---------- */

.kiosk-scene {
  grid-area: scene;
  position: relative;
  min-height: 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

#scene-svg {
  width: 100%;
  height: 100%;
  transition: filter 0.6s ease, opacity 0.6s ease;
}

#scene-svg.is-frozen {
  filter: grayscale(0.85);
  opacity: 0.55;
}

/* badges (sun, pylon) */

.badge-circle {
  fill: #FFFFFF;
  stroke: #E2E8F0;
  stroke-width: 2;
}

.badge {
  filter: drop-shadow(0 4px 10px rgba(30, 41, 59, 0.12));
}

.sun-glyph {
  stroke: var(--m-solar);
  fill: none;
  opacity: 0.45;
  transition: opacity 0.4s ease;
}

.sun-badge.is-active .sun-glyph { opacity: 1; }

.pylon-glyph {
  stroke: #64748B;
  stroke-width: 3.4;
  fill: none;
}

.pylon-glyph circle { fill: #64748B; stroke: none; }

/* sun ray onto the roof */

.sun-ray {
  fill: none;
  stroke: var(--m-solar);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 1 9; /* period 10 divides the -100 dash cycle */
  opacity: 0.3;
  transition: opacity 0.4s ease;
}

.sun-ray.is-active {
  opacity: 1;
  animation: ribbon-dash var(--dur, 1.6s) linear infinite;
}

/* hub */

.hub-circle {
  fill: #FFFFFF;
  stroke: #E2E8F0;
  stroke-width: 2;
}

.hub-dot {
  fill: var(--brand-yellow);
  stroke: rgba(26, 26, 26, 0.2);
  stroke-width: 1;
}

.hub.is-active .hub-dot {
  animation: pulse 2.2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .hub.is-active .hub-dot { animation: none; }
}

/* energy ribbons */

.lane path {
  fill: none;
  stroke-linecap: round;
}

.ribbon-base {
  stroke: #B9C4D5;
  stroke-width: 3.5;
  opacity: 1;
}

.ribbon-glow {
  stroke-width: calc(var(--w, 7) * 2px);
  opacity: 0;
  filter: url(#ribbon-soften);
  animation: ribbon-dash var(--dur, 1.6s) linear infinite;
  transition: opacity 0.4s ease;
}

.ribbon-core {
  stroke-width: calc(var(--w, 7) * 1px);
  opacity: 0;
  animation: ribbon-dash var(--dur, 1.6s) linear infinite;
  transition: opacity 0.4s ease;
}

.lane.is-flowing .ribbon-glow { opacity: 0.3; }
.lane.is-flowing .ribbon-core { opacity: 1; }

.lane-solar path:not(.ribbon-base) { stroke: var(--m-solar); }
.lane-cons path:not(.ribbon-base) { stroke: var(--m-cons); }
.lane-export path:not(.ribbon-base) { stroke: var(--m-export); }
.lane-import path:not(.ribbon-base) { stroke: var(--m-grid); }

@keyframes ribbon-dash {
  to { stroke-dashoffset: calc(-1 * var(--plen, 100px)); }
}

@media (prefers-reduced-motion: reduce) {
  .ribbon-core, .sun-ray.is-active {
    animation: none !important;
  }
}

/* callouts */

.callout-card {
  fill: #FFFFFF;
  stroke: #E4EAF1;
  stroke-width: 1;
}

/* vector stand-in for a drop shadow: SVG filters make Safari rasterize
   the whole group, turning the callout text blurry on zoom */
.callout-shadow {
  fill: rgba(30, 41, 59, 0.04);
}
.callout-shadow-far {
  fill: rgba(30, 41, 59, 0.025);
}

.callout-leader {
  stroke: #AFBCCB;
  stroke-width: 2.5;
  stroke-dasharray: 1 8;
  stroke-linecap: round;
}

.callout-title {
  font-family: var(--font-heading);
  font-size: 30px;
  font-weight: 500;
  fill: #1E293B;
}

.callout-sub {
  font-family: var(--font-body);
  font-size: 22px;
  font-weight: 550;
}

.sub-cons { fill: var(--m-cons); }
.sub-solar { fill: var(--m-solar); }

.callout-line { font-family: var(--font-body); }
.callout-val { font-size: 32px; font-weight: 650; font-variant-numeric: tabular-nums; }
.val-solar { fill: var(--m-solar); }
.val-cons { fill: var(--m-cons); }
.val-export { fill: var(--m-export); }
.val-import { fill: #64748B; }
.callout-unit { font-size: 18px; font-weight: 550; fill: #94A3B8; }
.callout-tag { font-size: 18px; font-weight: 500; fill: #64748B; }

/* ---------- Chart panel ---------- */

.chart-panel {
  grid-area: chart;
  min-height: 0;
}

.chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2vw;
  margin-bottom: 0.6vh;
}

.chart-head h2 {
  margin: 0;
  font-size: 1.75vh;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--m-ink-soft);
}

.chart-legend {
  display: flex;
  align-items: center;
  gap: 1.6vw;
  font-size: 1.7vh;
  color: var(--m-ink-soft);
}

.leg {
  display: inline-flex;
  align-items: center;
  gap: 0.8vh;
}

.leg::before {
  content: "";
  width: 1.4vh;
  height: 1.4vh;
  min-width: 9px;
  min-height: 9px;
  border-radius: 0.4vh;
}

.leg-solar::before { background: var(--m-solar); }
.leg-cons::before { background: var(--m-cons); }

.chart-body {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
}

.chart-body canvas {
  position: absolute;
  inset: 0;
}

/* =====================================================================
   Kiosk page on phones / narrow windows: the fixed 100vh three-column
   grid becomes a scrolling single column with px-based type (the vh
   units above are tuned for a 16:9 wall display, not a phone).
   ===================================================================== */
/* ---------- Technical section (staff dashboard) ---------- */

.tech-tiles {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin-bottom: 12px;
}

.tech-tile {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 14px 16px;
}

.tech-tile-label {
  margin: 0 0 6px;
  font-size: 12px;
  color: var(--ink-muted);
}

.tech-tile-value {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 500;
  color: var(--ink-primary);
  font-variant-numeric: tabular-nums;
}

.tech-unit {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--ink-muted);
  margin-left: 4px;
}

.tech-chart { margin-bottom: 12px; }

.tech-head-right {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.tech-updated {
  font-size: 12.5px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.tech-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: start;
}

.tech-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 8px;
  font-size: 13px;
}

.tech-table th,
.tech-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border-subtle);
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink-primary);
}

.tech-table thead th {
  color: var(--ink-muted);
  font-weight: 550;
  border-bottom: 1px solid var(--border-strong);
}

.tech-table tbody th {
  text-align: left;
  font-weight: 550;
  color: var(--ink-secondary);
}

.tech-note {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--ink-muted);
  line-height: 1.5;
}

.mppt-list { margin-top: 10px; }

.mppt-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
}

.mppt-name {
  width: 58px;
  flex: none;
  font-size: 12.5px;
  color: var(--ink-secondary);
}

.mppt-bar {
  flex: 1 1 auto;
  height: 10px;
  background: var(--gray-975);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.mppt-fill {
  display: block;
  height: 100%;
  background: var(--warm-orange);
  border-radius: var(--radius-pill);
  transition: width 0.5s ease;
}

@media (prefers-reduced-motion: reduce) {
  .mppt-fill { transition: none; }
}

.mppt-val {
  width: 122px;
  flex: none;
  text-align: right;
  font-size: 12.5px;
  color: var(--ink-primary);
  font-variant-numeric: tabular-nums;
}

.strings-details { margin-top: 14px; }

.strings-details summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--ink-secondary);
}

@media (max-width: 900px) {
  .tech-tiles { grid-template-columns: repeat(3, 1fr); }
  .tech-grid { grid-template-columns: 1fr; }
}

@media (max-width: 520px) {
  .tech-tiles { grid-template-columns: repeat(2, 1fr); }
  .mppt-val { width: 104px; }
}

.kiosk-foot { display: none; }

@media (max-width: 820px) {
  /* the wall-display page locks scrolling on html.kiosk; phones must scroll */
  html.kiosk,
  body.kiosk {
    height: auto;
    overflow: visible;
  }
  body.kiosk { overflow-y: auto; }

  .kiosk-shell {
    height: auto;
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
    grid-template-areas:
      "header"
      "scene"
      "left"
      "right"
      "chart";
    gap: 10px;
    padding: 12px 12px 28px;
  }

  .kiosk-header { flex-wrap: wrap; gap: 6px 10px; align-items: center; }
  .kiosk-brand { flex-wrap: nowrap; min-width: 0; }
  /* the phone already shows date and time; drop the redundant chips */
  #date-chip, #time-chip { display: none; }
  .kiosk-title h1 { font-size: 19px; white-space: nowrap; }
  .kiosk-subtitle { font-size: 13px; margin: 2px 0 0 0; }
  .kiosk-logo { height: 24px; margin-right: 6px; }
  .kiosk-chips { flex-wrap: wrap; gap: 8px; }
  .chip { font-size: 13px; padding: 7px 13px; }

  .kiosk-scene {
    width: 100%;
    aspect-ratio: 1300 / 790;
    min-height: 0;
  }

  /* enlarge the callout cards so the live figures stay readable on a
     phone; each scales from an origin that keeps it inside the viewBox */
  .callout-body { transform-box: fill-box; }
  .cb-museum { transform-origin: 0% 50%; transform: scale(1.4); }
  /* solar: nudge right, clear of the trees; grid: move to the empty
     ground bottom-left so the pylon and wire stay visible */
  .cb-solar { transform-origin: 100% 40%; transform: translate(24px, -62px) scale(1.4); }
  .cb-grid { transform-origin: 50% 100%; transform: translate(-330px, 32px) scale(1.4); }

  /* staff login: plain link at the very bottom instead of a header pill */
  .chip-login { display: none; }
  .kiosk-foot {
    display: block;
    text-align: center;
    padding: 4px 0 24px;
    font-size: 14px;
  }
  .kiosk-foot a {
    color: var(--m-ink-muted);
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .col-left, .col-right { gap: 12px; }
  .col-left .m-card, .col-right .m-card { flex: none; }

  .m-card { padding: 14px 16px; border-radius: 14px; justify-content: flex-start; }
  .m-card-head h2 { font-size: 14px; }
  .m-ic { width: 34px; height: 34px; }
  .m-label { font-size: 13px; }
  .m-dir { font-size: 14px; margin: 4px 0 -2px; }
  .m-big { font-size: 34px; margin: 4px 0 0; }
  .m-foot { margin-top: 6px; }
  .m-foot-label { font-size: 12px; }
  .m-foot-value { font-size: 15px; }
  .m-spark { height: 44px; max-width: 50%; }
  .m-note { font-size: 13px; margin-top: 8px; }

  .status-ic { width: 40px; height: 40px; }

  .mix-wrap { gap: 16px; margin-top: 8px; }
  .donut { width: 96px; height: 96px; }
  .leg-row { font-size: 14px; margin: 5px 0; gap: 8px; }
  .leg-dot { width: 10px; height: 10px; }

  .chart-head { flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
  .chart-head h2 { font-size: 13px; }
  .chart-legend .leg { font-size: 13px; gap: 6px; }
  .chart-legend { gap: 12px; flex-wrap: wrap; }
  .leg::before { width: 10px; height: 10px; border-radius: 3px; }
  .chart-note { font-size: 13px; margin: 2px 0 8px; }
  .chart-body { min-height: 230px; }

  .kiosk-stale-banner { font-size: 13px; }

  .live-pill { gap: 6px; margin-left: 10px; padding: 5px 11px; font-size: 13px; }
  .live-pill .live-dot { width: 8px; height: 8px; }
  .m-card-head { gap: 9px; }
  .m-card-status { gap: 10px; }
  .status-title { font-size: 17px; margin-top: 2px; }
  .status-sub { font-size: 13px; }
}

/* =====================================================================
   Admin page (user management) - shares the login card look
   ===================================================================== */
.admin-shell { max-width: 560px; }

.login-label-gap { margin-top: 14px; }

.admin-back {
  color: var(--ink-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.admin-h2 {
  margin: 22px 0 10px;
  font-size: 13px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.admin-note { color: var(--ink-secondary); }

.user-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.user-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-subtle);
  font-size: 14px;
}
.user-row:last-child { border-bottom: none; }

.user-name { font-weight: 650; color: var(--ink-primary); }

.user-email {
  color: var(--ink-muted);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1 1 auto;
}

.user-role {
  font-size: 11.5px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  background: var(--surface-card-alt);
  border-radius: var(--radius-pill);
  padding: 3px 9px;
}
.user-role.is-admin {
  color: #7A5A00;
  background: var(--brand-yellow);
}

.user-actions {
  margin-left: auto;
  display: flex;
  gap: 6px;
}

.user-btn {
  font: inherit;
  font-size: 12.5px;
  color: var(--ink-secondary);
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  padding: 5px 11px;
  cursor: pointer;
}
.user-btn:hover { background: var(--surface-card-alt); }
.user-btn-danger { color: var(--warm-coral); border-color: rgba(255, 90, 91, 0.4); }

select.login-input { appearance: auto; }

.admin-link,
a.logout-button { text-decoration: none; display: inline-flex; align-items: center; }
