/* ==========================================================================
   Pi Lab Dashboard -- design tokens + layout + components
   ========================================================================== */

:root{
  --bg: #080b12;
  --bg-grad: radial-gradient(1200px 800px at 12% -10%, #0f1b2d 0%, #080b12 55%);
  --panel: #10161f;
  --panel-2: #0c1119;
  --panel-hover: #141c28;
  --inset: #060a10;
  --border: #1c2635;
  --border-2: #26344a;
  --text: #e6edf6;
  --text-dim: #94a4bb;
  --text-faint: #5c6d85;
  --accent: #22d3ee;
  --accent-2: #38bdf8;
  --green: #34d399;
  --amber: #fbbf24;
  --red: #f87171;
  --blue: #60a5fa;
  --purple: #a78bfa;
  --pink: #f472b6;
  --radius-lg: 16px;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 8px 30px rgba(0,0,0,.45);
  --shadow-sm: 0 2px 10px rgba(0,0,0,.3);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --header-h: 108px;

  /* -- component-scoped tokens: same literal values as the rules below use
        today, pulled out so the light theme can override them without
        touching dark rendering at all -- */
  --topbar-bg: rgba(8,11,18,.86);
  --tabhover-bg: rgba(255,255,255,.03);
  --rowhover-bg: rgba(255,255,255,.02);
  --selection-bg: rgba(34,211,238,.28);
  --focus-ring: rgba(34,211,238,.15);
  --modal-overlay-bg: rgba(4,6,10,.7);
  --chart-grid: rgba(255,255,255,.05);
  --chart-tooltip-body: #cfe3ff;
  --simbadge-border: rgba(251,191,36,.4);
  --simbadge-bg: rgba(251,191,36,.08);
  --runpill-grad-1: rgba(248,113,113,.14);
  --runpill-grad-2: rgba(248,113,113,.05);
  --runpill-border: rgba(248,113,113,.4);
  --runpill-text: #ffd7d7;
  --runpill-elapsed: #fff;
  --pill-live-border: rgba(52,211,153,.35);
  --pill-live-bg: rgba(52,211,153,.08);
  --pill-warm-border: rgba(251,191,36,.35);
  --pill-warm-bg: rgba(251,191,36,.08);
  --pill-rec-border: rgba(248,113,113,.4);
  --pill-rec-bg: rgba(248,113,113,.1);
  --rectoggle-checked-bg: rgba(248,113,113,.18);
  --btnwarn-bg: rgba(251,191,36,.12);
  --btnwarn-border: rgba(251,191,36,.4);
  --btnwarn-text: #ffe1a3;
  --banner-bg: rgba(251,191,36,.08);
  --banner-border: rgba(251,191,36,.3);
  --banner-text: #ffe1a3;
  --infonote-bg: rgba(96,165,250,.08);
  --infonote-border: rgba(96,165,250,.3);
  --infonote-text: #cfe3ff;
  --svc-failed-border: rgba(248,113,113,.35);
  --svc-failed-bg: rgba(248,113,113,.08);
  --danger-border: rgba(248,113,113,.35);
  --danger-bg: rgba(248,113,113,.05);
}

/* ==========================================================================
   Light theme -- overrides only. Applied via data-theme="light" on <html>,
   set by the inline head script (index.html) and static/app.js. Dark stays
   the default (:root above) so unset/legacy state renders unchanged.
   ========================================================================== */
:root[data-theme="light"]{
  --bg: #eef1f6;
  --bg-grad: radial-gradient(1200px 800px at 12% -10%, #ffffff 0%, #eef1f6 55%);
  --panel: #ffffff;
  --panel-2: #f4f6fa;
  --panel-hover: #e8ecf2;
  --inset: #eef1f6;
  --border: #dde3ec;
  --border-2: #c7d0de;
  --text: #101725;
  --text-dim: #48546a;
  --text-faint: #5b6678;
  --accent: #0e7490;
  --accent-2: #0369a1;
  --green: #047857;
  --amber: #b45309;
  --red: #b91c1c;
  --blue: #1d4ed8;
  --purple: #6d28d9;
  --pink: #be185d;
  --shadow: 0 8px 30px rgba(15,23,42,.12);
  --shadow-sm: 0 2px 10px rgba(15,23,42,.08);

  --topbar-bg: rgba(255,255,255,.86);
  --tabhover-bg: rgba(15,23,42,.045);
  --rowhover-bg: rgba(15,23,42,.03);
  --selection-bg: rgba(14,116,144,.22);
  --focus-ring: rgba(14,116,144,.18);
  --modal-overlay-bg: rgba(15,23,42,.45);
  --chart-grid: rgba(15,23,42,.08);
  --chart-tooltip-body: #1e3a5f;
  --simbadge-border: rgba(180,83,9,.45);
  --simbadge-bg: rgba(180,83,9,.12);
  --runpill-grad-1: rgba(185,28,28,.14);
  --runpill-grad-2: rgba(185,28,28,.05);
  --runpill-border: rgba(185,28,28,.4);
  --runpill-text: #7f1d1d;
  --runpill-elapsed: #450a0a;
  --pill-live-border: rgba(4,120,87,.35);
  --pill-live-bg: rgba(4,120,87,.1);
  --pill-warm-border: rgba(180,83,9,.35);
  --pill-warm-bg: rgba(180,83,9,.1);
  --pill-rec-border: rgba(185,28,28,.4);
  --pill-rec-bg: rgba(185,28,28,.12);
  --rectoggle-checked-bg: rgba(185,28,28,.16);
  --btnwarn-bg: rgba(180,83,9,.12);
  --btnwarn-border: rgba(180,83,9,.4);
  --btnwarn-text: #7c3a06;
  --banner-bg: rgba(180,83,9,.1);
  --banner-border: rgba(180,83,9,.35);
  --banner-text: #7c3a06;
  --infonote-bg: rgba(29,78,216,.08);
  --infonote-border: rgba(29,78,216,.3);
  --infonote-text: #1e3a8a;
  --svc-failed-border: rgba(185,28,28,.35);
  --svc-failed-bg: rgba(185,28,28,.1);
  --danger-border: rgba(185,28,28,.35);
  --danger-bg: rgba(185,28,28,.06);
}

*, *::before, *::after{ box-sizing: border-box; }
html, body{ height: 100%; }
body{
  margin:0;
  background: var(--bg-grad);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
a{ color: var(--accent-2); }
button, input, select{ font-family: inherit; color: inherit; }
::selection{ background: var(--selection-bg); }

.hidden{ display:none !important; }
.mono{ font-family: var(--mono); font-variant-numeric: tabular-nums; }
.muted{ color: var(--text-dim); }
.faint{ color: var(--text-faint); }

/* ---------------------------------------------------------------- header - */

.topbar{
  position: sticky; top:0; z-index: 40;
  background: var(--topbar-bg);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--border);
}
.topbar-row{
  display:flex; align-items:center; gap:16px;
  padding: 10px 18px 0;
  max-width: 1400px; margin: 0 auto;
}
.brand{
  display:flex; align-items:center; gap:9px;
  font-weight: 700; font-size: 16px; letter-spacing:.2px;
  white-space: nowrap;
  min-width: 0;                 /* let the subtitle ellipsis instead of shoving the clock */
}
.brand-text{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.brand-line{ display:flex; align-items:center; gap:9px; }
.brand-sub{
  font-weight: 500; font-size: 11px; letter-spacing: .01em;
  color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis;
}
.brand-dot{
  width:9px; height:9px; border-radius:50%;
  background: var(--green); box-shadow: 0 0 10px 1px currentColor;
  transition: background .25s, color .25s;
}
.brand-dot.bad{ background: var(--red); color: var(--red); }
.brand-dot.ok{ color: var(--green); }
.sim-badge{
  font-size: 10px; font-weight:700; letter-spacing:.06em;
  color: var(--amber); border:1px solid var(--simbadge-border);
  background: var(--simbadge-bg);
  border-radius: 999px; padding: 2px 7px;
}

/* -- node identity: which Pi am I looking at? --------------------------------
   --node-accent is injected per-machine in index.html from the hostname.
   The stripe is deliberately the loudest cue: it reads from across the room
   and from a glance at a background tab, without adding UI chrome. */
.node-badge{
  font-size: 10px; font-weight:700; letter-spacing:.06em;
  color: var(--node-accent);
  border: 1px solid color-mix(in srgb, var(--node-accent) 40%, transparent);
  background: color-mix(in srgb, var(--node-accent) 10%, transparent);
  border-radius: 999px; padding: 2px 7px;
}
.node-stripe{
  height: 3px; width: 100%;
  background: linear-gradient(90deg,
    var(--node-accent) 0%,
    color-mix(in srgb, var(--node-accent) 35%, transparent) 60%,
    transparent 100%);
}

.header-spacer{ flex: 1 1 auto; }

.clock{
  font-family: var(--mono); font-size: 13px; color: var(--text-dim);
  white-space: nowrap;
}

.theme-toggle{
  appearance:none; cursor:pointer; border-radius: 999px;
  width:44px; height:44px; min-width:44px; min-height:44px; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
  background: var(--panel-hover); border:1px solid var(--border-2); color: var(--text-dim);
  transition: background .15s, border-color .15s, color .15s, transform .08s;
}
.theme-toggle:hover{ color: var(--text); border-color: var(--accent); }
.theme-toggle:active{ transform: scale(.92); }
.theme-toggle svg{ width:18px; height:18px; display:block; }
.theme-toggle .icon-moon{ display:none; }
:root[data-theme="light"] .theme-toggle .icon-sun{ display:none; }
:root[data-theme="light"] .theme-toggle .icon-moon{ display:block; }

.run-pill{
  display:flex; align-items:center; gap:8px;
  background: linear-gradient(180deg, var(--runpill-grad-1), var(--runpill-grad-2));
  border:1px solid var(--runpill-border);
  color: var(--runpill-text);
  border-radius: 999px; padding: 5px 12px 5px 10px;
  font-size: 12.5px; font-weight:600; white-space: nowrap;
}
.run-pill .led{ width:7px; height:7px; border-radius:50%; background:var(--red); animation: pulse 1.4s infinite; }
.run-pill .elapsed{ font-family: var(--mono); color:var(--runpill-elapsed); }

@keyframes pulse{
  0%,100%{ opacity:1; transform: scale(1); }
  50%{ opacity:.35; transform: scale(.75); }
}

.tabs{
  display:flex; gap:2px; margin-top:10px;
  overflow-x:auto; scrollbar-width:none;
  max-width: 1400px; padding: 0 18px;
  margin-left:auto; margin-right:auto;
}
.tabs::-webkit-scrollbar{ display:none; }
.tab-btn{
  appearance:none; border:none; background:transparent; cursor:pointer;
  color: var(--text-dim); font-size: 13.5px; font-weight: 600;
  padding: 10px 16px; border-radius: 10px 10px 0 0;
  white-space: nowrap; position:relative;
  transition: color .15s, background .15s;
  min-height: 40px;
}
.tab-btn:hover{ color: var(--text); background: var(--tabhover-bg); }
.tab-btn.active{ color: var(--accent); }
.tab-btn.active::after{
  content:""; position:absolute; left:10px; right:10px; bottom:-1px; height:2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 2px;
}

/* ---------------------------------------------------------------- layout - */

.page{
  max-width: 1400px; margin: 0 auto; padding: 20px 18px 64px;
}
.tab-panel{ display:none; }
.tab-panel.active{ display:block; animation: fadein .18s ease; }
@keyframes fadein{ from{ opacity:0; transform: translateY(4px); } to{ opacity:1; transform:none; } }

.section-title{
  font-size: 13px; font-weight:700; text-transform:uppercase; letter-spacing:.08em;
  color: var(--text-dim); margin: 26px 0 10px;
}
.section-title:first-child{ margin-top:0; }

.panel{
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  border:1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.panel-pad{ padding: 16px 18px; }

/* ---------------------------------------------------------------- tiles -- */

.tile-grid{
  display:grid; gap:12px;
  /* 240px, not 220: tile headlines are full maker+model ("GSS SprintIR-WF-100
     #1"), and at 220 five of them wrapped onto a second line -- breaking mid
     token at the model's hyphens. 240 fits every current name on one line for
     the cost of one column; wider buys nothing. */
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.tile{
  background: linear-gradient(165deg, var(--panel), var(--panel-2));
  border:1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  display:flex; flex-direction:column; gap:8px;
  position:relative; overflow:hidden;
  transition: border-color .2s, transform .2s;
}
.tile::before{
  content:""; position:absolute; inset:0 0 auto 0; height:3px;
  background: var(--tile-color, var(--accent));
  opacity:.85;
}
.tile.offline{ opacity:.55; }
.tile-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:8px; }
.tile-name{ font-weight:700; font-size:13.5px; }
.tile-sub{ font-size:11px; color: var(--text-faint); margin-top:1px; }
.tile-value{
  font-family: var(--mono); font-size: 30px; font-weight:600; line-height:1.1;
  display:flex; align-items:baseline; gap:6px; margin-top:2px;
}
.tile-value .unit{ font-size:14px; color: var(--text-dim); font-weight:500; }
.tile-meta{ display:flex; flex-wrap:wrap; gap:6px 14px; font-size:11.5px; color:var(--text-dim); }
.tile-meta b{ color: var(--text); font-weight:600; }
.tile-foot{ display:flex; align-items:center; justify-content:space-between; margin-top:auto; padding-top:6px; }

.status-pill{
  display:inline-flex; align-items:center; gap:5px;
  font-size: 10.5px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding: 3px 8px; border-radius: 999px;
  border:1px solid var(--border-2); color: var(--text-dim);
}
.status-pill .led{ width:6px; height:6px; border-radius:50%; background: currentColor; }
.status-pill.offline{ color: var(--text-faint); }
.status-pill.live{ color: var(--green); border-color: var(--pill-live-border); background: var(--pill-live-bg); }
.status-pill.warm{ color: var(--amber); border-color: var(--pill-warm-border); background: var(--pill-warm-bg); }
.status-pill.warm .led{ animation: pulse 1.2s infinite; }
.status-pill.rec{ color: var(--red); border-color: var(--pill-rec-border); background: var(--pill-rec-bg); }
.status-pill.rec .led{ animation: pulse 1s infinite; }

.rec-toggle{
  display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  font-size: 11px; font-weight:700; letter-spacing:.05em; color: var(--text-dim);
  user-select:none; min-height:28px;
}
.rec-toggle input{ position:absolute; opacity:0; width:1px; height:1px; }
.rec-toggle .sw{
  width:30px; height:18px; border-radius:999px; background: var(--inset);
  border:1px solid var(--border-2); position:relative; transition: background .15s, border-color .15s;
}
.rec-toggle .sw::after{
  content:""; position:absolute; top:1px; left:1px; width:14px; height:14px; border-radius:50%;
  background: var(--text-faint); transition: transform .15s, background .15s;
}
.rec-toggle input:checked + .sw{ background: var(--rectoggle-checked-bg); border-color: var(--red); }
.rec-toggle input:checked + .sw::after{ transform: translateX(12px); background: var(--red); }
.rec-toggle input:disabled + .sw{ opacity:.5; }
.rec-toggle.on{ color: var(--red); }

/* ---------------------------------------------------------------- forms -- */

.field{ display:flex; flex-direction:column; gap:5px; }
.field label{ font-size: 10.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color: var(--text-faint); }
input[type=text], input[type=number], input[type=password], select, textarea{
  background: var(--inset); border:1px solid var(--border-2); color: var(--text);
  border-radius: var(--radius-sm); padding: 9px 10px; font-size: 13.5px;
  min-height: 40px; outline:none; transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus{ border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
input::placeholder{ color: var(--text-faint); }
select{ cursor:pointer; }

.btn{
  appearance:none; border:none; cursor:pointer; border-radius: var(--radius-sm);
  padding: 10px 16px; font-size: 13.5px; font-weight:700; letter-spacing:.02em;
  min-height: 44px; display:inline-flex; align-items:center; justify-content:center; gap:7px;
  background: var(--panel-hover); color: var(--text); border:1px solid var(--border-2);
  transition: transform .08s ease, filter .15s, background .15s, border-color .15s, opacity .15s;
}
.btn:hover:not(:disabled){ filter:brightness(1.12); }
.btn:active:not(:disabled){ transform: scale(.97); }
.btn:disabled{ opacity:.4; cursor:not-allowed; }
.btn.primary{ background: linear-gradient(180deg, #2dd9f0, #14b8d6); color:#04222a; border-color: transparent; }
.btn.success{ background: linear-gradient(180deg, #3fe0ac, #1fae7f); color:#04231a; border-color: transparent; }
.btn.danger{ background: linear-gradient(180deg, #fb8a8a, #ef4444); color:#2a0505; border-color: transparent; }
.btn.ghost{ background: transparent; }
.btn.small{ min-height:34px; padding:6px 12px; font-size:12px; }
.btn.block{ width:100%; }
.btn.warn{ background: var(--btnwarn-bg); border-color: var(--btnwarn-border); color:var(--btnwarn-text); }

.chip-row{ display:flex; flex-wrap:wrap; gap:8px; }
.chip{
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid var(--border-2); border-radius: 999px; padding: 7px 13px;
  font-size: 12.5px; font-weight:600; color: var(--text-dim); background: var(--inset);
  cursor:pointer; user-select:none; min-height:34px; transition: all .15s;
}
/* duration chip with an inline minutes field -- clicking the input selects the
   chip, so it behaves like the fixed-duration chips beside it */
.chip-custom{ gap:4px; padding-left:9px; }
.chip-custom input{
  width: 52px; background: transparent; border: none; outline: none;
  color: inherit; font: inherit; font-weight: 700; text-align: right;
  -moz-appearance: textfield;
}
.chip-custom input::-webkit-outer-spin-button,
.chip-custom input::-webkit-inner-spin-button{ -webkit-appearance: none; margin: 0; }
.chip-custom input::placeholder{ color: var(--text-dim); opacity:.55; font-weight:600; }
/* the scheduled-start picker is a datetime-local: it needs room for a whole
   date + time, and it is left-aligned because it reads as text, not a number */
.chip-custom input[type="datetime-local"]{ width: auto; min-width: 172px; text-align: left; }
/* the picker glyph is a dark bitmap: invert it on the dark chip, leave it alone
   on the light theme and on the ACTIVE chip (whose fill is light) */
.chip-custom input[type="datetime-local"]::-webkit-calendar-picker-indicator{
  filter: invert(.7); cursor: pointer;
}
html[data-theme="light"] .chip-custom input[type="datetime-local"]::-webkit-calendar-picker-indicator,
.chip.active input[type="datetime-local"]::-webkit-calendar-picker-indicator{ filter:none; }
.chip.active{ color: var(--bg); background: var(--accent); border-color: var(--accent); }
.chip.toggle-off{ opacity:.45; text-decoration: line-through; }
.chip .swatch{ width:9px; height:9px; border-radius:50%; background: currentColor; }

/* --------------------------------------------------------------- run bar - */

.run-bar{ display:flex; flex-wrap:wrap; gap:16px; align-items:flex-end; }
.run-bar .field{ min-width: 120px; }
.run-bar .grow{ flex:1 1 220px; }
.duration-group{ display:flex; gap:6px; flex-wrap:wrap; }
.run-actions{ display:flex; gap:10px; margin-left:auto; }
.run-status{
  margin-top:14px; padding-top:14px; border-top:1px solid var(--border);
  display:flex; flex-wrap:wrap; gap:18px; font-size:12.5px; color:var(--text-dim);
}
.run-status b{ color:var(--text); font-family: var(--mono); }

.pump-bar{ display:flex; flex-wrap:wrap; gap:16px; align-items:center; justify-content:space-between; }
.pump-actions{ display:flex; gap:10px; }
@media (max-width: 640px){
  .pump-actions{ width:100%; }
  .pump-actions .btn{ flex:1; }
}
.run-status .files{ display:flex; flex-wrap:wrap; gap:8px; }
.run-status .file-chip{
  font-family: var(--mono); font-size:11px; background: var(--inset);
  border:1px solid var(--border-2); border-radius:6px; padding:3px 8px; color: var(--text-dim);
}
/* --- scheduled runs: the preview under the bar, and the armed banner ------ */
.sched-preview{
  margin-top:12px; padding:10px 12px; font-size:12.5px; color: var(--text-dim);
  background: var(--inset); border:1px solid var(--border-2); border-radius: var(--radius-sm);
  display:flex; flex-direction:column; gap:4px;
}
.sched-preview b{ color: var(--text); font-family: var(--mono); }
.sched-armed{
  margin-top:12px; padding:10px 12px; font-size:12.5px; color: var(--text-dim);
  border-radius: var(--radius-sm);
  display:flex; align-items:center; flex-wrap:wrap; gap:12px;
}
/* armed = something is going to happen; done = how the last one turned out */
.sched-armed.armed{ background: var(--pill-warm-bg); border:1px solid var(--pill-warm-border); }
.sched-armed.done{ background: var(--inset); border:1px solid var(--border-2); }
.sched-armed .grow{ flex:1 1 260px; display:flex; flex-direction:column; gap:3px; }
.sched-armed b{ color: var(--text); font-family: var(--mono); }
.warn-text{ color: var(--amber); }
.status-pill.bad{ color: var(--red); border-color: var(--pill-rec-border); background: var(--pill-rec-bg); }
/* armed-but-not-recording: same header pill, amber and steady rather than a
   pulsing red REC dot -- nothing is being written yet */
.run-pill.armed{ border-color: var(--pill-warm-border); }
.run-pill.armed .led{ background: var(--amber); animation:none; }

.progress{
  height:6px; border-radius:999px; background: var(--inset); overflow:hidden; margin-top:8px;
  border:1px solid var(--border-2);
}
.progress > i{ display:block; height:100%; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width .3s; }

/* ---------------------------------------------------------------- pi strip */

.pi-strip{ display:grid; gap:10px; grid-template-columns: repeat(auto-fill, minmax(150px,1fr)); }
.pi-stat{ display:flex; flex-direction:column; gap:3px; }
.pi-stat .k{ font-size:10.5px; text-transform:uppercase; letter-spacing:.06em; color: var(--text-faint); }
.pi-stat .v{ font-size:14px; font-weight:600; font-family: var(--mono); }
.pi-note{
  margin-top:12px; font-size:12px; color: var(--text-faint); border-top:1px solid var(--border);
  padding-top:10px;
}
.banner{
  display:flex; align-items:center; gap:10px;
  background: var(--banner-bg); border:1px solid var(--banner-border);
  color:var(--banner-text); border-radius: var(--radius-sm); padding: 10px 14px; font-size:12.5px;
  margin-bottom:14px;
}

/* --------------------------------------------------------------- charts -- */

.chart-toolbar{
  display:flex; flex-wrap:wrap; gap:10px 16px; align-items:center; margin-bottom:12px;
}
.chart-toolbar .grow{ flex:1 1 auto; }
.chart-wrap{ position:relative; height: 360px; }
.chart-wrap canvas{ width:100% !important; height:100% !important; }
.chart-hint{ font-size:11px; color: var(--text-faint); margin-top:8px; text-align:right; }
.hint{ font-size:11.5px; color: var(--text-faint); line-height:1.5; max-width:70ch; }
.legend-row{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }

.info-note{
  display:flex; gap:10px; align-items:flex-start;
  background: var(--infonote-bg); border:1px solid var(--infonote-border);
  border-radius: var(--radius-sm); padding: 12px 14px; font-size:12.5px; color:var(--infonote-text);
  margin-bottom:16px;
}
.info-note .ic{ font-size:16px; line-height:1; }

/* Info notes are reference material, not something to re-read every visit, so
   they collapse to just the (i) badge and expand on click. */
.info-note{ cursor:pointer; transition: padding .12s; }
.info-note:hover{ border-color: var(--border-2); }
.info-note.collapsed{
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px; padding:0; margin-bottom:12px; border-radius:999px;
}
.info-note.collapsed > *:not(.ic){ display:none; }
.info-note.collapsed .ic{ font-size:14px; }

.reading-hero{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
.reading-hero .num{ font-family: var(--mono); font-size:44px; font-weight:700; }
.reading-hero .u{ font-size:16px; color: var(--text-dim); }

/* ------------------------------------------------------------- cal panel - */

.cal-grid{ display:grid; gap:10px; grid-template-columns: repeat(auto-fill, minmax(170px,1fr)); align-items:end; }
.cal-log{
  margin-top:12px; background: var(--inset); border:1px solid var(--border-2); border-radius: var(--radius-sm);
  padding: 10px 12px; font-family: var(--mono); font-size:11.5px; color: var(--text-dim);
  max-height: 160px; overflow:auto; white-space:pre-wrap;
}
.run-disabled-note{ font-size:12px; color: var(--amber); margin-top:8px; }

/* --------------------------------------------------------------- tables -- */

.table-wrap{ overflow-x:auto; }
table.data-table{ width:100%; border-collapse: collapse; font-size:13px; }
table.data-table th{
  text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.05em;
  color: var(--text-faint); padding: 8px 10px; border-bottom:1px solid var(--border);
  white-space:nowrap;
}
table.data-table td{ padding: 9px 10px; border-bottom:1px solid var(--border); vertical-align:middle; white-space:nowrap; }
table.data-table tr:hover td{ background: var(--rowhover-bg); }
table.data-table .actions{ display:flex; gap:6px; }
.empty-row{ color: var(--text-faint); padding: 20px 10px; text-align:center; }

/* ------------------------------------------------------- files browser -- */
.crumbs{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; font-size:13px; min-height:26px; }
.crumbs span{ color: var(--text); }
.crumb-sep{ color: var(--text-faint); }
a.file-link{ color: var(--accent-2); text-decoration:none; }
a.file-link:hover{ text-decoration:underline; }

/* ------------------------------------------------- hardware reference -- */
/* Static spec tables (Hardware tab). Unlike the live data tables these carry
   prose, so cells wrap instead of forcing the whole table to scroll. */
table.ref-table td{ white-space: normal; vertical-align: top; line-height:1.45; }
table.ref-table td:last-child{ white-space: nowrap; }
.ref-name{ font-weight:700; }
.ref-sub{ color: var(--text-faint); font-size:11.5px; margin-top:3px; line-height:1.4; }
.ref-path{ font-family: var(--mono); font-size:11.5px; color: var(--text-dim); }

.status{
  display:inline-block; padding:2px 8px; border-radius:999px;
  font-size:10.5px; font-weight:700; letter-spacing:.02em;
  border:1px solid currentColor; white-space:nowrap;
}
.status-live{ color: var(--green); }
.status-ready{ color: var(--blue); }
.status-pending{ color: var(--amber); }
.status-parked{ color: var(--text-faint); }

/* ------------------------------------------------------------- doc list -- */

.doc-list{ display:flex; flex-direction:column; gap:6px; }
.doc-item{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding: 9px 12px; background: var(--inset); border:1px solid var(--border-2); border-radius: var(--radius-sm);
}
.doc-item .name{ font-size:13px; font-weight:600; }
.doc-item .size{ font-size:11px; color: var(--text-faint); }

/* -------------------------------------------------------------- 2-col ---- */

.grid-2{ display:grid; gap:16px; grid-template-columns: 1fr 1fr; align-items:start; }
@media (max-width: 900px){ .grid-2{ grid-template-columns: 1fr; } }
/* the affiliation line is the first thing to go when width gets tight -- it is
   context, not state, and the node badge still says which Pi this is */
@media (max-width: 900px){ .brand-sub{ display:none; } }

/* ------------------------------------------------------------- devices -- */

.device-block{ border:1px solid var(--border); border-radius: var(--radius); padding:14px 16px; margin-bottom:12px; }
.device-block .dh{ display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:10px; }
.device-block .dh-title{ display:flex; align-items:center; gap:8px; font-weight:700; font-size:14px; }
.device-block .dh-title .swatch{ width:10px; height:10px; border-radius:3px; }

/* ------------------------------------------------------------- system --- */

.svc-row{
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;
  padding: 10px 4px; border-bottom:1px solid var(--border);
}
.svc-row:last-child{ border-bottom:none; }
.svc-name{ font-weight:600; font-size:13px; }
.svc-desc{ font-size:11.5px; color: var(--text-faint); }
.svc-state{
  font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
  padding:3px 9px; border-radius:999px; border:1px solid var(--border-2); color:var(--text-dim);
}
.svc-state.active{ color: var(--green); border-color: var(--pill-live-border); background: var(--pill-live-bg); }
.svc-state.failed{ color: var(--red); border-color: var(--svc-failed-border); background: var(--svc-failed-bg); }
.svc-actions{ display:flex; gap:8px; }

.log-viewer{
  background: var(--inset); border:1px solid var(--border-2); border-radius: var(--radius-sm);
  padding:12px; font-family: var(--mono); font-size:11.5px; color: var(--text-dim);
  max-height: 340px; overflow:auto; white-space:pre-wrap; margin-top:10px;
}

.wifi-row{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:9px 4px; border-bottom:1px solid var(--border); flex-wrap:wrap; }
.wifi-row:last-child{ border-bottom:none; }
.wifi-ssid{ font-weight:600; font-size:13px; display:flex; align-items:center; gap:8px; }
.signal-bars{ display:inline-flex; align-items:flex-end; gap:2px; height:12px; }
.signal-bars i{ width:3px; background: var(--text-faint); border-radius:1px; }
.signal-bars i.on{ background: var(--accent); }
/* saved but not currently audible -- still one click away (e.g. Lab04 from the Pi 5) */
.wifi-row.out-of-range .wifi-ssid{ color: var(--text-dim); }
.wifi-row.out-of-range .signal-bars{ opacity:.35; }
/* "saved" = the Pi already holds this network's password, so Connect needs no typing */
.wifi-saved{
  font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:2px 6px; border-radius:999px; color: var(--green);
  border:1px solid var(--pill-live-border); background: var(--pill-live-bg);
}

.danger-zone{ border:1px solid var(--danger-border); background: var(--danger-bg); border-radius: var(--radius-lg); padding:16px 18px; }
.danger-zone .section-title{ color: var(--red); margin-top:0; }
.danger-row{ display:flex; flex-wrap:wrap; gap:12px; align-items:flex-end; }

.toast-stack{
  position: fixed; right:16px; bottom:16px; z-index:100;
  display:flex; flex-direction:column; gap:8px; max-width: 360px;
}
.toast{
  background: var(--panel); border:1px solid var(--border-2); border-left:4px solid var(--accent);
  border-radius: var(--radius-sm); padding: 11px 14px; font-size:13px; box-shadow: var(--shadow);
  animation: toastin .18s ease;
}
.toast.error{ border-left-color: var(--red); }
.toast.success{ border-left-color: var(--green); }
@keyframes toastin{ from{ opacity:0; transform: translateY(8px); } to{ opacity:1; transform:none; } }

.footer-note{ margin-top:40px; text-align:center; color: var(--text-faint); font-size:11.5px; }

/* --------------------------------------------------------------- modal --- */

.modal-overlay{
  position: fixed; inset:0; background: var(--modal-overlay-bg); backdrop-filter: blur(3px);
  display:flex; align-items:center; justify-content:center; z-index:80; padding:20px;
}
.modal{
  background: var(--panel); border:1px solid var(--border-2); border-radius: var(--radius-lg);
  max-width: 900px; width:100%; max-height: 86vh; overflow:auto; box-shadow: var(--shadow);
  padding: 20px 22px;
}
.modal-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:14px; }
.modal-head h3{ margin:0; font-size:16px; }

/* ==========================================================================
   ARCHITECTURE tab -- the system map. Built from HTML boxes rather than an
   SVG drawing so it reflows on a phone, inherits both themes from the tokens
   above, and can be lit up live by adding a class from the poll.
   ========================================================================== */

.arch-lead{ margin:0; font-size:15px; }
.arch-lead b{ color: var(--text); }

/* -- the four rules -- */
.arch-rules{ display:grid; grid-template-columns: repeat(auto-fit, minmax(300px,1fr)); gap:12px; }
.arch-rule{
  display:flex; gap:12px; padding:14px 16px;
  background: var(--panel); border:1px solid var(--border); border-radius: var(--radius);
}
.arch-rule-n{
  flex:0 0 26px; height:26px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-family: var(--mono); font-size:12px; font-weight:700;
  color: var(--accent); background: var(--pill-live-bg); border:1px solid var(--border-2);
}
.arch-rule-t{ font-weight:700; font-size:13.5px; margin-bottom:4px; }
.arch-rule-b{ font-size:13px; color: var(--text-dim); }

/* -- chains of boxes (hardware lanes + the recording branch) -- */
.arch-scroll{ overflow-x:auto; padding-bottom:4px; }
.arch-scroll::-webkit-scrollbar{ height:6px; }
.arch-scroll::-webkit-scrollbar-thumb{ background: var(--border-2); border-radius:3px; }

.arch-lane{ margin-bottom:14px; }
.arch-lane:last-child{ margin-bottom:0; }
.arch-lane-h{
  font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color: var(--text-faint); margin-bottom:6px;
}
.arch-chain{ display:flex; align-items:stretch; gap:6px; min-width:max-content; }
.arch-chain-wrap{ flex-wrap:wrap; min-width:0; }

.arch-box{
  flex:0 0 auto; min-width:132px; max-width:230px; padding:9px 12px;
  background: var(--panel-2); border:1px solid var(--border); border-radius: var(--radius-sm);
}
.arch-box-t{ font-size:12.5px; font-weight:650; line-height:1.3; }
.arch-box-s{ font-size:11px; color: var(--text-faint); margin-top:2px; line-height:1.35; }
.arch-box-f{ font-size:10.5px; color: var(--text-faint); margin-top:5px; }
.arch-box-f code, .arch-box-s code{ font-size:10.5px; }
.arch-box-tag{
  display:inline-block; font-size:9.5px; font-weight:800; letter-spacing:.09em;
  color: var(--red); margin-bottom:3px;
}
.arch-box-skip{ border-style:dashed; }
.arch-box-end{ border-color: var(--border-2); background: var(--panel); }
.arch-crit{ border-color: var(--danger-border); background: var(--danger-bg); max-width:280px; }

/* live states, applied by app.js */
.arch-box.live{ border-color: var(--pill-live-border); background: var(--pill-live-bg); }
.arch-box.live .arch-box-t{ color: var(--green); }
.arch-box.warn{ border-color: var(--pill-warm-border); background: var(--pill-warm-bg); }
.arch-box.warn .arch-box-t{ color: var(--amber); }
.arch-box.bad{ border-color: var(--danger-border); background: var(--danger-bg); }
.arch-box.bad .arch-box-t{ color: var(--red); }
.arch-box.off{ opacity:.6; }

.arch-arrow{
  align-self:center; color: var(--text-faint); font-size:15px; flex:0 0 auto; user-select:none;
}

/* -- power callout -- */
.arch-power{ margin-top:18px; padding-top:16px; border-top:1px solid var(--border); }
.arch-power-h{
  font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color: var(--text-faint); margin-bottom:8px;
}

/* -- the vertical software stack -- */
.arch-stack{ display:flex; flex-direction:column; }
.arch-layer{
  display:grid; grid-template-columns: 120px 1fr auto; gap:14px; align-items:start;
  padding:13px 15px; background: var(--panel-2);
  border:1px solid var(--border); border-radius: var(--radius);
}
.arch-layer-k{
  font-size:10.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase;
  color: var(--accent); padding-top:2px;
}
.arch-layer-t{ font-weight:700; font-size:13.5px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.arch-layer-d{ font-size:13px; color: var(--text-dim); margin-top:3px; }
.arch-layer-f{ font-size:11px; color: var(--text-faint); text-align:right; padding-top:3px; white-space:nowrap; }
.arch-layer-open{ background: var(--panel); }

.arch-vsep{
  display:flex; align-items:center; gap:10px; padding:5px 0 5px 60px;
  font-size:11px; color: var(--text-faint);
}
.arch-vsep::before{
  content:"↓"; font-size:14px; color: var(--border-2); flex:0 0 auto;
}
.arch-vsep code{ font-size:10.5px; }

/* live pill next to a layer title */
.arch-live{
  display:inline-flex; align-items:center; gap:5px; padding:2px 8px; border-radius:999px;
  font-size:10.5px; font-weight:700; letter-spacing:.03em;
  border:1px solid var(--border-2); color: var(--text-faint);
}
.arch-live::before{ content:""; width:6px; height:6px; border-radius:50%; background: currentColor; }
.arch-live.ok{ color: var(--green); border-color: var(--pill-live-border); background: var(--pill-live-bg); }
.arch-live.warn{ color: var(--amber); border-color: var(--pill-warm-border); background: var(--pill-warm-bg); }
.arch-live.bad{ color: var(--red); border-color: var(--danger-border); background: var(--danger-bg); }

/* -- driver chips inside the drivers layer -- */
.arch-drivers{ display:grid; grid-template-columns: repeat(auto-fit, minmax(190px,1fr)); gap:8px; margin-top:10px; }
.arch-driver{
  padding:8px 10px; border:1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--panel-2);
}
.arch-driver.live{ border-color: var(--pill-live-border); background: var(--pill-live-bg); }
.arch-driver.off{ opacity:.62; }
.arch-driver-t{ display:flex; align-items:center; gap:6px; font-size:12.5px; font-weight:700; }
.arch-driver-t .dot{ width:7px; height:7px; border-radius:50%; background: var(--text-faint); flex:0 0 auto; }
.arch-driver.live .arch-driver-t .dot{ background: var(--green); }
.arch-driver-s{ font-size:11px; color: var(--text-dim); margin-top:3px; }
.arch-driver-p{ font-size:10.5px; color: var(--text-faint); margin-top:2px; font-family: var(--mono); }

/* -- arbiter claims -- */
.arch-claims{ display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.arch-claim{
  display:inline-flex; align-items:baseline; gap:6px; padding:4px 9px;
  border:1px solid var(--border); border-radius:999px; background: var(--panel-2); font-size:11px;
}
.arch-claim .p{ font-family: var(--mono); color: var(--text); }
.arch-claim .k{ color: var(--text-faint); }
.arch-claim.taken{ border-color: var(--pill-live-border); background: var(--pill-live-bg); }
.arch-claim.taken .k{ color: var(--green); font-weight:700; }
.arch-claim.free{ border-color: var(--pill-warm-border); background: var(--pill-warm-bg); }
.arch-claim.free .k{ color: var(--amber); }

/* -- small key/value strips -- */
.arch-kv{ display:flex; flex-wrap:wrap; gap:6px 18px; margin-top:9px; font-size:11.5px; color: var(--text-dim); }
.arch-kv-wide{ margin-top:14px; }
.arch-kv b{ color: var(--text); font-weight:650; font-family: var(--mono); }

.arch-branch-h{
  font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color: var(--text-faint); margin:22px 0 8px; padding-top:16px; border-top:1px solid var(--border);
}

/* -- copyable commands -- */
.arch-cmds{ display:flex; flex-direction:column; gap:6px; }
.arch-cmd{
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
  padding:9px 12px; background: var(--inset); border:1px solid var(--border);
  border-radius: var(--radius-sm); cursor:pointer; transition: border-color .12s, background .12s;
}
.arch-cmd:hover{ border-color: var(--accent); background: var(--panel-hover); }
.arch-cmd:active{ transform: scale(.995); }
.arch-cmd code{
  font-family: var(--mono); font-size:12px; color: var(--accent-2); white-space:pre-wrap;
  word-break:break-all;
}
.arch-cmd-d{ font-size:11.5px; color: var(--text-faint); margin-left:auto; text-align:right; }
.arch-cmd.copied{ border-color: var(--green); }
.arch-cmd.copied .arch-cmd-d::after{ content:" — copied"; color: var(--green); font-weight:700; }

/* -------------------------------------------------------------- mobile --- */

@media (max-width: 640px){
  :root{ font-size: 14px; }
  .topbar-row{ padding: 10px 12px 0; flex-wrap:wrap; }
  .clock{ order:3; }
  .theme-toggle{ order:4; }
  .tabs{ padding: 0 8px; }
  .page{ padding: 14px 10px 48px; }
  .tile-grid{ grid-template-columns: repeat(auto-fill, minmax(150px,1fr)); }
  .tile-value{ font-size:24px; }
  .run-actions{ margin-left:0; width:100%; }
  .run-actions .btn{ flex:1; }
  .reading-hero .num{ font-size:34px; }
  .chart-wrap{ height: 280px; }
  .brand span.full{ display:none; }

  /* the software stack collapses from 3 columns to a single flow; the
     hardware chains keep their width and scroll inside .arch-scroll */
  .arch-layer{ grid-template-columns: 1fr; gap:4px; }
  .arch-layer-f{ text-align:left; white-space:normal; }
  .arch-vsep{ padding-left:14px; }
  .arch-cmd-d{ margin-left:0; text-align:left; flex-basis:100%; }
  .arch-rules{ grid-template-columns: 1fr; }
}
