/* ==============================================================================================
   HYDROS LIVE — the HUD skin
   ==============================================================================================

   Steve, 13 Sep 2026: "i want the entire HYDROS Live graphic design to be upgraded to the ultra
   high tech, futuristic, tony stark computer game, animated graphics, do the entire thing in a
   similar style, entirely in the graphics used for the tutorial, across the board for all and
   everything hydros live."

   "The graphics used for the tutorial" is the language in public/tutorial.js: glass over a dark
   field, a cyan hairline along the lit edge, scanlines, four corner brackets, mono uppercase
   micro-labels, readouts that glow, and motion that means something.

   WHAT THIS FILE IS. Paint. It loads AFTER styles.css and every rule is scoped to #panel-hydros
   or .hy-scrim (the pop-ups mount on <body>, outside the panel). It changes no markup, no
   geometry that matters, and no behaviour. Delete the one <link> and HYDROS Live is exactly as it
   was — the 7 Sep "control room" block in styles.css underneath it is untouched and still works
   on its own.

   THE RULE THAT DECIDES EVERYTHING. This screen is how an operator finds out whether a plant is
   running. A number, an alarm, a device state must come out of this LOUDER than it went in.
   Anything decorative gets out of their way: the brackets and scanlines sit on panels, never over
   values; the sweeps are slow and dim; the only fast, bright, attention-taking motion in the whole
   file is on a critical alarm, because that is the one thing that should take attention.

   TEN SECONDS. Six of the eleven tabs replace #hy-tab-body wholesale on a ten-second timer
   (hydros.js renderTab). Any animation on an element inside it RESTARTS then. So: nothing inside
   the tab body animates for longer than ~2.5s, and the one-off "boot" is gated behind a real tab
   change by hydros-hud.js. Long, slow motion lives on the panel itself, the tab bar and the site
   header, which survive a refresh.
   ============================================================================================ */

#panel-hydros, .hy-scrim {
  /* The tutorial's own values, so the two read as one system. */
  --hud: #36d1ff;
  --hud-bright: #7ae2ff;
  --hud-dim: rgba(54, 209, 255, .38);
  --hud-soft: rgba(54, 209, 255, .10);
  --hud-line: rgba(54, 209, 255, .22);
  --hud-mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
  --hud-bracket: 13px;     /* arm length of a corner bracket */
  --hud-glass-a: rgba(19, 29, 43, .94);
  --hud-glass-b: rgba(11, 18, 28, .94);
  /* A deeper field than the 7 Sep skin: the brackets and hairlines need somewhere dark to sit. */
  --paper: #05090f;
  --surface: #0e1620;
  --surface-2: #141d2a;
  --line: #22344a;
  --ink: #eaf6fe;
  --hud-digit: #f2fbff;  /* the brightest thing on the screen, and the only thing that is */
  --ink-dim: #9db6cd;    /* lifted from the 7 Sep #86a0b8: 6.7:1 to 8.7:1 on this ground, which is
                            what a label has to survive on a phone held outdoors */
}

/* ---------------------------------------------------------------------------------------------
   THE FIELD. A deep well with a horizon glow, a 44px survey grid, and a very slow vertical drift
   so the screen is never quite still. The drift is on the PANEL, which no refresh replaces.
   --------------------------------------------------------------------------------------------- */
#panel-hydros {
  position: relative;
  background:
    radial-gradient(1400px 700px at 50% -14%, rgba(54, 209, 255, .13), transparent 70%),
    radial-gradient(900px 500px at 88% 8%, rgba(0, 214, 160, .05), transparent 70%),
    linear-gradient(rgba(54, 209, 255, .030) 1px, transparent 1px) 0 0 / 100% 44px,
    linear-gradient(90deg, rgba(54, 209, 255, .030) 1px, transparent 1px) 0 0 / 44px 100%,
    var(--paper);
  animation: hudField 24s linear infinite;
}
@keyframes hudField {
  from { background-position: 50% -14%, 88% 8%, 0 0, 0 0, 0 0; }
  to   { background-position: 50% -14%, 88% 8%, 0 44px, 44px 0, 0 0; }
}

/* Vignette and a single slow scan bar down the whole module — the one full-height motion, at 11
   seconds and 4% opacity, so it registers as "live" without ever pulling the eye. */
#panel-hydros::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(120% 80% at 50% 50%, transparent 55%, rgba(0, 0, 0, .45) 100%);
}
#panel-hydros::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 160px; pointer-events: none; z-index: 0;
  background: linear-gradient(180deg, transparent, rgba(54, 209, 255, .055) 60%, transparent);
  animation: hudSweepDown 11s linear infinite;
}
@keyframes hudSweepDown { from { transform: translateY(-170px); } to { transform: translateY(100vh); } }
#panel-hydros > * { position: relative; z-index: 1; }

/* ---------------------------------------------------------------------------------------------
   THE PRIMITIVES
   --------------------------------------------------------------------------------------------- */

/* 1. GLASS. Every panel is a sheet of dark glass with a lit top edge. */
#panel-hydros .card,
#panel-hydros .hy-gpanel,
#panel-hydros .hy-mimic-card,
#panel-hydros .hy-card,
#panel-hydros .hy-group-card,
#panel-hydros .hy-cam,
#panel-hydros .ap-panel,
.hy-scrim .hy-gmodal,
.hy-scrim .hy-labmodal,
.hy-scrim .sv-modal {
  position: relative;
  background: linear-gradient(180deg, var(--hud-glass-a), var(--hud-glass-b));
  border: 1px solid var(--hud-line);
  border-radius: 10px;
  box-shadow:
    0 0 0 1px rgba(54, 209, 255, .04),
    0 14px 34px rgba(0, 0, 0, .55),
    0 0 44px rgba(54, 209, 255, .05);
}

/* 2. SCANLINES + the lit edge. ::before, so ::after stays free for the brackets. */
#panel-hydros .card::before,
#panel-hydros .hy-gpanel::before,
#panel-hydros .hy-mimic-card::before,
#panel-hydros .hy-card::before,
#panel-hydros .ap-panel::before,
.hy-scrim .hy-gmodal::before,
.hy-scrim .sv-modal::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  border-radius: inherit;
  background:
    linear-gradient(90deg, transparent, var(--hud), transparent) top / 100% 1px no-repeat,
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 3px);
  opacity: .9;
}

/* 3. CORNER BRACKETS. Eight gradients on one pseudo-element: pure CSS, so they survive every
      ten-second re-render without a line of JavaScript. */
#panel-hydros .card::after,
#panel-hydros .hy-mimic-card::after,
#panel-hydros .hy-card::after,
#panel-hydros .hy-gpanel::after,
#panel-hydros .hy-cam::after,
#panel-hydros .ap-panel::after,
.hy-scrim .hy-gmodal::after,
.hy-scrim .sv-modal::after {
  content: ""; position: absolute; inset: 5px; pointer-events: none; z-index: 2;
  background:
    linear-gradient(var(--hud), var(--hud)) left     top    / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) left     top    / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--hud), var(--hud)) right    top    / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) right    top    / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--hud), var(--hud)) left     bottom / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) left     bottom / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--hud), var(--hud)) right    bottom / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) right    bottom / var(--hud-bracket) 2px no-repeat;
  opacity: .5;
  transition: opacity .2s;
}
#panel-hydros .hy-card:hover::after,
#panel-hydros .card:hover::after { opacity: .95; }
/* A graph panel and a camera are small and there are many of them, so their brackets are shorter
   and dimmer — the mark should say "instrument", not crowd the trace inside it. */
#panel-hydros .hy-gpanel::after,
#panel-hydros .hy-cam::after { --hud-bracket: 8px; inset: 3px; opacity: .36; }
#panel-hydros .hy-gpanel:hover::after { opacity: .8; }

/* Panel contents sit above the scanlines. */
#panel-hydros .card > *,
#panel-hydros .hy-gpanel > *,
#panel-hydros .hy-card > *,
#panel-hydros .ap-panel > *,
.hy-scrim .hy-gmodal > *,
.hy-scrim .sv-modal > * { position: relative; z-index: 1; }

/* 4. MICRO-LABELS. Mono, uppercase, widely tracked — the way an instrument names a channel.
      Everything here is a LABEL, never a value. */
#panel-hydros .hy-tile-label,
#panel-hydros .hy-stat-label,
#panel-hydros .hy-card-sub,
#panel-hydros .hy-gpanel-sub,
#panel-hydros .hy-chiprow-label,
#panel-hydros .hy-tile-foot,
#panel-hydros .hy-card-seen,
#panel-hydros .hy-sp-tag,
#panel-hydros .hy-cp-meta,
#panel-hydros .ap-rowlabel,
#panel-hydros .hy-lbl,
#panel-hydros .hy-tiny,
#panel-hydros table th,
.hy-scrim .sv-table th {
  font-family: var(--hud-mono);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 500;
}
#panel-hydros .hy-tile-label,
#panel-hydros .hy-stat-label,
#panel-hydros .hy-chiprow-label,
#panel-hydros .ap-rowlabel { font-size: 9.5px; color: var(--ink-dim); }
/* Column headings: tracked, but less than the standalone labels — a table has many of them side
   by side, and every extra 0.04em there costs a wrapped line down the whole Device Map. */
#panel-hydros table th,
.hy-scrim .sv-table th {
  font-size: 9.5px; color: var(--hud); border-bottom: 1px solid var(--hud-line);
  letter-spacing: .09em;
}

/* 5. READOUTS. The numbers are the point of the screen, so they get the mono face, tabular
      figures (so a changing value does not jiggle its neighbours) and the glow. */
#panel-hydros .hy-num,
#panel-hydros .hy-tile-value,
#panel-hydros .hy-stat-val,
#panel-hydros .hy-cp-value,
#panel-hydros .hy-headline-value,
#panel-hydros .stat .value,
#panel-hydros .hy-qchip b,
#panel-hydros td.num,
.hy-scrim .sv-table td.num {
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
/* A plain reading is WHITE and seated, not glowing. If every one of the forty tiles on Status
   glows equally then the glow says nothing; it is kept for a value in trouble (above) and for
   the one big headline number, which is the screen's answer to "how is this plant?". */
#panel-hydros .hy-num,
#panel-hydros .hy-tile-value,
#panel-hydros .hy-stat-val,
#panel-hydros .stat .value {
  color: var(--hud-digit);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .75);
}
#panel-hydros .hy-headline-value,
#panel-hydros .hy-num.big {
  color: var(--hud-bright);
  text-shadow: 0 0 26px rgba(54, 209, 255, .55);
}

/* ---------------------------------------------------------------------------------------------
   THE TAB BAR reads as a console keyboard: bracketed keys, the live one lit and scanning.
   It lives OUTSIDE #hy-tab-body, so its motion is never restarted by a refresh.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .hy-tabs { gap: 6px; }
#panel-hydros .hy-tab {
  position: relative;
  background: rgba(20, 29, 42, .85);
  border: 1px solid var(--hud-line);
  border-radius: 6px;
  color: var(--ink-dim);
  font-family: var(--hud-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 9px 13px;
  overflow: hidden;
  transition: color .15s, border-color .15s, background .15s, box-shadow .15s;
}
#panel-hydros .hy-tab:hover { color: var(--ink); border-color: var(--hud); background: rgba(54, 209, 255, .10); }
#panel-hydros .hy-tab.active {
  background: linear-gradient(180deg, rgba(54, 209, 255, .22), rgba(54, 209, 255, .08));
  border-color: var(--hud);
  color: #ffffff;
  box-shadow: 0 0 20px rgba(54, 209, 255, .35), inset 0 0 18px rgba(54, 209, 255, .12);
}
/* The live key scans, slowly, on a 2.4s cycle. */
#panel-hydros .hy-tab.active::after {
  content: ""; position: absolute; left: -40%; top: 0; bottom: 0; width: 40%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .22), transparent);
  animation: hudKeyScan 2.4s linear infinite;
}
@keyframes hudKeyScan { to { left: 120%; } }

/* ---------------------------------------------------------------------------------------------
   THE SITE HEADER: the plant's name as a title plate, its state as a lamp.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .hy-site-head h1,
#panel-hydros .page-head h1 {
  font-family: var(--font-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-shadow: 0 0 26px rgba(54, 209, 255, .35);
}
#panel-hydros .hy-site-head .hy-unit,
#panel-hydros .hy-headline-sub {
  font-family: var(--hud-mono); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-dim);
}

/* ---------------------------------------------------------------------------------------------
   STATE. Chips, dots and lamps. This is the part that must be LOUDER than before, so the colour
   is carried by fill AND ring AND glow — three channels, which survives a sunlit phone screen
   better than colour alone.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .chip, #panel-hydros .hy-chip, #panel-hydros .hy-syschip, #panel-hydros .hy-qchip {
  font-family: var(--hud-mono); letter-spacing: .1em; text-transform: uppercase;
}
#panel-hydros .chip.ok, #panel-hydros .hy-chip.ok, #panel-hydros .hy-syschip.ok {
  box-shadow: 0 0 14px rgba(0, 214, 160, .35), inset 0 0 10px rgba(0, 214, 160, .12);
  border-color: var(--good);
}
#panel-hydros .chip.warn, #panel-hydros .hy-chip.warn, #panel-hydros .hy-syschip.warn {
  box-shadow: 0 0 14px rgba(255, 192, 77, .38), inset 0 0 10px rgba(255, 192, 77, .14);
  border-color: var(--warn);
}
#panel-hydros .chip.crit, #panel-hydros .hy-chip.crit, #panel-hydros .hy-syschip.crit {
  box-shadow: 0 0 18px rgba(255, 95, 109, .5), inset 0 0 12px rgba(255, 95, 109, .18);
  border-color: var(--crit);
  animation: hudAlarm 1.6s ease-in-out infinite;
}
/* The one piece of insistent motion in the file, and it is on the one thing worth insisting
   about. 1.6s is a heartbeat, not a strobe. */
@keyframes hudAlarm {
  0%, 100% { box-shadow: 0 0 18px rgba(255, 95, 109, .5), inset 0 0 12px rgba(255, 95, 109, .18); }
  50%      { box-shadow: 0 0 30px rgba(255, 95, 109, .85), inset 0 0 16px rgba(255, 95, 109, .3); }
}

#panel-hydros .hy-dot { box-shadow: 0 0 10px currentColor; }
#panel-hydros .hy-dot.ok { box-shadow: 0 0 12px var(--good); }
#panel-hydros .hy-dot.warn { box-shadow: 0 0 12px var(--warn); }
#panel-hydros .hy-dot.crit { box-shadow: 0 0 14px var(--crit); animation: hudAlarmDot 1.6s ease-in-out infinite; }
@keyframes hudAlarmDot { 0%, 100% { box-shadow: 0 0 14px var(--crit); } 50% { box-shadow: 0 0 24px var(--crit); } }

/* A plant in trouble gets a lit edge on its whole card — visible across a room. */
#panel-hydros .hy-alarm-card,
#panel-hydros .hy-card.crit {
  border-color: var(--crit);
  box-shadow: 0 0 0 1px rgba(255, 95, 109, .25), 0 14px 34px rgba(0, 0, 0, .55), 0 0 40px rgba(255, 95, 109, .22);
}
#panel-hydros .hy-card.crit::after,
#panel-hydros .hy-alarm-card::after {
  background-image:
    linear-gradient(var(--crit), var(--crit)), linear-gradient(var(--crit), var(--crit)),
    linear-gradient(var(--crit), var(--crit)), linear-gradient(var(--crit), var(--crit)),
    linear-gradient(var(--crit), var(--crit)), linear-gradient(var(--crit), var(--crit)),
    linear-gradient(var(--crit), var(--crit)), linear-gradient(var(--crit), var(--crit));
  opacity: .85;
}
#panel-hydros .hy-card.warn::after { background-image:
  linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn)),
  linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn)),
  linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn)),
  linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn));
  opacity: .7; }

/* ---------------------------------------------------------------------------------------------
   TILES AND QUALITY CHIPS. A left rule of state colour is already there; it becomes a lit bar.
   --------------------------------------------------------------------------------------------- */
/* THE REPAIR — read this before touching anything below it.
   Measured in the browser, 13 Sep 2026: inside HYDROS Live a crit tile, a warn tile and an ok
   tile came out IDENTICAL — same ground, same 0.8px border, same colour. The state wash and the
   4px rail had been gone since the 7 Sep skin, because
       #panel-hydros .hy-tile { background: …; border: 1px solid var(--line) }   (1,1,0)
   outranks
       .hy-tile.crit { background: var(--crit-bg); border-left-color: var(--crit) }   (0,2,0)
   and the `border` SHORTHAND also reset the 4px rail to 1px. An operator glancing at Status saw
   forty identical tiles whatever the plant was doing.
   So: never the `background` or `border` shorthand on anything whose state class carries colour.
   Ground, rail and glow are restated here at ID specificity, and the state is carried on THREE
   channels — filled ground, 4px rail, and a glow — because one channel does not survive a phone
   screen in sunlight. */
#panel-hydros .hy-tile, #panel-hydros .hy-qchip {
  position: relative;
  background-color: transparent;
  background-image: linear-gradient(180deg, rgba(20, 29, 42, .92), rgba(13, 20, 30, .92));
  border-color: var(--hud-line);
  border-left-width: 4px;
  border-left-color: var(--hud);
  box-shadow: inset 3px 0 12px -6px var(--hud);
}
#panel-hydros .hy-tile.ok, #panel-hydros .hy-qchip.ok {
  border-left-color: var(--good); box-shadow: inset 4px 0 14px -7px var(--good);
}
#panel-hydros .hy-tile.warn, #panel-hydros .hy-qchip.warn {
  background-image: linear-gradient(180deg, rgba(64, 48, 14, .92), rgba(44, 34, 17, .92));
  border-color: rgba(255, 192, 77, .45); border-left-color: var(--warn);
  box-shadow: inset 4px 0 16px -6px var(--warn), 0 0 16px rgba(255, 192, 77, .18);
}
#panel-hydros .hy-tile.crit, #panel-hydros .hy-qchip.crit {
  background-image: linear-gradient(180deg, rgba(74, 22, 32, .94), rgba(46, 19, 26, .94));
  border-color: rgba(255, 95, 109, .55); border-left-color: var(--crit);
  box-shadow: inset 4px 0 18px -6px var(--crit), 0 0 22px rgba(255, 95, 109, .26);
}
/* The value and the label inside a tile in trouble take the colour too — the tile is read from
   two metres away, and at that distance the ground alone is a smudge. */
#panel-hydros .hy-tile.crit .hy-tile-value, #panel-hydros .hy-qchip.crit b {
  color: #ffd9dd; text-shadow: 0 0 16px rgba(255, 95, 109, .75);
}
#panel-hydros .hy-tile.warn .hy-tile-value, #panel-hydros .hy-qchip.warn b {
  color: #ffe6b8; text-shadow: 0 0 16px rgba(255, 192, 77, .6);
}
#panel-hydros .hy-tile.crit .hy-tile-label { color: #ffb3ba; }
#panel-hydros .hy-tile.warn .hy-tile-label { color: #ffd894; }
/* A tile in trouble is not the place for decoration: the scanlines come off so the ground reads
   as one flat colour. */
#panel-hydros .hy-tile.crit::before, #panel-hydros .hy-tile.warn::before { display: none; }

/* ---------------------------------------------------------------------------------------------
   GRAPH PANELS. A bracketed instrument with a mono channel name and a lit baseline.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .hy-gpanel { border-color: var(--hud-line); }
#panel-hydros .hy-gpanel:hover { border-color: var(--hud); box-shadow: 0 0 22px rgba(54, 209, 255, .18); }
#panel-hydros .hy-gpanel-name {
  font-family: var(--hud-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--hud-bright);
}
#panel-hydros .hy-gpanel-range,
#panel-hydros .hy-gzoom { font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .1em; color: var(--ink-dim); }
#panel-hydros .hy-gpanel-head { border-bottom: 1px solid var(--hud-line); padding-bottom: 5px; }
#panel-hydros .hy-axis { font-family: var(--hud-mono); font-size: 9px; letter-spacing: .06em; fill: var(--ink-dim); }
#panel-hydros .hy-gchart path { filter: drop-shadow(0 0 4px rgba(54, 209, 255, .45)); }
#panel-hydros .hy-spark path { filter: drop-shadow(0 0 3px rgba(54, 209, 255, .5)); }

/* ---------------------------------------------------------------------------------------------
   THE SCHEMATIC. The one drawing on the screen, so it gets the most light: a reactor readout
   rather than a diagram. Everything here is a filter or a stroke — no geometry is touched.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .hy-mimic-card {
  background:
    radial-gradient(700px 320px at 50% 0%, rgba(54, 209, 255, .09), transparent 70%),
    linear-gradient(180deg, #0b1420, #070d16);
}
#panel-hydros .hy-mimic .hy-vessel { fill: rgba(16, 26, 39, .9); stroke: var(--hud-line); }
#panel-hydros .hy-mimic .hy-pipe { stroke: #2a4058; }
#panel-hydros .hy-mimic .hy-flow { filter: drop-shadow(0 0 5px rgba(0, 214, 160, .95)); }
#panel-hydros .hy-mimic .hy-bub { filter: drop-shadow(0 0 4px rgba(54, 209, 255, .9)); }
#panel-hydros .hy-mimic .hy-fillwater { filter: drop-shadow(0 0 9px rgba(54, 209, 255, .45)); }
#panel-hydros .hy-mimic .hy-eq.r-on .hy-state-ring { filter: drop-shadow(0 0 8px rgba(0, 214, 160, .95)); }
#panel-hydros .hy-mimic .hy-eq.r-fon .hy-state-ring,
#panel-hydros .hy-mimic .hy-eq.r-foff .hy-state-ring { filter: drop-shadow(0 0 9px currentColor); }
#panel-hydros .hy-mimic .hy-uv-glow, #panel-hydros .hy-mimic .hy-uv-beam { filter: drop-shadow(0 0 7px rgba(150, 120, 255, .8)); }
#panel-hydros .hy-mimic .hy-lbl, #panel-hydros .hy-mimic .hy-zonetag {
  font-family: var(--hud-mono); letter-spacing: .1em; text-transform: uppercase;
}
/* The readings on the drawing sit straight on top of vessels, pipes, water and sludge — whatever
   colour happens to be under them. paint-order puts a dark stroke DOWN FIRST and the glyph on
   top of it, so every numeral carries its own dark seat wherever it lands. This is the single
   biggest readability gain in the restyle and it costs nothing. */
#panel-hydros .hy-mimic .hy-num, #panel-hydros .hy-mimic .hy-lbl, #panel-hydros .hy-mimic .hy-eq-letter {
  paint-order: stroke fill;
  stroke: #05090f;
  stroke-linejoin: round;
  font-variant-numeric: tabular-nums slashed-zero;   /* P1B-0 must never read as P1B-O */
}
#panel-hydros .hy-mimic .hy-num { stroke-width: 3px; fill: var(--hud-digit, #f2fbff); }
#panel-hydros .hy-mimic .hy-lbl { stroke-width: 2.4px; }
#panel-hydros .hy-mimic .hy-eq-letter { stroke-width: 2.4px; }

/* A STOPPED device must never read as a dim running one. The glow is what says "running", so a
   device that is off gets none at all. */
#panel-hydros .hy-mimic .hy-eq.r-off .hy-state-ring { filter: none; }

/* ---------------------------------------------------------------------------------------------
   CONTROL PANEL and DEVICE MAP: rows of a register listing.
   --------------------------------------------------------------------------------------------- */
/* Register names are already long (class_c_recycle_valve_override). The mono face alone gives
   them the look; adding tracking pushed them out of their 176px column, so there is none here,
   and anything still too long is allowed to shrink rather than overflow its row. */
#panel-hydros .hy-cp-name, #panel-hydros .hy-dm-row .hy-code, #panel-hydros .hy-code {
  font-family: var(--hud-mono); letter-spacing: 0;
}
/* A register name longer than its column (class_c_recycle_valve_override in 176px) spilled out of
   the row before this skin existed; mono makes it a little wider still. Letting it wrap fixes both.
   Everything in the cell, because the name is not always in an element with a class of its own. */
#panel-hydros .hy-cp-main, #panel-hydros .hy-cp-main * { min-width: 0; overflow-wrap: anywhere; }
#panel-hydros .hy-code { overflow-wrap: anywhere; min-width: 0; }
#panel-hydros .hy-cp-row, #panel-hydros .hy-dm-row { border-bottom: 1px solid rgba(54, 209, 255, .10); }
#panel-hydros .hy-cp-row:hover, #panel-hydros .hy-dm-row:hover { background: rgba(54, 209, 255, .06); }
#panel-hydros .hy-cp-tabs .hy-tab { font-size: 9.5px; padding: 7px 11px; }
#panel-hydros .hy-sp-lo, #panel-hydros .hy-sp-hi, #panel-hydros .hy-cp-range {
  font-family: var(--hud-mono); font-size: 10px; letter-spacing: .08em; color: var(--ink-dim);
}

/* ---------------------------------------------------------------------------------------------
   TABLES read as a console log.
   --------------------------------------------------------------------------------------------- */
#panel-hydros table td, .hy-scrim .sv-table td { border-bottom-color: rgba(54, 209, 255, .10); }
#panel-hydros tbody tr:hover td, .hy-scrim .sv-table tbody tr:hover td { background: rgba(54, 209, 255, .07); }
#panel-hydros .table-wrap, #panel-hydros .table-scroll { border-color: var(--hud-line); }

/* ---------------------------------------------------------------------------------------------
   BUTTONS as console keys.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .btn, .hy-scrim .btn {
  font-family: var(--hud-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  border-radius: 6px;
  border-color: var(--hud-line);
  transition: box-shadow .15s, border-color .15s, background .15s;
}
#panel-hydros .btn:hover, .hy-scrim .btn:hover { border-color: var(--hud); box-shadow: 0 0 14px rgba(54, 209, 255, .3); }
#panel-hydros .btn.primary, .hy-scrim .btn.primary {
  background: linear-gradient(180deg, rgba(54, 209, 255, .3), rgba(54, 209, 255, .12));
  border-color: var(--hud); color: #eaffff;
  box-shadow: 0 0 16px rgba(54, 209, 255, .3), inset 0 0 14px rgba(54, 209, 255, .1);
}
#panel-hydros .btn.primary:hover, .hy-scrim .btn.primary:hover { box-shadow: 0 0 26px rgba(54, 209, 255, .55); }
#panel-hydros .btn.danger, .hy-scrim .btn.danger { border-color: var(--crit); }
#panel-hydros .btn.danger:hover, .hy-scrim .btn.danger:hover { box-shadow: 0 0 16px rgba(255, 95, 109, .45); }

/* ---------------------------------------------------------------------------------------------
   FORMS. Dark wells with a lit focus ring.
   --------------------------------------------------------------------------------------------- */
#panel-hydros input, #panel-hydros select, #panel-hydros textarea,
.hy-scrim input, .hy-scrim select, .hy-scrim textarea {
  background: rgba(6, 12, 20, .85);
  border-color: var(--hud-line);
  color: var(--ink);
}
#panel-hydros input:focus, #panel-hydros select:focus, #panel-hydros textarea:focus,
.hy-scrim input:focus, .hy-scrim select:focus, .hy-scrim textarea:focus {
  border-color: var(--hud);
  box-shadow: 0 0 0 3px rgba(54, 209, 255, .16), 0 0 18px rgba(54, 209, 255, .2);
  outline: none;
}
#panel-hydros .field > label, .hy-scrim .field > label {
  font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-dim);
}

/* ---------------------------------------------------------------------------------------------
   THE ANNUAL PLAN RIBBON as a mission timeline.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .ap-ribbon-card { position: relative; }
#panel-hydros .ap-month, #panel-hydros .ap-mo {
  font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-dim);
}
#panel-hydros .ap-lane { background: rgba(54, 209, 255, .05); }
#panel-hydros .ap-today { background: var(--hud); box-shadow: 0 0 14px var(--hud); }
#panel-hydros .ap-mark { box-shadow: 0 0 10px rgba(54, 209, 255, .35); font-family: var(--hud-mono); }
#panel-hydros .ap-mark:hover { box-shadow: 0 0 18px var(--hud); z-index: 3; }
#panel-hydros .ap-year { font-family: var(--hud-mono); letter-spacing: .18em; }

/* ---------------------------------------------------------------------------------------------
   THE NOTEBOOK. It is the one screen Steve has called imperative on phones, so it gets the light
   and the brackets but none of the motion.
   --------------------------------------------------------------------------------------------- */
#panel-hydros .hy-nb-count, #panel-hydros .hy-nb-label, #panel-hydros .hy-search-count {
  font-family: var(--hud-mono); letter-spacing: .12em; text-transform: uppercase; font-size: 9.5px;
}
#panel-hydros .hy-nb-item { border-color: rgba(54, 209, 255, .12); }
#panel-hydros .hy-nb-item:hover { border-color: var(--hud-line); background: rgba(54, 209, 255, .04); }
#panel-hydros .hy-nb-meta { font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .06em; }

/* ---------------------------------------------------------------------------------------------
   POP-UPS arrive the way the briefing's does.
   --------------------------------------------------------------------------------------------- */
.hy-scrim { background: rgba(3, 8, 14, .72); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.hy-scrim .hy-gmodal, .hy-scrim .sv-modal, .hy-scrim .hy-labmodal { animation: hudModalIn .34s cubic-bezier(.2, .8, .2, 1) 1; }
@keyframes hudModalIn { from { opacity: 0; transform: scale(.965); } to { opacity: 1; transform: scale(1); } }
.hy-scrim .hy-gmodal-head, .hy-scrim .sv-modal .sv-head {
  border-bottom: 1px solid var(--hud-line);
}
.hy-scrim .hy-gmodal-head h2, .hy-scrim .hy-gmodal-title {
  font-family: var(--hud-mono); font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--hud);
}

/* ---------------------------------------------------------------------------------------------
   BOOT. Only on a real tab change — hydros-hud.js adds .hud-boot to #hy-tab-body and takes it off
   again. Without that gate this would fire every ten seconds on six of the tabs.
   --------------------------------------------------------------------------------------------- */
#panel-hydros #hy-tab-body.hud-boot > * { animation: hudBootIn .42s cubic-bezier(.2, .8, .2, 1) both; }
#panel-hydros #hy-tab-body.hud-boot > *:nth-child(2) { animation-delay: .05s; }
#panel-hydros #hy-tab-body.hud-boot > *:nth-child(3) { animation-delay: .10s; }
#panel-hydros #hy-tab-body.hud-boot > *:nth-child(4) { animation-delay: .15s; }
#panel-hydros #hy-tab-body.hud-boot > *:nth-child(n+5) { animation-delay: .20s; }
@keyframes hudBootIn {
  from { opacity: 0; transform: translateY(10px); clip-path: inset(0 0 100% 0); }
  to   { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }
}

/* Somebody who has asked their machine for more contrast, or is standing in the sun with the
   setting on: the decoration is what goes, and the structure hardens. */
@media (prefers-contrast: more) {
  #panel-hydros, .hy-scrim { --ink-dim: #c8dcee; --hud-line: rgba(54, 209, 255, .5); }
  #panel-hydros .card::before, #panel-hydros .hy-card::before, #panel-hydros .hy-gpanel::before,
  #panel-hydros .ap-panel::before, #panel-hydros .hy-mimic-card::before { display: none; }
  #panel-hydros .card::after, #panel-hydros .hy-card::after, #panel-hydros .ap-panel::after { opacity: 1; }
  #panel-hydros::after { display: none; }
}

/* ---------------------------------------------------------------------------------------------
   PHONES. Brackets shrink, the field grid coarsens, and the decorative motion goes: an operator
   standing at a plant on a 375px screen needs the values, not the show.
   --------------------------------------------------------------------------------------------- */
@media (max-width: 620px) {
  #panel-hydros { --hud-bracket: 9px; animation: none; }
  #panel-hydros::after { display: none; }
  #panel-hydros .hy-tab { font-size: 9.5px; letter-spacing: .1em; padding: 10px 11px; min-height: 44px; }
  #panel-hydros .hy-tab.active::after { display: none; }
  #panel-hydros .card::before, #panel-hydros .hy-card::before, #panel-hydros .ap-panel::before { opacity: .5; }
}

/* A tile that CROSSED a line flares once — the whole tile, not the digit, because the thing that
   changed is what the tile is saying, not what it is showing. hydros-hud.js decides which tiles
   crossed; a reading that merely wobbled gets nothing. */
#panel-hydros .hud-rolled { animation: hudCross 1.3s ease-out 1; }
@keyframes hudCross {
  0%   { box-shadow: 0 0 0 2px #ffffff, 0 0 34px rgba(255, 255, 255, .8); }
  35%  { box-shadow: 0 0 0 2px var(--hud), 0 0 30px rgba(54, 209, 255, .6); }
  100% { box-shadow: 0 0 0 0 transparent, 0 0 0 transparent; }
}

/* ---------------------------------------------------------------------------------------------
   REDUCED MOTION.
   styles.css turns every animation off globally, and the machine this was built on reports the
   preference — so without this block Steve would have asked for animated graphics and been shown
   a still picture.
   The line drawn here is the one the preference is actually about: LARGE MOVEMENT. Nothing below
   moves a box across the screen. What is kept is light — a background drifting one pixel a frame,
   a glow rising and falling, a dim sheen crossing a key — plus the alarm pulse, which carries
   meaning and must never be switched off. What is taken away is every slide, scale and wipe: the
   boot becomes a plain fade, and a pop-up simply appears.
   --------------------------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* light, not movement — kept */
  #panel-hydros { animation: hudField 40s linear infinite !important; }
  #panel-hydros::after { animation: hudSweepDown 18s linear infinite !important; opacity: .6; }
  #panel-hydros .hy-tab.active::after { animation: hudKeyScan 3.2s linear infinite !important; }
  #panel-hydros .chip.crit, #panel-hydros .hy-chip.crit, #panel-hydros .hy-syschip.crit {
    animation: hudAlarm 2.4s ease-in-out infinite !important;
  }
  #panel-hydros .hy-dot.crit { animation: hudAlarmDot 2.4s ease-in-out infinite !important; }
  #panel-hydros .hud-rolled { animation: hudCross 1.6s ease-out 1 !important; }

  /* movement — removed, replaced by a fade */
  #panel-hydros #hy-tab-body.hud-boot > * { animation: hudBootFade .3s ease-out both !important; }
  @keyframes hudBootFade { from { opacity: 0; } to { opacity: 1; } }
  .hy-scrim .hy-gmodal, .hy-scrim .sv-modal, .hy-scrim .hy-labmodal {
    animation: hudBootFade .2s ease-out 1 !important;
  }
}

/* ================================================================================================
   THE LOGGING CLOCK (Steve, 14 Sep 2026)
   "a countdown timer until the next logging event ... a visual effect like an old school calculator"

   An LCD, not a HUD readout: the rest of this skin glows, and a calculator display does the opposite
   — it is a dark grey-green pane with dead segments sitting in it, and the lit segments are only
   slightly darker than the ghosts. That contrast inversion is the whole trick. The ghost digits are
   a real element (88:88 underneath at low opacity), which is how an actual segment display looks
   when you can see the unlit segments, and it also stops the width jittering as digits change.
   ============================================================================================== */
.hy-logclock {
  display: inline-flex; align-items: center; gap: 9px;
  margin-top: 7px; padding: 5px 9px 5px 8px;
  border: 1px solid rgba(54, 209, 255, .20); border-radius: 3px;
  background: linear-gradient(180deg, #0d1512, #0a110f);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .7), inset 0 0 0 1px rgba(255, 255, 255, .02);
}
.hy-logclock-label {
  font: 600 8.5px/1 var(--hud-mono); letter-spacing: .16em; text-transform: uppercase;
  color: rgba(140, 190, 160, .55); white-space: nowrap;
}
/* The pane the digits sit on. position:relative so the ghosts can stack under the live value. */
.hy-logclock-lcd {
  position: relative; padding: 2px 5px 1px; border-radius: 2px;
  background: #101a15; box-shadow: inset 0 1px 2px rgba(0, 0, 0, .8);
  font: 700 17px/1 var(--hud-mono); letter-spacing: .06em;
  font-variant-numeric: tabular-nums; /* a proportional 1 would make the whole thing twitch */
}
.hy-logclock-ghost {
  position: absolute; inset: 2px 5px 1px; color: rgba(120, 255, 180, .10);
  pointer-events: none; user-select: none;
}
.hy-logclock-live {
  position: relative; color: #7dffb4;
  text-shadow: 0 0 5px rgba(125, 255, 180, .38);
}
/* Under ten seconds it is about to happen; at zero it is overdue and says so rather than sitting
   on 00:00 pretending. Amber, not red — a late reading is not yet a fault. */
.hy-logclock.soon .hy-logclock-live { color: #ffd27a; text-shadow: 0 0 6px rgba(255, 210, 122, .45); }
.hy-logclock.due  .hy-logclock-live { color: #ffb35c; text-shadow: 0 0 7px rgba(255, 179, 92, .5);
  animation: hudLcdDue 1.6s ease-in-out infinite; }
@keyframes hudLcdDue { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
/* No history to predict from — show dead segments rather than a guess. */
.hy-logclock.unknown .hy-logclock-live { color: rgba(120, 255, 180, .22); text-shadow: none; }

/* ================================================================================================
   THE DATA SWEEP
   When a reading actually lands, a line crosses every panel that shows live data — the same
   vocabulary as the briefing's targeting scan and this skin's own slow sweep bar, just faster and
   once. It is the only fast motion on the page, which is what makes it read as an event.
   ============================================================================================== */
.hy-sweep { position: relative; }
.hy-sweep::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none; border-radius: inherit;
  background: linear-gradient(100deg,
    transparent 0%, rgba(54, 209, 255, 0) 38%,
    rgba(54, 209, 255, .10) 46%, rgba(125, 255, 180, .30) 50%, rgba(54, 209, 255, .10) 54%,
    rgba(54, 209, 255, 0) 62%, transparent 100%);
  background-size: 260% 100%; background-repeat: no-repeat;
  animation: hudDataSweep 900ms cubic-bezier(.35, .1, .25, 1) 1;
}
@keyframes hudDataSweep {
  from { background-position: 160% 0; }
  to   { background-position: -160% 0; }
}
/* Reduced motion: the sweep is an EVENT NOTICE, not decoration, so it still happens — it just
   appears and fades rather than travelling. */
@media (prefers-reduced-motion: reduce) {
  .hy-sweep::after { animation: hudDataFlash 700ms ease-out 1; background: rgba(125, 255, 180, .12); }
  @keyframes hudDataFlash { from { opacity: 1; } to { opacity: 0; } }
  .hy-logclock.due .hy-logclock-live { animation: none; }
}

/* ==============================================================================================
   THE PRODUCTION SCREENS — the same instrument, three more channels
   ==============================================================================================

   Steve, 17 Sep 2026: "this isn't a bad layout, but needs to be redone in the graphics style guide
   you've developed in hydros live, ultra futuristic and high tech."

   Scoped to .hud-screen and written against the SAME tokens as the block above, so every screen
   wearing it is one system rather than several dialects. It is its own block rather than 175
   widened selectors: the promise at the top of this file is that deleting one <link> puts
   everything back, and a comma added to every rule up there would have made that a lie the first
   time somebody edited one of them.

   ONE CLASS, NOT A LIST OF IDS. It was a list until 17 Sep 2026, and the list had to be retyped on
   every single rule — which is how the paragraph you are reading ended up with "and written against
   the SAME tokens as the block above" stamped into it five times by a find-and-replace. Adding a
   screen is now one word in index.html: class="hud-screen". The screens wearing it today are
   Forecast Production, Production Planner, My Workshop, My Site Work, My Training, Serial Number
   Generator and Factory Acceptance Testing.

   THE RULE FROM THE TOP OF THIS FILE STILL DECIDES EVERYTHING. The forecast is how Steve finds out
   what he has to build and what he has not ordered yet. The numbers come out LOUDER. The brackets,
   the grid and the sweep sit on panels and never over a value. ORDERS OVERDUE is the one thing on
   this screen that should take attention, so it is the only thing that is amber and the only thing
   that moves.
   ============================================================================================== */

.hud-screen {
  --hud: #36d1ff;
  --hud-bright: #7ae2ff;
  --hud-dim: rgba(54, 209, 255, .38);
  --hud-soft: rgba(54, 209, 255, .10);
  --hud-line: rgba(54, 209, 255, .22);
  --hud-mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
  --hud-bracket: 13px;
  --hud-glass-a: rgba(19, 29, 43, .94);
  --hud-glass-b: rgba(11, 18, 28, .94);
  --paper: #05090f;
  --surface: #0e1620;
  --surface-2: #141d2a;
  --line: #22344a;
  --ink: #eaf6fe;
  --ink-dim: #9db6cd;
  --hud-digit: #f2fbff;
  --warn: #e0b04c;
  --warn-bg: rgba(224, 176, 76, .12);
  --accent: #36d1ff;
  --accent-soft: rgba(54, 209, 255, .10);

  position: relative;
  color: var(--ink);
  background:
    radial-gradient(1400px 700px at 50% -14%, rgba(54, 209, 255, .13), transparent 70%),
    radial-gradient(900px 500px at 88% 8%, rgba(0, 214, 160, .05), transparent 70%),
    linear-gradient(rgba(54, 209, 255, .030) 1px, transparent 1px) 0 0 / 100% 44px,
    linear-gradient(90deg, rgba(54, 209, 255, .030) 1px, transparent 1px) 0 0 / 44px 100%,
    var(--paper);
  animation: hudField 24s linear infinite;
}

/* Vignette, and one slow scan down the whole module. Same 11s, same 4%, as HYDROS Live. */
.hud-screen::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(120% 80% at 50% 50%, transparent 55%, rgba(0, 0, 0, .45) 100%);
}
.hud-screen::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 160px; pointer-events: none; z-index: 0;
  background: linear-gradient(180deg, transparent, rgba(54, 209, 255, .055) 60%, transparent);
  animation: hudSweepDown 11s linear infinite;
}
.hud-screen > * { position: relative; z-index: 1; }

/* The title reads as a channel name, and the blurb steps back out of the way of it. */
.hud-screen .page-head h1 {
  color: var(--ink);
  text-shadow: 0 0 30px rgba(54, 209, 255, .30);
}
.hud-screen .page-head p { color: var(--ink-dim); }

/* GLASS, LIT EDGE, SCANLINES, BRACKETS — the four primitives, unchanged. */
.hud-screen .card,
.hud-screen .visit-card,
.hud-screen .policy-item,
.hud-screen .stat {
  position: relative;
  background: linear-gradient(180deg, var(--hud-glass-a), var(--hud-glass-b));
  /* A continuous frame, with the brackets as reinforcement on top of it — never instead of it. */
  border: 1px solid rgba(54, 209, 255, .30);
  border-radius: 10px;
  box-shadow:
    0 0 0 1px rgba(54, 209, 255, .04),
    0 14px 34px rgba(0, 0, 0, .55),
    0 0 44px rgba(54, 209, 255, .05);
}
.hud-screen .card::before,
.hud-screen .visit-card::before,
.hud-screen .policy-item::before,
.hud-screen .stat::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  border-radius: inherit;
  background:
    linear-gradient(90deg, transparent, var(--hud), transparent) top / 100% 1px no-repeat,
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .022) 0 1px, transparent 1px 3px);
  opacity: .9;
}
/* The brackets sit ON the border corners, not floating inside them. At inset 5px they read as a
   second, broken rectangle — which is what makes a HUD look like a mistake rather than an
   instrument. On the corner they reinforce the frame instead of competing with it. */
.hud-screen .card::after,
.hud-screen .visit-card::after,
.hud-screen .policy-item::after,
.hud-screen .stat::after {
  content: ""; position: absolute; inset: -1px; pointer-events: none; z-index: 2;
  background:
    linear-gradient(var(--hud), var(--hud)) left  top    / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) left  top    / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--hud), var(--hud)) right top    / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) right top    / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--hud), var(--hud)) left  bottom / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) left  bottom / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--hud), var(--hud)) right bottom / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--hud), var(--hud)) right bottom / var(--hud-bracket) 2px no-repeat;
  opacity: .5;
  transition: opacity .2s;
}
.hud-screen .card:hover::after,
.hud-screen .visit-card:hover::after,
.hud-screen .policy-item:hover::after { opacity: .95; }
/* A stat tile is small and there are six of them: shorter, dimmer marks, so they say "instrument"
   without crowding the number inside. */
.hud-screen .stat::after { --hud-bracket: 10px; inset: -1px; opacity: .55; }
/* The base .stat rule in styles.css sets overflow: hidden (it needed it for the old 3px left
   stripe, which this skin replaces). With the brackets sitting at inset -1px, that clip was
   swallowing them — the cards had corners and the tiles did not (Steve, 17 Sep 2026: "these
   needs the nicer newer corners"). Nothing else in a tile relies on the clip. */
.hud-screen .stat { overflow: visible; }
.hud-screen .stat:hover::after { opacity: .8; }
.hud-screen .visit-card > *,
.hud-screen .policy-item > *,
.hud-screen .card > *,
.hud-screen .stat > * { position: relative; z-index: 1; }

/* MICRO-LABELS. Everything here names a channel; nothing here is a value. */
.hud-screen .card > h2,
.hud-screen .stat .label,
.hud-screen .forecast-cell label {
  font-family: var(--hud-mono);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 500;
  color: var(--hud);
}
.hud-screen .card > h2 { font-size: 11px; }
.hud-screen .stat .label,
.hud-screen .forecast-cell label { font-size: 9.5px; color: var(--ink-dim); }
.hud-screen .desc,
.hud-screen .stat .foot { color: var(--ink-dim); }
.hud-screen .collapse-chevron { color: var(--hud); }

/* READOUTS. Mono, tabular, and the brightest thing on the screen. */
.hud-screen .stat .value {
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  color: var(--hud-digit);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .75);
}

/* The month boxes read as console keys: a lit frame, a mono figure, and the one you are typing in
   glowing. A zero is dimmed — twelve bright zeros would drown the two months that matter. */
.hud-screen .forecast-cell input {
  width: 100%;
  background: rgba(5, 9, 15, .75);
  border: 1px solid var(--hud-line);
  border-radius: 8px;
  color: var(--hud-digit);
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  text-align: right;
  padding: 9px 11px;
  transition: border-color .18s, box-shadow .18s, background .18s;
}
.hud-screen .forecast-cell input:hover { border-color: var(--hud-dim); }
.hud-screen .forecast-cell input:focus {
  outline: none;
  border-color: var(--hud);
  background: rgba(54, 209, 255, .06);
  box-shadow: 0 0 22px rgba(54, 209, 255, .28), inset 0 0 14px rgba(54, 209, 255, .07);
}
/* :placeholder-shown cannot see a value of "0", so the dimming is done by the app adding
   .is-zero — see renderForecastGrid. Without the class the box simply stays bright, which is the
   safe direction to fail in. */
.hud-screen .forecast-cell input.is-zero { color: #46617c; }

/* The app already marks this tile .s-warn (and a healthy one .s-good), so the skin paints what
   the app already knows rather than asking it to say it twice.
   ORDERS OVERDUE is the only thing on this screen allowed to move. Same rule as a critical alarm
   in HYDROS Live: if everything pulses, a pulse means nothing. */
.hud-screen .stat.s-warn { border-color: rgba(224, 176, 76, .45); }
.hud-screen .stat.s-warn .value { color: var(--warn); text-shadow: 0 0 22px rgba(224, 176, 76, .40); }
.hud-screen .stat.s-warn::after { background-image:
    linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn)),
    linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn)),
    linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn)),
    linear-gradient(var(--warn), var(--warn)), linear-gradient(var(--warn), var(--warn));
  opacity: .75; animation: fcAlert 2.4s ease-in-out infinite; }
@keyframes fcAlert { 0%, 100% { opacity: .38; } 50% { opacity: .95; } }

/* The tiles rise on first paint, left to right, like a panel coming up. ~1.1s in total and it
   never repeats, because this panel is not re-rendered on a timer. */
.hud-screen .stat { animation: fcTileIn .5s ease-out both; }
.hud-screen .stat-row .stat:nth-child(2) { animation-delay: .07s; }
.hud-screen .stat-row .stat:nth-child(3) { animation-delay: .14s; }
.hud-screen .stat-row .stat:nth-child(4) { animation-delay: .21s; }
@keyframes fcTileIn { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }

/* (the reduced-motion rule that stood here was inert — styles.css switches every animation off
   with !important — and is replaced at the end of the file by the HYDROS form of it) */

/* A tile that is good news is stated, not celebrated — green only on the mark, never a glow. */
.hud-screen .stat.s-good .value { color: var(--hud-digit); }
.hud-screen .stat.s-good::after { opacity: .45; }

/* ----------------------------------------------------------------------------------------------
   TABLES, CHIPS, KEYS AND FIELDS — the parts the Production Planner and My Workshop are made of.
   The three panels above share these; a table is where most of this screen's information actually
   lives, so it gets the same care as a readout.
   ---------------------------------------------------------------------------------------------- */

/* A table header names a channel: mono, uppercase, tracked — but less than a standalone label,
   because there are eight of them side by side and every extra 0.04em costs a wrapped line. */
.hud-screen table th {
  font-family: var(--hud-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--hud);
  border-bottom: 1px solid rgba(54, 209, 255, .30);
  background: rgba(54, 209, 255, .04);
}
#panel-planner table td,
#panel-active table td {
  border-bottom: 1px solid rgba(54, 209, 255, .10);
  color: var(--ink);
}
/* Figures are mono and tabular so a column of them lines up and a changing value does not jiggle
   its neighbours. */
#panel-planner table td.num,
#panel-active table td.num,
#panel-planner .num,
#panel-active .num {
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  color: var(--hud-digit);
}
/* The row under the cursor lifts slightly — enough to keep your place across eight columns on a
   wide screen, not enough to pull the eye on its own. */
#panel-planner table tbody tr:hover,
#panel-active table tbody tr:hover { background: rgba(54, 209, 255, .05); }
/* (scrollbar: see the module-owns-its-scrollbar block at the end of the file) */

/* The part number under a name, and any other small ident. */
#panel-planner .id,
#panel-active .id {
  font-family: var(--hud-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* The assembly name is the way into its instruction sheet, so it reads as a live control rather
   than as text that happens to be clickable. */
#panel-planner .linkish,
#panel-active .linkish,
#panel-planner .ws-open,
#panel-active .ws-open {
  color: var(--ink);
  font-weight: 600;
  border-bottom: 1px dotted var(--hud-dim);
}
#panel-planner .linkish:hover,
#panel-active .linkish:hover,
#panel-planner .ws-open:hover,
#panel-active .ws-open:hover {
  color: var(--hud-bright);
  border-bottom-color: var(--hud);
  text-shadow: 0 0 16px rgba(54, 209, 255, .45);
}

/* CHIPS. An outlined tag, not a filled sticker — the status is the word, and a solid block of
   colour behind every row would fight the numbers. */
.hud-screen .chip {
  font-family: var(--hud-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid var(--hud-line);
  color: var(--ink-dim);
}
#panel-planner .chip.ok, #panel-active .chip.ok { border-color: rgba(53, 183, 206, .55); color: #35b7ce; }
#panel-planner .chip.warn, #panel-active .chip.warn { border-color: rgba(224, 176, 76, .55); color: #e0b04c; }
#panel-planner .chip.crit, #panel-active .chip.crit { border-color: rgba(226, 105, 90, .6); color: #e2695a; }

/* KEYS. Every button on these screens is a console key: dark, bracketed by its own border, lit
   when the finger is on it. */
.hud-screen .btn,
#panel-active .wb-btn , #panel-serials .wb-btn , #panel-fat .wb-btn {
  background: rgba(20, 29, 42, .85);
  border: 1px solid var(--hud-line);
  color: var(--ink);
  font-family: var(--hud-mono);
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  transition: border-color .18s, box-shadow .18s, background .18s, color .18s;
}
.hud-screen .btn:hover,
#panel-active .wb-btn:hover , #panel-serials .wb-btn:hover , #panel-fat .wb-btn:hover {
  border-color: var(--hud);
  color: var(--hud-bright);
  background: rgba(54, 209, 255, .08);
  box-shadow: 0 0 20px rgba(54, 209, 255, .25);
}
.hud-screen .btn.primary,
#panel-active .wb-btn.go , #panel-serials .wb-btn.go , #panel-fat .wb-btn.go {
  border-color: var(--hud);
  color: var(--hud-bright);
  background: rgba(54, 209, 255, .12);
}

/* FIELDS. The in-table quantity boxes get the same treatment as the forecast's month keys. */
#panel-planner .cell-input,
#panel-active .cell-input,
#panel-planner input[type="text"],
#panel-planner input[type="number"],
#panel-planner input[type="search"] {
  background: rgba(5, 9, 15, .75);
  border: 1px solid var(--hud-line);
  border-radius: 7px;
  color: var(--hud-digit);
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
}
#panel-planner .cell-input:focus,
#panel-active .cell-input:focus,
#panel-planner input:focus {
  outline: none;
  border-color: var(--hud);
  background: rgba(54, 209, 255, .06);
  box-shadow: 0 0 18px rgba(54, 209, 255, .26);
}
#panel-planner .checkfield label,
#panel-active .checkfield label { color: var(--ink-dim); }
#panel-planner input[type="checkbox"],
#panel-active input[type="checkbox"] { accent-color: var(--hud); }

/* The line above the table that counts what is covered, buildable and blocked — the screen's one
   sentence of prose, so it is seated rather than glowing, with its figures picked out. */
#panel-planner .summary-line {
  color: var(--ink-dim);
  border-left: 2px solid var(--hud-line);
  padding-left: 10px;
}
#panel-planner .summary-line b {
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
  color: var(--hud-digit);
}

/* MY WORKSHOP's board. Most of it already draws from --line, --accent and --ink-dim, so the token
   re-point above carries it; these are the few places that need the instrument face rather than
   the app's. */
#panel-active .wb-head { color: var(--hud); }
#panel-active .wb-row { border-top-color: rgba(54, 209, 255, .12); }
#panel-active .wb-row:last-child { border-bottom-color: rgba(54, 209, 255, .12); }
#panel-active .wb-row:hover { background: rgba(54, 209, 255, .04); }
#panel-active .wb-row.dragging {
  background: rgba(54, 209, 255, .10);
  box-shadow: 0 0 0 1px var(--hud), 0 10px 30px rgba(0, 0, 0, .6);
}
#panel-active .wb-pn { color: var(--ink-dim); }
#panel-active .wb-prog-n,
#panel-active .wb-logged { color: var(--hud-digit); }
#panel-active .wb-logged.live { color: #35b7ce; text-shadow: 0 0 16px rgba(53, 183, 206, .45); }
#panel-active .wb-bar { background: rgba(54, 209, 255, .14); }
#panel-active .wb-bar span { background: var(--hud); box-shadow: 0 0 10px rgba(54, 209, 255, .6); }
/* (.mb-bar is the ØRGANISER's compact bench, which lives OUTSIDE every panel and keeps the app's
   light voice — the two rules that named it here were dead code.) */
/* The initials are the one place a person's name appears on this screen, so they get the mono face
   and read as channel selects on a desk. */
#panel-active .wb-init {
  font-family: var(--hud-mono);
  border-color: var(--hud-line);
  color: var(--ink-dim);
  background: rgba(5, 9, 15, .6);
}
#panel-active .wb-init.on { border-color: var(--hud); color: var(--hud-bright); background: rgba(54, 209, 255, .10); }
#panel-active .wb-init.ticking {
  border-color: #35b7ce; color: #35b7ce;
  box-shadow: 0 0 0 1px rgba(53, 183, 206, .45), 0 0 14px rgba(53, 183, 206, .35);
}
#panel-active .wb-grip { color: var(--hud-dim); }
#panel-active .wb-grip:hover { color: var(--hud); }

/* The whole-shop clock board keeps the same hairlines as everything else. */
#panel-active .ws-board { color: var(--ink); }
/* (the clock board's rail: the four-side border-color shorthand that stood here at ID specificity
   was wiping the running/paused rail — THE trap from the memory note. Restated with longhands at the
   end of the file.) */

/* ----------------------------------------------------------------------------------------------
   THE PROTOCOLS, not just the paint (Steve, 17 Sep 2026: "still not right ... please use same
   design protocols that we've developed in hydros live").

   Three things were wrong, and all three are things HYDROS Live already decided:

   1. THE FIELD HAD NO BEZEL. The dark field began exactly where the title began — a hard
      vertical edge with the words sitting on it. The first fix ran the field out to the edges of
      the page, which was the wrong reading: Steve sent a crop of HYDROS Live's own boundary, and
      it is NOT full-bleed. It is a console bezel — 3px cyan border, 18px radius, 20/22/30px of
      padding inside, a glow outside — set into the light page with the sidebar toggle sitting
      beside it. The rule is copied from #panel-hydros in styles.css ("A proper console bezel
      around the module instead of a hairline edge"), not re-imagined.

   2. THE TITLE WAS NOT A TITLE PLATE. #panel-hydros sets uppercase, .06em tracking and a cyan
      glow on h1 — that is what makes it read as a channel name on an instrument. Mine was left in
      sentence case, which is the app's voice, not the HUD's.

   3. THE CHIPS WERE OUTLINED. The rule written into the HYDROS block above is explicit: colour is
      carried by fill AND ring AND glow — "three channels, which survives a sunlit phone screen
      better than colour alone". I had made them outline-only, which is the opposite of the
      protocol. A workshop is exactly the sunlit-phone case it was written for.
   ---------------------------------------------------------------------------------------------- */

/* 1. THE BEZEL — verbatim from #panel-hydros (styles.css). overflow: hidden is the one addition:
      the field's grid, the vignette and the scan bar are all painted on this box, and a rounded
      bezel with square-cornered paint inside it is exactly the kind of seam this fixes. Nothing
      that needs to escape the box lives in it — the sheet, the popups and the tour all mount on
      <body>. */
.hud-screen {
  border: 3px solid rgba(54, 209, 255, .45);
  border-radius: 18px;
  padding: 20px 22px 30px;
  overflow: hidden;
  box-shadow:
    0 0 0 1px rgba(8, 16, 26, .9),
    0 0 44px rgba(54, 209, 255, .18),
    0 22px 60px rgba(0, 0, 0, .55);
}
@media (max-width: 760px) {
  /* A 3px bezel and 22px of padding on a 375px phone would spend 50px of the width on frame.
     Thinner and tighter, but still a bezel — the shape is the protocol, the millimetres are not. */
  .hud-screen {
    border-width: 2px;
    border-radius: 14px;
    padding: 14px 12px 22px;
  }
}

/* 2. THE TITLE PLATE — the same rule as #panel-hydros .page-head h1. */
.hud-screen .page-head h1 {
  font-family: var(--font-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-shadow: 0 0 26px rgba(54, 209, 255, .35);
}

/* 3. CHIPS: fill AND ring AND glow, as the HYDROS block sets out. These come after the outlined
      versions further up and deliberately override them. */
.hud-screen .chip {
  font-family: var(--hud-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.hud-screen .chip.ok {
  background-color: rgba(0, 214, 160, .14); border-color: var(--good, #00d6a0); color: #35b7ce;
  box-shadow: 0 0 14px rgba(0, 214, 160, .35), inset 0 0 10px rgba(0, 214, 160, .12);
}
.hud-screen .chip.warn {
  background-color: rgba(255, 192, 77, .14); border-color: #ffc04d; color: #ffc04d;
  box-shadow: 0 0 14px rgba(255, 192, 77, .38), inset 0 0 10px rgba(255, 192, 77, .14);
}
.hud-screen .chip.crit {
  background-color: rgba(255, 95, 109, .16); border-color: #ff5f6d; color: #ff8a93;
  box-shadow: 0 0 18px rgba(255, 95, 109, .5), inset 0 0 12px rgba(255, 95, 109, .18);
}


/* ==============================================================================================
   THE PRODUCTION SCREENS — corrections from the 17 Sep 2026 audit, and Serial / F.A.T.
   ==============================================================================================
   Five auditors read the two style-guide sources, then every production page, and two verifiers
   checked every selector against the markup and every rule against the three traps that bit that
   day (the shorthand that wipes state colour, an inherited overflow clip, specificity that loses
   to styles.css). What follows is what survived, with the verifiers' fixes applied. Fabrication
   Procedures and the Production Logbook are being deleted, so nothing here names them.
   ============================================================================================== */

/* ---- 2. Complete the token re-point ----------------------------------------------------------
   The block re-pointed --warn and --accent only. Every consumer of the other six fell through to
   :root's LIGHT values inside the dark field — a teal running rail, a pale-mint slab, a brick
   error line, a navy link on near-black. Values verbatim from #panel-hydros. color-scheme: dark
   makes the native controls (date-picker icon, checkbox glyph, number spinners, <select> popups)
   draw dark too — "inputs inside the module have to be dark too, or they punch white holes in it". */
.hud-screen {
  --good: #00d6a0;
  --good-bg: #06271f;
  --crit: #ff5f6d;
  --crit-bg: #2e131a;
  --accent-strong: #36d1ff;
  --accent-hover: #7ae2ff;
  color-scheme: dark;
}
/* A link the operator cannot read is the opposite of "LOUDER than it went in". */
.hud-screen a { color: var(--hud-bright); }
.hud-screen a:hover { text-shadow: 0 0 16px rgba(54, 209, 255, .45); }

/* ---- 3. Sticky table headers must be opaque ---------------------------------------------------
   styles.css keeps th position: sticky inside the 560px .table-scroll; the block's 4% tint let the
   rows scroll straight through the header. The tint now rides on a background-image over an opaque
   background-color, so the seat and the hairline coexist. */
.hud-screen table th {
  background-color: #0e1620;
  background-image: linear-gradient(rgba(54, 209, 255, .05), rgba(54, 209, 255, .05));
}
.hud-screen .table-scroll,
.hud-screen .table-wrap { border-color: var(--hud-line); }
/* A clickable register row is a control, so it lifts a little more than a plain one. */
#panel-serials tr.cp-row:hover td, #panel-fat tr.cp-row:hover td { background-color: rgba(54, 209, 255, .07); }

/* ---- 4. The whole-shop clock board on My Workshop ---------------------------------------------
   THE REPAIR, again: the block had `#panel-active .ws-row { border-color: … }` — the four-side
   shorthand at ID specificity, which wiped the running/paused rail from styles.css on the one board
   the shop watches all day. Ground, rail and glow restated here with longhands; state on three
   channels. That shorthand rule is deleted in the same change. */
#panel-active .ws-board { color: var(--ink); }
#panel-active .ws-row {
  position: relative;
  background-color: transparent;
  background-image: linear-gradient(180deg, rgba(20, 29, 42, .92), rgba(13, 20, 30, .92));
  border-top-color: rgba(54, 209, 255, .14);
  border-right-color: rgba(54, 209, 255, .14);
  border-bottom-color: rgba(54, 209, 255, .14);
  border-left-width: 4px;
  border-left-color: var(--hud-line);
  box-shadow: inset 3px 0 12px -6px var(--hud);
  opacity: 1;   /* base .paused dims the whole row including its keys; state travels on rail, lamp and clock instead */
}
#panel-active .ws-row.running {
  border-left-color: var(--good);
  background-image: linear-gradient(90deg, rgba(0, 214, 160, .10), rgba(13, 20, 30, .92) 45%);
  box-shadow: inset 4px 0 14px -7px var(--good), 0 0 16px rgba(0, 214, 160, .10);
}
#panel-active .ws-row.paused {
  border-left-color: var(--warn);
  background-image: linear-gradient(90deg, rgba(224, 176, 76, .10), rgba(13, 20, 30, .92) 45%);
  box-shadow: inset 4px 0 16px -6px var(--warn);
  opacity: 1;
}
/* The clock is this board's headline number: mono, tabular, lit while it runs, seated while paused. */
#panel-active .ws-clock {
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  color: var(--hud-digit);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .75);
}
#panel-active .ws-row.running .ws-clock { color: #35b7ce; text-shadow: 0 0 16px rgba(53, 183, 206, .45); }
#panel-active .ws-row.paused .ws-clock { color: var(--ink-dim); text-shadow: none; }
/* The Running / Paused word becomes a lamp chip — fill AND ring AND glow. */
#panel-active .ws-status {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px; border-radius: 999px;
  border-width: 1px; border-style: solid; border-color: var(--hud-line);
  font-family: var(--hud-mono); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
#panel-active .ws-status::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; flex: none;
  background-color: currentColor; box-shadow: 0 0 8px currentColor;
}
#panel-active .ws-status.ok {
  background-color: rgba(0, 214, 160, .14); border-color: var(--good); color: #35b7ce;
  box-shadow: 0 0 14px rgba(0, 214, 160, .35), inset 0 0 10px rgba(0, 214, 160, .12);
}
#panel-active .ws-status.low {
  background-color: rgba(255, 192, 77, .14); border-color: #ffc04d; color: #ffc04d;
  box-shadow: 0 0 14px rgba(255, 192, 77, .38), inset 0 0 10px rgba(255, 192, 77, .14);
}
#panel-active .ws-who { font-family: var(--hud-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--hud-bright); }
#panel-active .ws-what { color: var(--ink); font-weight: 600; }

/* ---- 5. The two chip tones the block never restyled, the dots, the crit heartbeat ------------
   .chip.low and .chip.neutral are what the Planner actually emits; the block's outlined rule
   flattened them. background-color at (1,2,0) outranks both the base and the block. */
.hud-screen .chip.low {
  background-color: rgba(255, 192, 77, .14);
  border-color: #ffc04d;
  color: #ffc04d;
  box-shadow: 0 0 14px rgba(255, 192, 77, .38), inset 0 0 10px rgba(255, 192, 77, .14);
}
/* neutral is a statement, not a state: seated, no glow. */
.hud-screen .chip.neutral {
  background-color: rgba(157, 182, 205, .08);
  border-color: rgba(157, 182, 205, .35);
  color: var(--ink-dim);
  box-shadow: none;
}
/* The 6px dot follows whatever the chip's state set. */
.hud-screen .chip::before {
  background-color: currentColor;
  box-shadow: 0 0 6px currentColor;
}
/* "1.6s is a heartbeat, not a strobe" — the HYDROS block gives .chip.crit the pulse; this one did not. */
.hud-screen .chip.crit {
  animation: hudAlarm 1.6s ease-in-out infinite;
}

/* ---- 8. Serial Number Generator and Factory Acceptance Testing ------------------------------
   F.A.T. has sticky back bars; sticky scopes to the nearest scroll container, and the bezel's
   overflow: hidden would make the panel that container. overflow: clip clips the field paint at
   the radius without making a scrollport. After the widened bezel rule, so it wins. */
#panel-fat { overflow: clip; }
@media (max-width: 760px) {
  #panel-fat .cp-back-bar {
    background-color: rgba(5, 9, 15, .92);
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
    border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: var(--hud-line);
  }
}
#panel-fat .cp-back-bar .btn { font-family: var(--hud-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; }

/* Phones: HYDROS Live stops the field drift and the sweep below 620px; all five panels follow. */
@media (max-width: 620px) {
  .hud-screen { --hud-bracket: 9px; animation: none; }
  .hud-screen::after { display: none; }
}

/* READOUTS: on these two pages the serial IS the value, not a sub-label — so .id is a readout here
   (the widened .id rule deliberately does not include these ids). Slashed zero: P1B-0 must never
   read as P1B-O. */
.hud-screen .id {
  font-family: var(--hud-mono);
  font-variant-numeric: tabular-nums slashed-zero;
  letter-spacing: .02em;
  color: var(--hud-digit);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .75);
}

/* FORMS. With color-scheme: dark the date-picker icon draws light on the dark well. */
.hud-screen input, .hud-screen select, .hud-screen textarea {
  background-color: rgba(6, 12, 20, .85);
  background-image: none;
  border-color: var(--hud-line);
  color: var(--ink);
  transition: border-color .18s, box-shadow .18s;
}
.hud-screen input:focus, .hud-screen select:focus, .hud-screen textarea:focus {
  outline: none;
  border-color: var(--hud);
  box-shadow: 0 0 0 3px rgba(54, 209, 255, .16), 0 0 18px rgba(54, 209, 255, .2);
}
.hud-screen ::placeholder { color: #46617c; }
.hud-screen .field > label { font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-dim); }
/* Values typed into the record are readouts. */
#panel-serials input[type="date"], #panel-fat input[type="date"],
#panel-fat .fat-check-value, #panel-fat .fat-cal-reading, #panel-fat textarea.paste-box { font-family: var(--hud-mono); font-variant-numeric: tabular-nums; color: var(--hud-digit); }
/* The Pass / Fail selects read as a console key face — but the 11px only above phone width, or
   every one of the ~100 selects would trigger iOS's zoom-on-focus (the 16px phone guard is (0,0,1)). */
#panel-fat select.fat-dev-res, #panel-fat select.fat-check-res { font-family: var(--hud-mono); letter-spacing: .06em; text-transform: uppercase; }
@media (min-width: 761px) {
  #panel-fat select.fat-dev-res, #panel-fat select.fat-check-res { font-size: 11px; }
}
/* A completed record disables every cell: keep the well, dim the face, never hide the value. */
#panel-fat input:disabled, #panel-fat select:disabled { opacity: .55; }

/* Personnel ticks read as channel selects on a desk; the name stays sentence case. */
#panel-fat .cp-tech-checks .checkfield { background-color: rgba(20, 29, 42, .85); border-color: var(--hud-line); }
#panel-fat .cp-tech-checks .checkfield:hover { border-color: var(--hud); box-shadow: 0 0 14px rgba(54, 209, 255, .25); }
#panel-fat .cp-tech-checks .checkfield label { color: var(--ink); }
#panel-fat .fieldnote-bar { border-top-color: var(--hud-line); }

/* The LIVE banner: this page can move plant. A state, not an alarm — steady ring and glow, no pulse. */
#panel-fat .fat-live-banner {
  background-color: rgba(54, 209, 255, .07);
  border-color: var(--hud);
  color: var(--ink);
  box-shadow: 0 0 18px rgba(54, 209, 255, .18), inset 0 0 14px rgba(54, 209, 255, .06);
}
#panel-fat .fat-live-banner > b:first-child { font-family: var(--hud-mono); letter-spacing: .16em; color: var(--hud-bright); text-shadow: 0 0 14px rgba(54, 209, 255, .5); }

/* STATE on the per-device live slot, repainted every 15 s: ring via box-shadow so the chip's
   geometry never changes under a repaint; every state restated at (1,2,0) because the base states
   are (0,2,0) `background` shorthands. hudAlarm at 1.6 s is the only motion inside a slot. */
#panel-fat .fat-live-chip { font-family: var(--hud-mono); letter-spacing: .1em; text-transform: uppercase; }
#panel-fat .fat-live-chip.on {
  background-color: rgba(0, 214, 160, .18); color: #bfffe9;
  box-shadow: 0 0 0 1px var(--good), 0 0 14px rgba(0, 214, 160, .35), inset 0 0 10px rgba(0, 214, 160, .12);
}
#panel-fat .fat-live-chip.off { background-color: rgba(157, 182, 205, .08); color: var(--ink-dim); box-shadow: 0 0 0 1px var(--hud-line); }
#panel-fat .fat-live-chip.ok { background-color: rgba(0, 214, 160, .12); color: var(--good); box-shadow: 0 0 0 1px var(--good), 0 0 10px rgba(0, 214, 160, .25); }
#panel-fat .fat-live-chip.bad {
  background-color: rgba(255, 95, 109, .16); color: #ff8a93;
  box-shadow: 0 0 0 1px var(--crit), 0 0 18px rgba(255, 95, 109, .5), inset 0 0 12px rgba(255, 95, 109, .18);
  animation: hudAlarm 1.6s ease-in-out infinite;
}
#panel-fat .fat-live-chip.pend { background-color: rgba(224, 176, 76, .14); color: var(--warn); box-shadow: 0 0 0 1px var(--warn), 0 0 14px rgba(224, 176, 76, .35); }

/* The planner's .linkish voice for the one link on these pages, "Open its Care Plan". */
#panel-fat .cp-item-meta a { color: var(--hud-bright); border-bottom: 1px dotted var(--hud-dim); text-decoration: none; }
#panel-fat .cp-item-meta a:hover { border-bottom-color: var(--hud); text-shadow: 0 0 16px rgba(54, 209, 255, .45); }

/* ---- 9. The two F.A.T. pop-ups on .hy-scrim, and the HYDROS Live → Setup card that leads to F.A.T.
   Micro-labels for the counts and keys, readouts for the designators, fill AND ring AND glow for the
   evidence tiles, and the alarm pulse only on a watchdog reporting a problem while a device is held
   ON — "the only fast, bright, attention-taking motion in the whole file is on a critical alarm". */
.hy-scrim .hy-devmodal .hy-gmodal-head b { font-family: var(--hud-mono); font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--hud); }
.hy-scrim .fat-walk-count { font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .16em; color: var(--hud); }
.hy-scrim .fat-walk-name { letter-spacing: .04em; text-transform: uppercase; text-shadow: 0 0 22px rgba(54, 209, 255, .35); }
.hy-scrim .fat-walk-bar { background-color: rgba(54, 209, 255, .14); }
.hy-scrim .fat-walk-bar > div { background-color: var(--hud); box-shadow: 0 0 10px rgba(54, 209, 255, .6); }
.hy-scrim .fat-walk-id { border-bottom-color: rgba(54, 209, 255, .12); }
.hy-scrim .fat-walk-id-k { font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; }
.hy-scrim .fat-walk-id-v .id { font-family: var(--hud-mono); font-variant-numeric: tabular-nums slashed-zero; color: var(--hud-digit); text-shadow: 0 1px 0 rgba(0, 0, 0, .75); }
.hy-scrim .fat-walk-id-h { font-family: var(--hud-mono); font-size: 10px; letter-spacing: .06em; }
.hy-scrim .fat-walk-ev {
  font-family: var(--hud-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  background-color: rgba(20, 29, 42, .85); border-color: var(--hud-line);
}
.hy-scrim .fat-walk-ev.on {
  background-color: rgba(0, 214, 160, .14); border-color: var(--good); color: var(--good);
  box-shadow: 0 0 14px rgba(0, 214, 160, .35), inset 0 0 10px rgba(0, 214, 160, .12);
}
.hy-scrim .fat-walk-ev.bad {
  background-color: rgba(255, 95, 109, .16); border-color: var(--crit); color: var(--crit);
  box-shadow: 0 0 18px rgba(255, 95, 109, .5), inset 0 0 12px rgba(255, 95, 109, .18);
  animation: hudAlarm 1.6s ease-in-out infinite;
}
.hy-scrim .fat-walk-note { background-color: rgba(54, 209, 255, .06); border-left-width: 2px; border-left-style: solid; border-left-color: var(--hud-line); }
.hy-scrim .fat-walk-note.warn { background-color: rgba(255, 192, 77, .10); border-left-color: var(--warn); color: #ffd894; }
.hy-scrim .fat-walk-log, .hy-scrim .fat-live-log { font-family: var(--hud-mono); font-size: 11.5px; }
/* The unattended run's tally. The device name is a READOUT (it is what the plant calls the thing),
   the reason stays in the body voice, and only a real failure gets the coral — a row waiting on a
   person is not an alarm and must not read like one. Longhand colours only: .fat-run-row carries
   its state in a class, so a border shorthand here would throw that away. */
.hy-scrim .fat-run-list { border-color: var(--hud-line); background-color: rgba(5, 9, 15, .55); }
.hy-scrim .fat-run-row { border-bottom-color: rgba(54, 209, 255, .12); }
.hy-scrim .fat-run-dev { font-family: var(--hud-mono); letter-spacing: .06em; color: var(--hud-bright); }
.hy-scrim .fat-run-why { font-size: 12px; }
.hy-scrim .fat-run-row.fail .fat-run-dev { color: #ff8a93; }
.hy-scrim .fat-run-now { font-family: var(--hud-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--hud); }
.hy-scrim .fat-live-log { background-color: rgba(5, 9, 15, .8); border-width: 1px; border-style: solid; border-color: var(--hud-line); }
/* Inside #panel-hydros the field, card and key rules already apply; the serial is a READOUT (it
   had no base rule at all) and the status word beside it a LABEL. */
#panel-hydros .hy-fat-unit { border-bottom-color: rgba(54, 209, 255, .12); }
#panel-hydros .hy-fat-serial .id { font-family: var(--hud-mono); font-variant-numeric: tabular-nums slashed-zero; color: var(--hud-digit); text-shadow: 0 1px 0 rgba(0, 0, 0, .75); }
#panel-hydros .hy-fat-status { font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-dim); }
/* Delete keeps the coral it has in the light skin; History's sub-headings take the title-plate
   voice the block gives every other heading on these screens. */
#panel-hydros .btn.ghost.hy-fat-del { color: #ff8a93; }
#panel-hydros .btn.ghost.hy-fat-del:hover { border-color: var(--crit); box-shadow: 0 0 14px rgba(255, 95, 109, .3); }
#panel-hydros .hy-hist-sub > h3 { letter-spacing: .06em; text-transform: uppercase; text-shadow: 0 0 22px rgba(54, 209, 255, .35); }

/* ---- 10. Reduced motion: keep the light, keep the alarms ------------------------------------
   styles.css turns every animation off globally with !important, and the machine this was built on
   reports the preference — so the block's earlier reduced-motion rule was inert and the bezels were
   still pictures while HYDROS Live drifted. The HYDROS form: light is kept (the drift, the sweep, the
   glow rising and falling) and the alarms carry meaning and are never switched off; every slide,
   scale and wipe is taken away. !important because styles.css's rule is. */
@media (prefers-reduced-motion: reduce) {
  .hud-screen { animation: hudField 40s linear infinite !important; }
  .hud-screen::after { animation: hudSweepDown 18s linear infinite !important; opacity: .6; }
  #panel-forecast .stat.s-warn::after, #panel-planner .stat.s-warn::after, #panel-active .stat.s-warn::after { animation: fcAlert 3.2s ease-in-out infinite !important; }
  .hud-screen .chip.crit,
  #panel-fat .fat-live-chip.bad,
  .hy-scrim .fat-walk-ev.bad { animation: hudAlarm 2.4s ease-in-out infinite !important; }
  /* the tile rise translates, so it stays off — but the tiles must still land visible */
  .hud-screen .stat { animation: none !important; opacity: 1; transform: none; }
}

/* ---- 11. Keys on a bench tablet: the 44px minimum HYDROS gives its own small keys -----------
   Sizes only; colour and state stay with the widened KEYS rule. My Workshop's own row keys and the
   crew ticks are the most-pressed controls on that page. */
@media (max-width: 620px) {
  #panel-active .btn.sm, #panel-serials .btn.sm, #panel-fat .btn.sm { min-height: 44px; min-width: 44px; }
  #panel-active .wb-btn { min-height: 44px; }
  #panel-active .wb-init { min-width: 44px; min-height: 40px; }
}

/* ---- 12. The module owns its scrollbar ------------------------------------------------------
   Scoped to the module so the rest of the app keeps the browser default. Firefox takes the
   two-value form; WebKit needs the pseudo-elements. */
.hud-screen, .hud-screen * {
  scrollbar-width: thin;
  scrollbar-color: #2f4a67 transparent;
}
.hud-screen ::-webkit-scrollbar { width: 10px; height: 10px; }
.hud-screen ::-webkit-scrollbar-track { background-color: transparent; }
.hud-screen ::-webkit-scrollbar-thumb {
  background-color: #2f4a67; border-radius: 999px; border: 2px solid transparent; background-clip: content-box;
}
.hud-screen ::-webkit-scrollbar-thumb:hover { background-color: #3f6288; background-clip: content-box; }
.hud-screen ::-webkit-scrollbar-corner { background-color: transparent; }

/* ---- 13. Polish: Forecast's two-tile row gets two columns, not four --------------------------- */
/* ==============================================================================================
   MY SITE WORK and MY TRAINING — two more channels (Steve, 17 Sep 2026: "please reskin My Sitework
   and My training. follow the design of My Workshop, that works well.")
   ==============================================================================================

   Everything structural is already done by the time you get here: both panels wear .hud-screen, so
   they have the field, the bezel, the title plate, the chips, the buttons and the inputs. A visit
   card and a policy item are declared as glass panels alongside .card above, so they have the lit
   edge, the scanlines and the corner brackets.

   What is left is the TYPOGRAPHY — the part that decides whether a screen reads as an instrument or
   as a web page wearing an instrument's paint. Same rule as everywhere else in this file: the thing
   you came to read gets louder, and every label around it steps back into mono, uppercase and dim.
   ============================================================================================== */

/* A section heading ("Started, not closed out" / "Next 4 weeks") is a channel label, not a title. */
.hud-screen .mg-sub {
  font-family: var(--hud-mono);
  font-size: 9.5px;
  letter-spacing: .16em;
  color: var(--hud);
  text-shadow: 0 0 14px rgba(54, 209, 255, .35);
}

/* THE SITE NAME IS THE THING YOU ARE LOOKING FOR. On a visits board you are scanning for a place,
   so the place is the loudest thing on the card and everything else is subordinate to it. */
.hud-screen .visit-site {
  color: var(--ink);
  letter-spacing: .04em;
  text-shadow: 0 0 22px rgba(54, 209, 255, .28);
}
.hud-screen .visit-title { color: var(--ink); }
.hud-screen .visit-meta {
  font-family: var(--hud-mono);
  font-size: 10.5px;
  letter-spacing: .06em;
  color: var(--ink-dim);
}
/* UNDERWAY is the one state on this screen that should take attention, so it is the only thing that
   is lit. Same reasoning as ORDERS OVERDUE on the forecast: one alarm per screen or none of them
   mean anything. Note the LONGHAND — border-left-color, not the "border-left" shorthand, which at
   this specificity would wipe the width the base rule sets and the stripe would vanish. */
.hud-screen .visit-card.underway {
  border-left-width: 4px;
  border-left-color: var(--good, #00d6a0);
  box-shadow:
    0 0 0 1px rgba(0, 214, 160, .10),
    0 14px 34px rgba(0, 0, 0, .55),
    0 0 44px rgba(0, 214, 160, .10);
}
.hud-screen .visit-card.underway::after { background:
    linear-gradient(var(--good), var(--good)) left  top    / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--good), var(--good)) left  top    / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--good), var(--good)) right top    / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--good), var(--good)) right top    / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--good), var(--good)) left  bottom / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--good), var(--good)) left  bottom / var(--hud-bracket) 2px no-repeat,
    linear-gradient(var(--good), var(--good)) right bottom / 2px var(--hud-bracket) no-repeat,
    linear-gradient(var(--good), var(--good)) right bottom / var(--hud-bracket) 2px no-repeat;
}
/* The base rule lifts the card 1px on hover. Kept — it is the one piece of feedback saying the whole
   card is the tap target — and the lit frame is added to it rather than replacing it. */
.hud-screen .visit-card:hover { border-color: var(--hud); }

/* MY TRAINING. A policy is a document you must read, so the title carries and the revision beside
   it is a part number: mono, tabular, dim. */
.hud-screen .policy-title {
  color: var(--ink);
  letter-spacing: .02em;
  text-shadow: 0 0 20px rgba(54, 209, 255, .22);
}
.hud-screen .policy-meta { color: var(--ink-dim); }
.hud-screen .policy-meta.signed-note { color: var(--good, #00d6a0); }
.hud-screen .policy-statement {
  color: var(--ink-dim);
  border-left: 2px solid var(--hud-dim);
  padding-left: 10px;
  font-style: normal;
}
.hud-screen .policy-sign { border-top-color: var(--hud-line); }
/* The signing box is the one place on this screen where somebody commits to something. It gets the
   weight: a lit field, and a name box that reads like a readout rather than a form field. */
.hud-screen .policy-sign-row input[type="text"] {
  font-family: var(--hud-mono);
  letter-spacing: .06em;
  color: var(--hud-digit);
}
.hud-screen .checkfield label { color: var(--ink); }
.hud-screen input[type="checkbox"] { accent-color: var(--hud); }

/* "Nothing of yours in the next 4 weeks" and friends. An empty state on a black field needs to be
   legible without pretending to be data. */
.hud-screen .empty-note { color: var(--ink-dim); font-family: var(--hud-mono); font-size: 11px; letter-spacing: .04em; }

/* A tap target on a gloved hand. Same 44px as the rest of the module. */
@media (max-width: 760px) {
  .hud-screen .visit-card { padding: 16px 16px; }
  .hud-screen .policy-sign-row input[type="text"] { min-width: 0; width: 100%; }
}

/* ==============================================================================================
   THE TRAINING SIGN-OFF WINDOW
   ==============================================================================================

   Steve, 17 Sep 2026: "each one of these training items needs to have a sign button, which brings up
   a popup window that asks people to confirm that they have read and understood the document, they
   confirm they have no further questions and then click a button to confirm that they agree to
   abide by the requirements", and "make it so that people cannot click the signoff button unless
   they have actually opened the document first."

   It wears .hy-scrim, so the scrim colour, the inputs and the buttons are already the console's —
   this block is the window itself. Three numbered steps, and each one unlocks the next: at any
   moment there is exactly one thing to do, which is the opposite of the stacked-up inline forms it
   replaces.

   The ✕ sits far right on the title bar, per the standing rule (Steve, 17 Sep 2026: "all X's for
   closing windows should be far right on the top bar, like all standard windows"). `all: unset`
   comes FIRST in that rule — declared after margin-left it would wipe it, which is exactly how the
   instruction sheet's ✕ ended up in the wrong place once already.
   ============================================================================================== */
.tsign-scrim { z-index: 900; padding: 16px; }
.tsign-card {
  width: min(560px, 96vw); max-height: 92vh; display: flex; flex-direction: column;
  background: linear-gradient(180deg, var(--hud-glass-a, rgba(19, 29, 43, .97)), var(--hud-glass-b, rgba(11, 18, 28, .97)));
  border: 1px solid rgba(54, 209, 255, .35); border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(8, 16, 26, .9), 0 0 44px rgba(54, 209, 255, .16), 0 24px 70px rgba(0, 0, 0, .6);
  color: var(--ink, #eaf6fe);
}
.tsign-head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 16px; border-bottom: 1px solid rgba(54, 209, 255, .18);
}
.tsign-head h2 {
  margin: 0; font-family: var(--font-display); font-size: 16px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink, #eaf6fe); text-shadow: 0 0 22px rgba(54, 209, 255, .3);
}
.tsign-rev {
  display: block; margin-top: 3px; font-family: var(--hud-mono, ui-monospace, monospace);
  font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-dim, #9db6cd);
}
.tsign-x {
  all: unset; margin-left: auto; cursor: pointer; flex: none;
  width: 30px; height: 30px; line-height: 30px; text-align: center; border-radius: 8px;
  font-size: 20px; color: var(--ink-dim, #9db6cd); border: 1px solid rgba(54, 209, 255, .22);
}
.tsign-x:hover { color: var(--ink, #eaf6fe); border-color: var(--hud, #36d1ff); background: rgba(54, 209, 255, .10); }
.tsign-body { padding: 16px; overflow-y: auto; }

/* A step number, so the sequence is visible rather than implied. */
.tsign-lead {
  display: flex; align-items: center; gap: 9px; margin: 16px 0 8px;
  font-family: var(--hud-mono, ui-monospace, monospace); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--hud, #36d1ff);
}
.tsign-lead:first-child { margin-top: 0; }
.tsign-step {
  display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border-radius: 50%; border: 1px solid var(--hud, #36d1ff); color: var(--hud, #36d1ff);
  font-size: 10px; box-shadow: 0 0 12px rgba(54, 209, 255, .3); flex: none;
}

/* STEP 1 is the whole point of the gate, so it is the biggest thing in the window until it is done,
   and it visibly changes state once it is. */
.tsign-doc { margin-bottom: 4px; }
.tsign-open {
  display: block; text-align: center; padding: 14px 16px; border-radius: 10px;
  border: 1px solid var(--hud, #36d1ff); color: var(--hud-bright, #7ae2ff) !important;
  background: rgba(54, 209, 255, .10); text-decoration: none;
  font-family: var(--hud-mono, ui-monospace, monospace); font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; box-shadow: 0 0 22px rgba(54, 209, 255, .22);
}
.tsign-open:hover { background: rgba(54, 209, 255, .18); box-shadow: 0 0 30px rgba(54, 209, 255, .4); }
.tsign-open.done {
  border-color: var(--good, #00d6a0); color: var(--good, #00d6a0) !important;
  background: rgba(0, 214, 160, .10); box-shadow: 0 0 18px rgba(0, 214, 160, .22);
}
.tsign-nofile, .tsign-gate {
  display: block; font-size: 12px; color: var(--warn, #e0b04c); margin-top: 8px; line-height: 1.5;
}

/* A term is a sentence somebody is signing, so it is set as text and not as a form label — full
   size, full contrast, and the whole row is the tap target. */
.tsign-term {
  display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
  padding: 11px 12px; margin-bottom: 8px; border-radius: 10px;
  border: 1px solid rgba(54, 209, 255, .18); background: rgba(54, 209, 255, .03);
  font-size: 13.5px; line-height: 1.5; color: var(--ink, #eaf6fe);
}
.tsign-term:hover { border-color: rgba(54, 209, 255, .4); }
.tsign-term input { accent-color: var(--hud, #36d1ff); width: 18px; height: 18px; margin-top: 1px; flex: none; }
.tsign-term.locked { opacity: .45; cursor: not-allowed; }
.tsign-term.locked:hover { border-color: rgba(54, 209, 255, .18); }

.tsign-name {
  width: 100%; box-sizing: border-box; padding: 11px 13px; border-radius: 10px;
  font-family: var(--hud-mono, ui-monospace, monospace); letter-spacing: .06em; font-size: 14px;
}

/* THE SIGNATURE. Its label IS the third term — the press is the agreement, so the words somebody
   agrees to are the words on the button they press, not a sentence somewhere above it. */
.tsign-go {
  all: unset; box-sizing: border-box; display: block; width: 100%; margin-top: 12px; cursor: pointer;
  padding: 15px 18px; border-radius: 12px; text-align: center;
  border: 1px solid var(--hud, #36d1ff); background: rgba(54, 209, 255, .14);
  color: var(--hud-bright, #7ae2ff); font-size: 14px; font-weight: 600; line-height: 1.45;
  box-shadow: 0 0 26px rgba(54, 209, 255, .25);
}
.tsign-go:hover:not(:disabled) { background: rgba(54, 209, 255, .24); box-shadow: 0 0 36px rgba(54, 209, 255, .45); }
.tsign-go:disabled {
  cursor: not-allowed; opacity: .4; border-color: rgba(54, 209, 255, .2);
  background: rgba(54, 209, 255, .04); box-shadow: none;
}
.tsign-note { margin: 12px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--ink-dim, #9db6cd); }
.tsign-body .error-note { margin-top: 10px; color: #e2695a; font-size: 12.5px; }

/* The button on the card that opens all this. */
.policy-gate {
  display: inline-block; margin-left: 10px; font-size: 11.5px; color: var(--warn, #e0b04c);
}

@media (max-width: 760px) {
  .tsign-card { width: 100%; max-height: 94vh; }
  .tsign-x { width: 44px; height: 44px; line-height: 44px; }
  .tsign-term { padding: 13px 12px; }
}

#panel-forecast #forecast-workshop-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) { #panel-forecast #forecast-workshop-stats { grid-template-columns: 1fr; } }

/* ==========================================================================================
   .st-screen - THE SYSTEM TEST SKIN
   ==========================================================================================
   Steve, 21 Sep 2026: "a unique schema to differentiate it from the normal operational
   schematic."

   THE ROOM CHANGES; THE STATE COLOURS DO NOT. This is one wrapper class that re-declares the
   whole token set, exactly as .hud-screen does - a PARTIAL re-point is a documented bug in this
   file, because anything left behind inherits the operational palette and the screen ends up
   half one thing and half the other.

   The field moves from cyan-on-black to bone-white ink on drafting indigo, over a still
   cross-hatch instead of the operational grid and scanlines. Bone-white and blue-grey are the
   only colour families nothing in this codebase already owns - green, amber, red, violet and
   teal are all spoken for by a state. So the ROOM is unmistakably different in a photograph
   while a fault still looks exactly like a fault.

   The operational screen breathes. This one does NOT: the plant is being held, and a still
   drawing says that better than any label. It also satisfies reduced-motion for free.

   THE ONE DIVERGENCE FROM THE OPERATIONAL SHEET, and it is safety-positive: a device commanded
   off here draws QUIET SLATE, not the operational pulsing red dashed ring. Under a System Test,
   held-off is the NORMAL condition of every device - twenty pulsing red hazards would swamp the
   one device under test and contradict this file's own law that if everything pulses, a pulse
   means nothing.
   ========================================================================================== */
.st-screen {
  /* the complete token set, re-declared */
  --paper: #0b1730;
  --surface: #10203f;
  --surface-2: #16294c;
  --line: #2c4470;
  --ink: #f2f6fc;
  --ink-dim: #a9bcd6;           /* 9.26:1 on --paper, above the 8.7:1 this file demands */
  --hud: #e3ecf7;
  --hud-bright: #ffffff;
  --hud-dim: rgba(227, 236, 247, .38);
  --hud-soft: rgba(227, 236, 247, .08);
  --hud-line: rgba(227, 236, 247, .26);
  --hud-glass-a: rgba(23, 37, 66, .94);
  --hud-glass-b: rgba(15, 26, 49, .94);
  --hud-digit: #ffffff;
  /* the five states this screen adds. Each re-uses a colour that already means this thing. */
  --st-held: #6f86a8;           /* commanded off - quiet, not a hazard */
  --st-test: #ffc400;           /* under test: the device IS forced on, so amber is the truth */
  --st-pass: #1f9e55;
  --st-fail: #ff5f6d;
  --st-eyes: #f2b24a;           /* needs a person - the same amber the Robo-Lab rig already uses */
  --st-out: rgba(169, 188, 214, .45);   /* not in this test */

  background-color: var(--paper);
  color: var(--ink);
  /* a draughtsman's cross-hatch, and it is STILL */
  background-image:
    repeating-linear-gradient(45deg, var(--hud-soft) 0 1px, transparent 1px 22px),
    repeating-linear-gradient(-45deg, var(--hud-soft) 0 1px, transparent 1px 22px);
}

/* the bezel geometry verbatim - 3px / 18px / 20-22-30 - with only the colour moved. That single
   swap is the strongest at-a-glance tell and costs no geometry. */
.st-screen .card {
  background-color: var(--surface);
  border: 3px solid rgba(227, 236, 247, .5);
  border-radius: 18px;
  box-shadow: 0 0 30px rgba(227, 236, 247, .14);
  overflow: visible;            /* protocol 4: brackets sit ON the frame and must not be clipped */
}
.st-screen .page-head h1 {
  font-family: var(--font-display, inherit);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--hud-bright);
  text-shadow: 0 0 26px rgba(227, 236, 247, .3);
}
.st-screen .page-head p { color: var(--ink-dim); }

/* protocol 3: a chip carries its state on FILL and RING and GLOW, never on one alone */
.st-screen .st-lamp.ok {
  background-color: rgba(31, 158, 85, .16);
  border-color: rgba(31, 158, 85, .7);
  box-shadow: 0 0 12px rgba(31, 158, 85, .3);
  color: #b8f0cf;
}
.st-screen .st-lamp.bad {
  background-color: rgba(255, 95, 109, .18);
  border-color: rgba(255, 95, 109, .8);
  box-shadow: 0 0 14px rgba(255, 95, 109, .35);
  color: #ffd4d8;
}
.st-screen .st-lamp.warn {
  background-color: rgba(242, 178, 74, .16);
  border-color: rgba(242, 178, 74, .7);
  box-shadow: 0 0 12px rgba(242, 178, 74, .28);
  color: #ffe4bd;
}
/* HELD and WAITING are statements, not states: seated, no glow. */
.st-screen .st-lamp.neutral,
.st-screen .st-lamp.unknown {
  background-color: rgba(227, 236, 247, .07);
  border-color: var(--hud-line);
  color: var(--ink-dim);
}

.st-screen .st-strip {
  background-color: var(--surface-2);
  border-color: var(--hud-line);
}
.st-screen .st-prog { background-color: rgba(227, 236, 247, .12); }
.st-screen .st-prog i { background-color: var(--st-test); }
.st-screen .st-count { color: var(--hud-bright); }
.st-screen .st-phase { color: var(--st-test); }
.st-screen .st-hint, .st-screen .st-checks-note { color: var(--ink-dim); }
.st-screen .st-off-chip {
  background-color: rgba(227, 236, 247, .06);
  border-color: var(--hud-line);
  color: var(--ink-dim);
}
.st-screen .st-off-chip.st-badge-pass { border-color: var(--st-pass); color: #b8f0cf; }
.st-screen .st-off-chip.st-badge-fail { border-color: var(--st-fail); color: #ffd4d8; }
.st-screen .st-off-chip.st-badge-eyes { border-color: var(--st-eyes); color: #ffe4bd; }

/* ---- the drawing -------------------------------------------------------------------------
   The HUD's own mimic rules are written #panel-hydros .hy-mimic …, so none of them reach here -
   this is #panel-fat. These are therefore the only paint the test drawing gets. */
.st-screen .hy-mimic .hy-vessel { fill: var(--surface-2); stroke: var(--hud-line); }
.st-screen .hy-mimic .hy-pipe { stroke: rgba(227, 236, 247, .22); }
.st-screen .hy-mimic .hy-lbl { fill: var(--ink-dim); }
/* the numeral paint-order seat is a LITERAL in the HUD block, so a token re-point would silently
   miss it and leave every number haloed in the wrong colour */
.st-screen .hy-mimic text { paint-order: stroke; stroke: #0b1730; stroke-width: 3px; }

/* 1. HELD OFF - the normal condition of every device here. Solid, thinner than the operational
      4px, no dash, no pulse, no glow. Deliberately quiet: it is not an exception. */
.st-screen .hy-mimic .hy-eq.r-off .hy-state-ring,
.st-screen .hy-mimic .hy-eq.r-foff .hy-state-ring {
  stroke: var(--st-held);
  stroke-width: 3;
  stroke-dasharray: none;
  opacity: 1;
  filter: none;
  animation: none !important;   /* the operational r-foff pulse is !important inside a media
                                   query, so an ordinary override loses on every machine with
                                   animation effects turned off */
}

/* 2. UNDER TEST - the point of the screen. Amber is not a liberty: the device IS forced on, so
      it states the same fact the Overview would. The pulse is killed; the halo below breathes
      instead, because the highlight MOVING is the motion that matters. */
.st-screen .hy-mimic .hy-eq.r-fon .hy-state-ring {
  stroke: var(--st-test);
  stroke-width: 5;
  stroke-dasharray: none;
  animation: none !important;
  filter: drop-shadow(0 0 10px rgba(255, 196, 0, .6));
}
.st-screen .hy-mimic .st-halo {
  fill: none;
  stroke: var(--st-test);
  stroke-width: 1.5;
  opacity: .45;
  animation: stBreathe 4s ease-in-out infinite;
}
@keyframes stBreathe { 0%, 100% { opacity: .55 } 50% { opacity: .15 } }

.st-screen .hy-mimic .st-plate { fill: var(--hud-bright); }
.st-screen .hy-mimic .st-plate-sub { fill: var(--st-test); }

/* 3-5. the verdicts. A BADGE, never the ring - on the real plant a red ring means FORCED OFF,
        and turning a failed device's ring red would lie about the machine. */
.st-screen .hy-mimic .st-badge { fill: var(--paper); stroke-width: 2; }
.st-screen .hy-mimic .st-badge.st-badge-pass { stroke: var(--st-pass); }
.st-screen .hy-mimic .st-badge.st-badge-fail { stroke: var(--st-fail); }
.st-screen .hy-mimic .st-badge.st-badge-eyes { stroke: var(--st-eyes); }
.st-screen .hy-mimic .st-badge-mark.st-badge-pass { fill: var(--st-pass); }
.st-screen .hy-mimic .st-badge-mark.st-badge-fail { fill: var(--st-fail); }
.st-screen .hy-mimic .st-badge-mark.st-badge-eyes { fill: var(--st-eyes); }
.st-screen .hy-mimic .st-badge-count { fill: var(--st-fail); }

/* 6. NOT IN THIS TEST - the dotted ghost, lifted from the operational .3 so it reads as a
      deliberate statement rather than a faded mistake. On Production 3 today this is most of
      the plant, and it is the only thing stopping the drawing from telling an operator that a
      plant is quiet when it is not. */
.st-screen .hy-mimic .hy-eq.unknown .hy-state-ring {
  stroke: var(--st-out);
  stroke-dasharray: 2 3;
  opacity: .55;
  animation: none !important;
}

/* the drawing is STILL. These are the last two things that would otherwise creep. */
.st-screen .hy-mimic .hy-sludge-drift,
.st-screen .hy-mimic .hy-bubble { animation: none !important; }
/* except the water the one commanded device is moving - the only flow on the drawing belongs
   to the only device that is on */
.st-screen .hy-mimic .hy-flow { stroke: var(--st-test); }

.st-screen .st-key i.k-held { border-color: var(--st-held); }
.st-screen .st-key i.k-test { border-color: var(--st-test); box-shadow: 0 0 8px rgba(255, 196, 0, .5); }
.st-screen .st-key i.k-pass { border-color: var(--st-pass); }
.st-screen .st-key i.k-fail { border-color: var(--st-fail); }
.st-screen .st-key i.k-eyes { border-color: var(--st-eyes); }
.st-screen .st-key i.k-out { border-color: var(--st-out); border-style: dotted; }
.st-screen .st-key { color: var(--ink-dim); }

@media (max-width: 760px) {
  .st-screen .card { border-width: 2px; border-radius: 14px; padding: 14px 12px 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .st-screen .hy-mimic .st-halo { animation: none !important; opacity: .5; }
}
@media (prefers-contrast: more) {
  .st-screen { --hud-line: rgba(227, 236, 247, .5); --ink-dim: #cfdcec; }
  .st-screen .card { border-color: rgba(227, 236, 247, .75); }
}

/* "Where to look on the panel" — the designators for the device under test. Amber, because it
   belongs to the device that is under test, and that device is amber everywhere on this screen.
   Fill AND ring AND glow, per protocol 3. */
.st-screen .st-now {
  background-color: rgba(23, 37, 66, .97);
  border-color: rgba(255, 196, 0, .55);
  box-shadow: 0 0 22px rgba(255, 196, 0, .18), 0 10px 30px rgba(0, 0, 0, .45);
  backdrop-filter: blur(3px);
}
.st-screen .st-now-head { color: var(--hud-bright); }
.st-screen .st-now-head b { color: var(--st-test); }
.st-screen .st-now-x { color: var(--ink-dim); }
.st-screen .st-now-cell b { color: var(--ink-dim); }
.st-screen .st-now-cell span { color: var(--hud-bright); }
.st-screen .st-now-cell.big span { color: var(--st-test); }
.st-screen .st-now-foot { color: var(--ink-dim); }
.st-screen .st-now-warn {
  background-color: rgba(255, 95, 109, .16);
  border: 1px solid rgba(255, 95, 109, .6);
  color: #ffd4d8;
}

/* ===========================================================================================
   CONTROL PANEL — one horizontal strip along the foot of the schematic card
   Steve, 26 Sep 2026: "put everything in that box the way it was when we woke up this morning, but
   lay them out horizontally in a single row, along the bottom below the key under the schematic,
   put them in the schematic border."

   Everything that was stripped out for height is back — the energy pair and both cabinet probes —
   because height was the only reason any of it left. Laid along the bottom the constraint is width,
   and the strip simply wraps when there is not enough of it. The vent fans do NOT come back: they
   moved to the drawing on their own merit, as machinery rather than switchboard fittings.

   It lives INSIDE .hy-mimic-card, after the drawing, so the card brackets frame the whole thing —
   drawing, key, then panel. Still HTML, not SVG: the drawing scales to a 720px floor and its 9px
   labels land at 6.75px, which a 22-cell breaker grid could not survive.
   =========================================================================================== */
.hy-cab {
  display: flex; align-items: stretch; gap: 12px; margin-top: 12px; padding-top: 11px;
  border-top: 1px solid var(--hud-line); font-family: var(--hud-mono); color: var(--ink);
}
.hy-cab-plate {
  flex: 0 0 62px; align-self: center; font-size: 9px; line-height: 1.25; letter-spacing: .14em;
  text-transform: uppercase; color: var(--hud-bright);
}
/* Centred, and centred on the CARD rather than on the space left over beside the name plate:
   the plate is a fixed 62px and ::after puts an empty 62px back on the right to balance it
   (Steve, 26 Sep 2026: "should be centered"). Without the spacer the groups sit half a plate
   width right of true centre, which reads as a mistake rather than a margin. */
.hy-cab-strip {
  flex: 1 1 0; min-width: 0; display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center; gap: 10px 14px;
}
.hy-cab::after { content: ""; flex: 0 0 62px; }
/* Each group is a self-contained cluster with a hairline between it and the next, so the strip
   still reads as five separate things rather than one long smear of numbers. */
.hy-cab-grp { display: flex; align-items: center; gap: 6px; padding-right: 14px; border-right: 1px solid var(--hud-line); }
.hy-cab-grp:last-child { border-right: 0; padding-right: 0; }
.hy-cab-warn {
  flex: 0 0 auto; align-self: center; max-width: 150px; padding: 5px 7px; font-size: 9.5px;
  line-height: 1.3; color: var(--crit); border: 1px solid var(--crit); border-radius: 5px;
  background: var(--crit-bg);
}

/* ---- supply rails ---- */
.hy-cab-rail {
  padding: 3px 7px; font-size: 10px; border: 1px solid var(--hud-line); border-radius: 5px;
  background: rgba(0, 0, 0, .18); text-align: center; white-space: nowrap;
}
.hy-cab-rail i {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 4px;
  background: var(--ink-dim); opacity: .35; vertical-align: middle;
}
.hy-cab-rail span { display: block; color: var(--ink-dim); letter-spacing: .04em; }
.hy-cab-rail b { display: block; margin-top: 1px; font-size: 11px; font-weight: 600; color: var(--hud-digit); font-variant-numeric: tabular-nums; }
.hy-cab-rail.ok i { background: var(--device-on); box-shadow: 0 0 6px var(--device-on); opacity: 1; }
.hy-cab-rail.crit { border-color: var(--crit); background: var(--crit-bg); }
.hy-cab-rail.crit i { background: var(--crit); box-shadow: 0 0 6px var(--crit); opacity: 1; }
.hy-cab-rail.crit b { color: var(--crit); }
.hy-cab-rail.nosig { border-style: dashed; }
.hy-cab-rail.nosig b { color: var(--ink-dim); font-weight: 400; }

/* ---- energy ---- */
.hy-cab-energy > div {
  padding: 3px 8px; border: 1px solid var(--hud-line); border-radius: 5px;
  background: rgba(0, 0, 0, .18); text-align: center; white-space: nowrap;
}
.hy-cab-energy b { display: block; font-size: 14px; font-weight: 600; color: var(--hud-digit); font-variant-numeric: tabular-nums; line-height: 1.15; }
.hy-cab-energy span { display: block; font-size: 8px; letter-spacing: .06em; color: var(--ink-dim); text-transform: uppercase; }

/* ---- the 22 breakers, still two rows of eleven ---- */
.hy-cab-grid { display: grid; grid-template-columns: repeat(11, 17px); gap: 3px; }
.hy-cb {
  position: relative; aspect-ratio: 1 / 1; display: flex; align-items: center;
  justify-content: center; border-radius: 3px; border: 1px solid var(--hud-line);
  background: rgba(0, 0, 0, .25);
}
.hy-cb i { font-style: normal; font-size: 9px; line-height: 1; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.hy-cb.closed { background: var(--device-on); border-color: var(--device-on); }
.hy-cb.closed i { color: #04140c; font-weight: 700; }
.hy-cb.open { background: rgba(157, 182, 205, .22); border-color: var(--ink-dim); }
.hy-cb.open i { color: var(--ink); }
/* "The plant has not told us" — the same dashed, faded look the drawing uses for no signal. */
.hy-cb.nosig { background: none; border-style: dashed; border-color: var(--hud-dim); opacity: .55; }
.hy-cb.nosig i { color: var(--ink-dim); }
.hy-cb.sup { border-top-width: 3px; border-top-color: var(--hud); }
.hy-cab-grid .hy-cb.hy-click { cursor: pointer; }
.hy-cab-grid .hy-cb.hy-click:hover { outline: 1px solid var(--hud-bright); outline-offset: 1px; }

/* ---- cabinet climate ---- */
.hy-cab-clim { display: flex; gap: 4px; align-items: baseline; font-size: 10px; white-space: nowrap; }
.hy-cab-clim > span { color: var(--ink-dim); }
.hy-cab-clim b, .hy-cab-clim u { font-weight: 600; text-decoration: none; color: var(--hud-digit); font-variant-numeric: tabular-nums; }
.hy-cab-clim u { color: var(--ink-dim); font-weight: 400; }
.hy-cab-clim.nosig b { color: var(--ink-dim); font-weight: 400; }

/* ---- the three links everything else depends on ---- */
.hy-cab-link { font-size: 10px; color: var(--ink-dim); letter-spacing: .04em; white-space: nowrap; }
.hy-cab-link b { font-weight: 600; color: var(--hud-digit); }
.hy-cab-link.ok b { color: var(--device-on); }
.hy-cab-link.crit b { color: var(--crit); }
.hy-cab-link.nosig b { color: var(--ink-dim); font-weight: 400; }

/* On a phone the strip stacks and the name plate goes back to one line. */
@media (max-width: 720px) {
  .hy-cab { flex-direction: column; gap: 8px; }
  .hy-cab::after { display: none; }
  .hy-cab-plate { flex: 0 0 auto; }
  .hy-cab-grp { border-right: 0; padding-right: 0; }
}
 width; the breaker cells grow
   with it, which is the one place they get comfortably large. */
@media (max-width: 720px) {
  .hy-cab { flex: 1 1 100%; }
}

/* ===========================================================================================
   ALARMS — a summary on the Overview, the list on its own tab (Steve, 26 Sep 2026)
   The banner used to print every open alarm in full at the top of the Overview; on Production 3
   that was six channels in one paragraph, pushing the plant drawing below the fold, and it grew
   with the number of faults — so the worse things got, the less of the plant you could see.
   =========================================================================================== */
.hy-alarm-summary {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 4px 16px;
  cursor: pointer;
}
.hy-alarm-summary:hover, .hy-alarm-summary:focus-visible { border-color: var(--hud-bright); outline: none; }
.hy-alarm-sum-head { grid-column: 1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.hy-alarm-sum-head b { font-size: 15px; }
.hy-alarm-sum-head span { font-size: 12px; color: var(--ink-dim); }
/* The worst open alarm, read out in full — a bare count says nothing about whether to hurry. */
.hy-alarm-sum-lead {
  grid-column: 1; font-size: 12.5px; color: var(--ink-dim); line-height: 1.4;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.hy-alarm-sum-go { grid-column: 2; grid-row: 1 / span 2; font-size: 12px; color: var(--hud-bright); white-space: nowrap; }
@media (max-width: 560px) {
  .hy-alarm-summary { grid-template-columns: 1fr; }
  .hy-alarm-sum-go { grid-column: 1; grid-row: auto; }
}

/* ---- the list ---- */
.hy-alarm-list { display: grid; gap: 7px; }
.hy-alarm-row {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px;
  padding: 9px 11px; border: 1px solid var(--hud-line); border-left-width: 3px; border-radius: 6px;
  background: rgba(0, 0, 0, .18);
}
.hy-alarm-row.warn { border-left-color: var(--warn); }
.hy-alarm-row.crit { border-left-color: var(--crit); }
/* An alarm nobody has looked at yet is the only one that should pull the eye. Once acknowledged
   it stays in the list but stops shouting; once the plant clears it, it is history. */
.hy-alarm-row.unseen { background: rgba(0, 0, 0, .3); }
.hy-alarm-row.acked { opacity: .82; }
.hy-alarm-row.cleared { opacity: .55; border-left-color: var(--hud-line); }
.hy-alarm-row.hy-click { cursor: pointer; }
.hy-alarm-row.hy-click:hover, .hy-alarm-row.hy-click:focus-visible { border-color: var(--hud-bright); outline: none; }
.hy-alarm-row-main { min-width: 0; }
.hy-alarm-row-top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.hy-alarm-code {
  font-family: var(--hud-mono); font-size: 9.5px; letter-spacing: .08em; color: var(--hud-bright);
  padding: 1px 5px; border: 1px solid var(--hud-line); border-radius: 3px; background: var(--hud-soft);
}
.hy-alarm-state { font-size: 10px; letter-spacing: .04em; color: var(--ink-dim); }
.hy-alarm-state.unseen { color: var(--warn); }
.hy-alarm-row b { font-size: 13px; line-height: 1.45; }
.hy-alarm-ack {
  font-size: 11px; color: var(--hud-bright); white-space: nowrap;
  padding: 4px 9px; border: 1px solid var(--hud-line); border-radius: 5px;
}
.hy-alarm-row.hy-click:hover .hy-alarm-ack { border-color: var(--hud-bright); background: var(--hud-soft); }
