/* joshiscool — OLED true-black terminal portal.
   Deliberate constraints (do not "fix" these toward a normal dark theme):
   - Background is #000000 so OLED pixels are actually off.
   - No text-shadow / no blurred box-shadow anywhere. Bloom on pure black is
     exactly the halo Josh does not want, and it costs contrast.
   - Foreground is #dee1e6, not #fff. Max-contrast white on black is fatiguing
     and is the worst case for burn-in on static chrome.
   - Accents are cyan-leaning rather than pure blue: blue OLED emitters degrade
     fastest, so wear is spread across the green and blue subpixels. */

:root {
  --bg: #000000;
  --panel: #050708;
  --line: #14201f;
  --line-hot: #1e3033;
  --fg: #dee1e6;
  --dim: #6f7d81;
  --dimmer: #3c4649;
  --cyan: #00c2cf;
  --cyan-deep: #0a6a72;
  --amber: #c8952b;
  --red: #c9503c;
  --green: #3f9e6c;
  --crest-ring: #3f484b;
  --crest-star: #99a3a7;
  --mono: "Share Tech Mono", ui-monospace, "JetBrains Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--mono);
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: 0.02em;
}

a { color: var(--cyan); }

/* --- one terminal ------------------------------------------------------ */
/* No page header, no agency branding, and no frame: the login is bare text on
   black. Everything the portal says is printed by boot.js, including the
   terminal's own identity line and the restricted-system notice. Sections are
   separated by space alone -- a real terminal has no hairline rules, and on
   OLED every rule is a lit row that buys nothing. */
.shell {
  max-width: 660px;
  margin: 0 auto;
  padding: 34px 18px 56px;
}

.term { font-size: 13.5px; }

/* The terminal identifies itself first, the way a real one does on connect. */
#term-id { margin-bottom: 15px; }
#term-id div {
  color: var(--dimmer);
  font-size: 11px;
  letter-spacing: 0.14em;
  min-height: 1.4em;
}

.crest { display: block; margin: 2px auto 20px; width: 78px; height: 78px; }
.crest circle, .crest path { fill: none; stroke: var(--crest-ring); stroke-width: 1.2; }
.crest .star { stroke: var(--crest-star); stroke-width: 1.4; }

/* The emblem draws itself in before the terminal starts printing. pathLength
   normalises every shape to 100 units, so a single dash length works for all
   of them regardless of their real perimeter. The tick ring is deliberately
   excluded: it already uses stroke-dasharray for its dots, so animating that
   property would destroy the dots -- it fades in instead. */
.crest .ring, .crest .star {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: draw 0.8s ease-out forwards;
}
.crest .ring:nth-of-type(2) { animation-delay: 0.12s; }
.crest .star { animation-delay: 0.3s; }
.crest .ticks { opacity: 0; animation: fade 0.5s ease-out 0.55s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes fade { to { opacity: 1; } }

/* Set when the sequence is skipped or motion is reduced. */
.no-draw .crest .ring, .no-draw .crest .star { stroke-dashoffset: 0; animation: none; }
.no-draw .crest .ticks { opacity: 1; animation: none; }

#boot-title {
  color: var(--cyan);
  margin: 0 0 12px;
  font-size: 13.5px;
  letter-spacing: 0.14em;
  min-height: 1.5em;
  white-space: pre-wrap;
  word-break: break-word;
}

#boot-lines { margin: 0; white-space: pre-wrap; word-break: break-word; }
#boot-lines div { color: var(--dim); }
#boot-lines div.done { color: var(--green); }

/* --- restricted-system notice ------------------------------------------ */
#legal { display: none; margin-top: 22px; }
#legal.show { display: block; }
.legal-head {
  color: var(--amber);
  font-size: 12px;
  letter-spacing: 0.18em;
  margin-bottom: 9px;
  min-height: 1.4em;
}
.legal-body {
  color: var(--dim);
  font-size: 12px;
  line-height: 1.7;
  margin-bottom: 9px;
  max-width: 62ch;
}
.legal-body:last-child { margin-bottom: 0; }

.cursor {
  display: inline-block;
  width: 0.62em;
  height: 1em;
  background: var(--cyan);
  vertical-align: text-bottom;
  animation: blink 1.05s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .cursor { animation: none; } }

/* --- passphrase -------------------------------------------------------- */
.auth { display: none; margin-top: 26px; }
.auth.show { display: block; }

/* A shell prompt, not a form. The input carries no border, no background and
   no box -- it is a bare run of text on the same line as the prompt, and the
   native caret (recoloured) acts as the cursor. */
.auth-row { display: flex; gap: 10px; align-items: baseline; }

.prompt { color: var(--green); font-size: 13.5px; letter-spacing: 0.04em; white-space: nowrap; }
.prompt.ok { color: var(--cyan); }

.auth input {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: 0;
  outline: none;
  color: var(--cyan);
  caret-color: var(--cyan);
  font-family: var(--mono);
  font-size: 16px; /* 16px stops iOS Safari zooming on focus */
  letter-spacing: 0.28em;
  padding: 2px 0;
}

/* The action sits on its own line rather than trailing the entry: on a wide
   screen a flex-grown input strands it against the right margin. */
.auth-actions { margin-top: 14px; }

.auth button {
  background: none;
  border: 0;
  padding: 2px 0;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.1em;
  cursor: pointer;
}
.auth button:hover:not(:disabled) { color: var(--cyan); }
.auth button:disabled { opacity: 0.4; cursor: not-allowed; }
.auth input:focus-visible, .auth button:focus-visible { outline: 1px solid var(--cyan); outline-offset: 3px; }

.auth-msg { min-height: 18px; margin-top: 11px; font-size: 12px; letter-spacing: 0.12em; color: var(--red); }
.auth-msg.ok { color: var(--green); }

/* --- dashboard ---------------------------------------------------------- */
/* Same machine as the login: no frames, no panels, bare output on black.
   Structure comes from spacing, prompts and alignment rather than boxes. */

.wrap { padding: 30px 18px 40px; max-width: 1400px; margin: 0 auto; }

.dash-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 8px;
}
.dash-id div {
  color: var(--dimmer);
  font-size: 11px;
  letter-spacing: 0.14em;
  min-height: 1.4em;
}
.dash-head button {
  flex: 0 0 auto;
  background: none;
  border: 0;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  padding: 2px 0;
  cursor: pointer;
}
.dash-head button:hover { color: var(--cyan); }
.dash-head button:focus-visible { outline: 1px solid var(--cyan); outline-offset: 2px; }

/* Section headers read as commands the terminal was given. */
.section-label {
  font-size: 11.5px;
  letter-spacing: 0.12em;
  color: var(--dim);
  margin: 30px 0 14px;
}
.section-label::before { content: '> '; color: var(--cyan); }

.grid { display: grid; gap: 26px 30px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid { grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); } }

.card { padding: 0; border: 0; background: none; }

.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.card-title { font-size: 13px; letter-spacing: 0.18em; color: var(--fg); text-transform: uppercase; }
.card.offline .card-title { color: var(--dim); }
.card-role { font-size: 9.5px; letter-spacing: 0.16em; color: var(--dimmer); text-transform: uppercase; }

/* Bracketed like a console status column. */
.status { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; white-space: nowrap; }
.status::before { content: '['; }
.status::after  { content: ']'; }
.status.up { color: var(--green); }
.status.down { color: var(--red); }
.status.standby { color: var(--amber); }

.gauge-row { display: flex; align-items: center; gap: 16px; margin-top: 14px; flex-wrap: wrap; }

.gauge { flex: 0 0 auto; width: 118px; height: 118px; position: relative; }
.gauge svg { display: block; width: 100%; height: 100%; }
.gauge .track { fill: none; stroke: #101a1b; stroke-width: 7; }
.gauge .value { fill: none; stroke: var(--cyan); stroke-width: 7; transition: stroke-dasharray 0.5s ease, stroke 0.5s ease; }
.gauge .tick { stroke: var(--dimmer); stroke-width: 1; }
.gauge .tick.major { stroke: var(--dim); stroke-width: 1.4; }

.gauge-read { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; }
.gauge-num { font-size: 25px; color: var(--cyan); line-height: 1; font-variant-numeric: tabular-nums; }
.gauge-unit { font-size: 10px; color: var(--dim); letter-spacing: 0.16em; margin-top: 4px; }
.gauge-cap { font-size: 8.5px; color: var(--dimmer); letter-spacing: 0.14em; margin-top: 2px; }
.gauge-num.warn { color: var(--amber); }
.gauge-num.crit { color: var(--red); }

.readouts { flex: 1 1 160px; min-width: 150px; display: flex; flex-direction: column; gap: 10px; }

.meter-label {
  display: flex; justify-content: space-between; gap: 8px;
  font-size: 10.5px; letter-spacing: 0.1em; color: var(--dim); margin-bottom: 5px;
}
.meter-label b { color: var(--fg); font-weight: normal; font-variant-numeric: tabular-nums; }

/* Segmented LED bar rather than a solid fill. Both track and fill are the same
   repeating gradient so lit and unlit cells line up exactly; the fill takes its
   colour from `color`, which is what the warn/crit classes override. */
.meter {
  height: 7px;
  background: repeating-linear-gradient(90deg, #162426 0 5px, transparent 5px 7px);
}
.meter i {
  display: block;
  height: 100%;
  color: var(--cyan-deep);
  background: repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 7px);
  transition: width 0.5s ease;
}
.meter i.warn { color: var(--amber); }
.meter i.crit { color: var(--red); }

.socket-list { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; }
.socket { font-size: 10.5px; color: var(--dimmer); letter-spacing: 0.1em; }
.socket b { color: var(--cyan); font-weight: normal; font-variant-numeric: tabular-nums; }

.vm-table { margin-top: 14px; }
.vm-head { font-size: 9.5px; letter-spacing: 0.2em; color: var(--dimmer); text-transform: uppercase; margin-bottom: 9px; }
.vm { margin-bottom: 11px; }
.vm:last-child { margin-bottom: 0; }
.vm-name { display: flex; justify-content: space-between; gap: 8px; font-size: 11.5px; color: var(--fg); }
.vm-name .id { color: var(--dimmer); }
.vm-name .mem { color: var(--dim); font-variant-numeric: tabular-nums; }
.vm.stopped .vm-name { color: var(--dimmer); }
.vm .meter { margin-top: 5px; }

.err { margin-top: 12px; font-size: 10.5px; color: var(--red); letter-spacing: 0.06em; word-break: break-word; }
.err::before { content: '! '; }
.err.standby { color: var(--amber); }

/* The terminal is still sitting there when the report ends. */
.cursor-line { margin-top: 36px; }
