/* ============================================================================
   hcOps design tokens
   ----------------------------------------------------------------------------
   Brand values come from hcPlatform/static/style.css so a plant reads the same
   in both apps. The data-viz values were VALIDATED, not chosen by eye:

     scripts/validate_palette.js "<ramp>" --ordinal --mode light  --surface #ffffff
     scripts/validate_palette.js "<ramp>" --ordinal --mode dark   --surface #1a1844

   Both ramps pass all four ordinal checks (single hue, monotone lightness,
   adjacent dL >= 0.06, end step clears 2:1 against its own surface).

   WHY AN ORDINAL RAMP AND NOT 7 CATEGORICAL HUES: the stages are an ordered
   process, not seven independent identities. Categorical hues would imply the
   stages are peers and would also sit at the 8-slot token ceiling with no room
   to grow. A ramp encodes direction — soil at one end, packed at the other —
   and intensity builds left to right so the eye travels the pipeline.

   Colour is NOT used to tell level tiles from flow tiles. That distinction is
   carried by a caption ("on hand" vs "today") and an icon, because four of
   seven stages are levels and hue alone would be unreadable at 20 feet and
   invisible to a colourblind viewer.
   ========================================================================= */

:root {
  color-scheme: light;

  /* Brand — hcPlatform/static/style.css */
  --hc-purple:       #100E2A;
  --hc-purple-mid:   #1a1844;
  --hc-gold:         #dea140;
  --hc-blue:         #0080c7;

  /* Surfaces */
  --page:      #f4f4f2;
  --surface:   #ffffff;
  --surface-2: #fafaf9;
  --border:    rgba(11, 11, 11, 0.10);
  --hairline:  #e1e0d9;

  /* Ink — text NEVER wears a data colour */
  --text-primary:   #0b0b0b;
  --text-secondary: #52514e;
  --text-muted:     #898781;

  /* Pipeline ordinal ramp, stage 1 -> 7 (light: light -> dark) */
  --stage-1: #61aedb;
  --stage-2: #3d97cc;
  --stage-3: #0f81ba;
  --stage-4: #006da0;
  --stage-5: #005a86;
  --stage-6: #00476c;
  --stage-7: #003553;

  /* Status — fixed tokens, never themed, never reused as a series colour.
     ALWAYS shipped with an icon + text label: on a light surface `warning`
     is 1.83:1, below the 3:1 bar, so the label is the required relief and
     colour never carries the meaning alone. */
  --status-live:     #0ca30c;
  --status-stale:    #fab219;
  --status-dead:     #d03b3b;
  --status-idle:     #898781;

  --meter-track: #cde2fb;

  --radius: 10px;
  --gap: 16px;

  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* Dark values under BOTH scopes: the media query covers the OS setting, the
   data-theme scope covers an explicit choice, and the :not() guard lets a
   light stamp beat OS-dark. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --page:      #0a0918;
    --surface:   var(--hc-purple);
    --surface-2: var(--hc-purple-mid);
    --border:    rgba(255, 255, 255, 0.12);
    --hairline:  #2a2750;

    --text-primary:   #ffffff;
    --text-secondary: #d5d3e2;
    --text-muted:     #a9a6bd;

    /* Dark steps are SELECTED for the dark surface, not an inverted flip, and
       run dark -> light so intensity still builds toward Clean Packed. */
    --stage-1: #1c5f8f;
    --stage-2: #2a7bb3;
    --stage-3: #3a95cf;
    --stage-4: #4ea9df;
    --stage-5: #6fbde8;
    --stage-6: #93cff0;
    --stage-7: #b8e0f7;

    --meter-track: #1c5f8f;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --page:      #0a0918;
  --surface:   var(--hc-purple);
  --surface-2: var(--hc-purple-mid);
  --border:    rgba(255, 255, 255, 0.12);
  --hairline:  #2a2750;

  --text-primary:   #ffffff;
  --text-secondary: #d5d3e2;
  --text-muted:     #a9a6bd;

  --stage-1: #1c5f8f;
  --stage-2: #2a7bb3;
  --stage-3: #3a95cf;
  --stage-4: #4ea9df;
  --stage-5: #6fbde8;
  --stage-6: #93cff0;
  --stage-7: #b8e0f7;

  --meter-track: #1c5f8f;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--page);
  color: var(--text-primary);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

/* ── Layout ──────────────────────────────────────────────────────────────── */
.hc-shell { max-width: 1400px; margin: 0 auto; padding: 24px 16px 48px; }

.hc-topbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.hc-topbar__brand { font-weight: 700; letter-spacing: .02em; }
.hc-topbar__spacer { flex: 1 1 auto; }
.hc-topbar__meta { color: var(--text-secondary); font-size: .875rem; }

/* ── Pipeline ────────────────────────────────────────────────────────────── */
.hc-pipeline {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  align-items: stretch;
}

.hc-tile {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 14px 12px;
  min-height: 168px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}

/* The ordinal ramp appears ONLY here — a 4px strip carrying position in the
   process. It never touches the numbers, which stay in ink tokens. */
.hc-tile__strip { position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--text-muted); }
.hc-tile[data-stage="1"] .hc-tile__strip { background: var(--stage-1); }
.hc-tile[data-stage="2"] .hc-tile__strip { background: var(--stage-2); }
.hc-tile[data-stage="3"] .hc-tile__strip { background: var(--stage-3); }
.hc-tile[data-stage="4"] .hc-tile__strip { background: var(--stage-4); }
.hc-tile[data-stage="5"] .hc-tile__strip { background: var(--stage-5); }
.hc-tile[data-stage="6"] .hc-tile__strip { background: var(--stage-6); }
.hc-tile[data-stage="7"] .hc-tile__strip { background: var(--stage-7); }

.hc-tile__head { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; }
.hc-tile__num {
  font-size: .75rem; font-weight: 700; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.hc-tile__label {
  font-size: .8125rem; font-weight: 600; color: var(--text-secondary);
  letter-spacing: .01em;
}

/* Proportional figures, not tabular: tabular-nums gives every digit the width
   of a 0, which makes a number like 121 look loose at display sizes. */
/* Anchored from the TOP, not pushed down by `margin-top: auto`.
   With auto, the value's position depended on whatever happened to sit below
   it, so a tile carrying a note rendered its number higher than its
   neighbours. Every tile has the same two single-line rows above the value
   (number+label, then the on-hand/today caption), so anchoring from the top
   lines them all up regardless of what follows. The status badge takes the
   auto margin instead and pins to the bottom. */
.hc-tile__value {
  font-size: 2.25rem; font-weight: 650; line-height: 1.1;
  margin-top: 10px; color: var(--text-primary);
}
.hc-tile__value--muted { color: var(--text-muted); font-size: 1.25rem; font-weight: 600; }
.hc-tile__unit { font-size: .875rem; font-weight: 600; color: var(--text-secondary); margin-left: 4px; }

/* The level/flow distinction. Deliberately NOT colour: a caption plus an icon,
   legible at 20 feet and unaffected by colour vision. */
.hc-tile__kind {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .6875rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-muted); margin-top: 2px;
}
.hc-tile__secondary {
  font-size: .8125rem; color: var(--text-secondary);
  margin-top: 6px; min-height: 1.2em;
}
.hc-tile__note {
  font-size: .6875rem; color: var(--text-muted); margin-top: 2px; font-style: italic;
}

/* `est.` marker — a derived piece count must never pass as a measured one. */
.hc-est {
  display: inline-block; font-size: .625rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted); border: 1px solid var(--border);
  border-radius: 4px; padding: 0 4px; margin-left: 6px; vertical-align: middle;
}

/* ── Status ──────────────────────────────────────────────────────────────── */
.hc-status {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .6875rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-secondary);
  /* Takes the slack so every tile's badge sits on the same baseline. */
  margin-top: auto; padding-top: 10px;
}
.hc-status__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--status-idle); flex: none; }
.hc-status[data-status="live"]  .hc-status__dot { background: var(--status-live); }
.hc-status[data-status="stale"] .hc-status__dot { background: var(--status-stale); }
.hc-status[data-status="dead"]  .hc-status__dot { background: var(--status-dead); }

/* A dead feed greys the VALUE so a stale number can't be read as current. */
.hc-tile[data-status="dead"] .hc-tile__value { color: var(--text-muted); }
.hc-tile[data-status="not_instrumented"] .hc-tile__value,
.hc-tile[data-status="no_data"] .hc-tile__value { color: var(--text-muted); font-size: 1.125rem; font-weight: 600; }

/* ── Meter (stage 7: packed vs due) ──────────────────────────────────────── */
.hc-meter { margin-top: 8px; }
.hc-meter__track {
  position: relative; height: 14px; border-radius: 7px;
  background: var(--meter-track); overflow: hidden;
}
.hc-meter__fill {
  height: 100%; border-radius: 7px 0 0 7px;
  background: var(--stage-7); transition: width .4s ease;
}
.hc-meter[data-pace="behind"]      .hc-meter__fill { background: var(--status-stale); }
.hc-meter[data-pace="well-behind"] .hc-meter__fill { background: var(--status-dead); }

/* Where the bar SHOULD be given how much of the shift has elapsed. Progress
   without pace can't tell you whether 64% at 1pm is fine or a problem. */
.hc-meter__pace {
  position: absolute; top: -3px; bottom: -3px; width: 2px;
  background: var(--text-primary); opacity: .75;
}
.hc-meter__legend {
  display: flex; justify-content: space-between;
  font-size: .6875rem; color: var(--text-secondary); margin-top: 4px;
}

/* ── Alerts ──────────────────────────────────────────────────────────────── */
/* Status colour + an icon + words, never colour alone: the warning token is
   1.83:1 on a light surface, and a colourblind viewer gets nothing from hue. */
.hc-alerts { display: flex; flex-direction: column; gap: 6px; }
.hc-alerts:empty { display: none; }

.hc-alert {
  display: flex; align-items: baseline; gap: 8px;
  padding: 8px 12px; border-radius: 6px;
  background: var(--surface-2);
  border-left: 3px solid var(--status-idle);
  font-size: .875rem;
}
.hc-alert[data-severity="warning"]  { border-left-color: var(--status-stale); }
.hc-alert[data-severity="critical"] { border-left-color: var(--status-dead); }
.hc-alert__icon { font-size: .75rem; flex: none; }
.hc-alert[data-severity="warning"]  .hc-alert__icon { color: var(--status-stale); }
.hc-alert[data-severity="critical"] .hc-alert__icon { color: var(--status-dead); }

/* On the wall the alert strip has to be readable at the same distance as the
   tiles, so it scales with the viewport like they do. */
.hc-board .hc-alerts { margin: 0 20px 12px; }
.hc-board .hc-alert  { font-size: clamp(.9375rem, 1.15vw, 1.375rem); padding: 10px 16px; }

/* Connection to the SERVER is gone — distinct from a dead plant FEED, which
   the payload reports per stage. Without this the board would keep showing its
   last good numbers, looking perfectly current. */
body[data-offline] .hc-pipeline { opacity: .45; transition: opacity .3s ease; }
body[data-offline] .hc-offline-banner { display: flex !important; }
.hc-offline-banner {
  display: none; align-items: center; gap: 8px;
  margin: 0 20px 12px; padding: 10px 16px; border-radius: 6px;
  background: var(--status-dead); color: #fff; font-weight: 600;
  font-size: clamp(.9375rem, 1.15vw, 1.375rem);
}

/* ── Board (TV) ──────────────────────────────────────────────────────────── */
body.hc-board {
  background: var(--page);
  overflow: hidden;              /* a wall display never scrolls */
}
.hc-board .hc-tile { min-height: 200px; padding: 18px; }
/* Sized so a 6-digit thousands-separated value ("123,456") still fits seven
   tiles across at 1920 — numbers are shown raw, never abbreviated. */
.hc-board .hc-tile__value  { font-size: clamp(1.75rem, 2.9vw, 3.25rem); }
.hc-board .hc-tile__label  { font-size: clamp(.875rem, 1.1vw, 1.125rem); }
.hc-board .hc-tile__kind,
.hc-board .hc-status       { font-size: clamp(.6875rem, .8vw, .875rem); }
.hc-board .hc-tile__secondary { font-size: clamp(.8125rem, .95vw, 1rem); }
.hc-board .hc-pipeline { grid-template-columns: repeat(7, 1fr); gap: 12px; }
.hc-board__header {
  display: flex; align-items: baseline; gap: 16px;
  padding: 14px 20px 10px;
}
.hc-board__plant { font-size: 1.5rem; font-weight: 700; letter-spacing: .04em; }
.hc-board__clock { margin-left: auto; font-size: 1.25rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.hc-board__body { padding: 0 20px 20px; }

/* Below ~1100px the 7-across board stops being readable; stack instead of
   letting tiles shrink into unreadable slivers. */
@media (max-width: 1100px) {
  .hc-board .hc-pipeline { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
  body.hc-board { overflow: auto; }
}

/* ── Tables, forms, misc ─────────────────────────────────────────────────── */
.hc-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; margin-top: var(--gap);
}
.hc-card__title { font-size: .9375rem; font-weight: 700; margin: 0 0 12px; }

.hc-table { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.hc-table th {
  text-align: left; font-size: .6875rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-muted);
  border-bottom: 1px solid var(--hairline); padding: 6px 8px; font-weight: 700;
}
.hc-table td { padding: 6px 8px; border-bottom: 1px solid var(--hairline); }
/* Tabular figures ONLY in columns that must align vertically. */
.hc-table td.num, .hc-table th.num { text-align: right; font-variant-numeric: tabular-nums; }

.hc-select, .hc-input {
  font: inherit; font-size: .875rem; padding: 6px 10px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text-primary);
}
.hc-btn {
  font: inherit; font-size: .875rem; font-weight: 600; cursor: pointer;
  padding: 8px 16px; border-radius: 6px; border: 1px solid transparent;
  background: var(--hc-purple-mid); color: #fff;
}
.hc-btn:hover { background: var(--hc-purple); }

.hc-flash { padding: 10px 14px; border-radius: 6px; margin-bottom: 12px; font-size: .875rem;
  border: 1px solid var(--border); background: var(--surface-2); }
.hc-flash[data-cat="danger"]  { border-left: 3px solid var(--status-dead); }
.hc-flash[data-cat="warning"] { border-left: 3px solid var(--status-stale); }
.hc-flash[data-cat="success"] { border-left: 3px solid var(--status-live); }

.hc-login { max-width: 360px; margin: 10vh auto; padding: 0 16px; }
.hc-login label { display: block; font-size: .8125rem; font-weight: 600; margin: 12px 0 4px; }
.hc-login .hc-input { width: 100%; }
.hc-login .hc-btn { width: 100%; margin-top: 18px; }

.hc-muted { color: var(--text-muted); }
.hc-small { font-size: .8125rem; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
