/* Oracle Architecture — operations console.
   Design note: nearly every value on this page is machine text (job ids, cron
   expressions, run ids, SHAs), so the monospace face is the primary voice and
   the sans is reserved for headings and prose. Colour is functional only: the
   five status hues are the vocabulary, and amber is spent exclusively on the
   capacity meter, which is the one thing that maps to a physical limit. */

@font-face {
  font-family: 'Plex Mono';
  src: url('/fonts/plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('/fonts/plex-mono-600.woff2') format('woff2');
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: 'Grotesk';
  src: url('/fonts/grotesk-500.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: 'Grotesk';
  src: url('/fonts/grotesk-700.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

:root {
  --panel-950: #101826;
  --panel-900: #16202f;
  --panel-850: #1a2536;
  --panel-800: #1e2a3c;
  --panel-700: #26344a;
  --line: #24314a;
  --line-soft: #1c2739;

  --ink-100: #dce4ee;
  --ink-300: #a8b6c8;
  --ink-400: #8797ac;
  --ink-600: #5c6b80;

  --ok: #3fb98a;
  --run: #4ea8de;
  --warn: #e0a33e;
  --fail: #e0605e;
  --idle: #5c6b80;

  /* The only accent. It belongs to load and nothing else. */
  --signal: #e0a33e;

  --mono: 'Plex Mono', ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;
  --sans: 'Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  --r: 4px;
  --gap: 16px;
}

* { box-sizing: border-box; }

html { color-scheme: dark; }

body {
  margin: 0;
  background: var(--panel-950);
  color: var(--ink-100);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--sans);
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0;
}

a { color: var(--run); text-decoration: none; }
a:hover { text-decoration: underline; }

button, input, select, textarea { font: inherit; }

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

/* ─────────────────────────────── login ──────────────────────────────────── */

.login-shell {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px;
}

.login-card {
  width: min(400px, 100%);
  background: var(--panel-900);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 32px;
}

.login-card .wordmark { margin-bottom: 28px; }

/* ─────────────────────────────── shell ──────────────────────────────────── */

.shell {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 216px 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    'head head'
    'nav  main';
}

.masthead {
  grid-area: head;
  border-bottom: 1px solid var(--line);
  background: var(--panel-900);
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 0 20px;
  min-height: 62px;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  z-index: 20;
}

.wordmark {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.02em;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.wordmark em {
  font-style: normal;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-600);
}

.masthead-stats {
  display: flex;
  gap: 22px;
  margin-left: auto;
  align-items: center;
  flex-wrap: wrap;
}

.stat { display: flex; flex-direction: column; gap: 1px; }
.stat b { font-size: 15px; font-weight: 600; line-height: 1.2; }
.stat span {
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-600);
}

/* ── signature: the capacity meter ──────────────────────────────────────────
   Eight discrete segments, one per weight unit of the scheduler's admission
   budget. This is the only element on the page with depth, because it is the
   only one standing in for something physical: 11.6 GB of RAM in a box. */

.capacity {
  display: flex;
  align-items: center;
  gap: 12px;
}

.capacity-track {
  display: flex;
  gap: 3px;
  padding: 4px;
  background: #0b111c;
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.55);
}

.cap-seg {
  width: 13px;
  height: 20px;
  border-radius: 1px;
  background: #182233;
  border: 1px solid #202c40;
  transition: background 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}

.cap-seg.lit {
  background: var(--signal);
  border-color: #f0bc63;
  box-shadow: 0 0 7px rgb(224 163 62 / 0.5), inset 0 1px 0 rgb(255 255 255 / 0.28);
}

.cap-seg.lit.heavy { background: #d98a2b; border-color: #e8a24a; }

.capacity-read { font-size: 11px; color: var(--ink-400); white-space: nowrap; }
.capacity-read b { color: var(--ink-100); font-weight: 600; }

/* ─────────────────────────────── nav ────────────────────────────────────── */

.sidenav {
  grid-area: nav;
  border-right: 1px solid var(--line);
  background: var(--panel-900);
  padding: 18px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sidenav button {
  appearance: none;
  background: none;
  border: 0;
  border-radius: var(--r);
  color: var(--ink-400);
  text-align: left;
  padding: 7px 10px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
}
.sidenav button:hover { background: var(--panel-850); color: var(--ink-100); }
.sidenav button[aria-current='true'] {
  background: var(--panel-800);
  color: var(--ink-100);
  box-shadow: inset 2px 0 0 var(--signal);
}
.sidenav .count { font-size: 10.5px; color: var(--ink-600); }

.sidenav-foot {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
  font-size: 10.5px;
  color: var(--ink-600);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ─────────────────────────────── main ───────────────────────────────────── */

main {
  grid-area: main;
  padding: 22px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.view-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.view-head h2 { font-size: 19px; }
.view-head p { margin: 0; color: var(--ink-400); font-size: 12px; }
.view-head .spacer { margin-left: auto; }

.card {
  background: var(--panel-900);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

.card-head {
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 10.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.card-head .spacer { margin-left: auto; }
.card-body { padding: 14px; }

/* ── signature: the 24-hour cron ribbon ─────────────────────────────────────
   Every job is a cron expression, and the whole point of the migration was
   staggering them so 2 OCPUs never see a pile-up. Plotting the firing times
   across one day is the only view that makes a collision visible at a glance. */

.ribbon { overflow-x: auto; }

.ribbon-grid {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 0 12px;
  min-width: 640px;
  align-items: center;
}

.ribbon-hours {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  font-size: 9.5px;
  color: var(--ink-600);
  border-bottom: 1px solid var(--line-soft);
  padding-bottom: 5px;
  margin-bottom: 7px;
}
.ribbon-hours span { text-align: left; }

.ribbon-label {
  font-size: 11px;
  color: var(--ink-400);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 3px 0;
}
.ribbon-label b { color: var(--ink-100); font-weight: 400; }

.ribbon-lane {
  position: relative;
  height: 15px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--line-soft) 1px, transparent 1px) 0 0 / calc(100% / 24) 100%;
}

.ribbon-tick {
  position: absolute;
  top: 3px;
  width: 4px;
  height: 9px;
  border-radius: 1px;
  background: var(--run);
  transform: translateX(-2px);
}
.ribbon-tick.w6 { background: var(--signal); height: 13px; top: 1px; }
.ribbon-tick.w3 { background: var(--ok); height: 11px; top: 2px; }

.ribbon-now {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 1px;
  background: var(--fail);
}

/* ─────────────────────────────── tables ─────────────────────────────────── */

table { width: 100%; border-collapse: collapse; }

th {
  text-align: left;
  font-weight: 400;
  font-size: 9.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-600);
  padding: 9px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  position: sticky;
  top: 0;
  background: var(--panel-900);
}

td {
  padding: 9px 14px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}

tbody tr:last-child td { border-bottom: 0; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--panel-850); }

.num { text-align: right; font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-400); }
.dim { color: var(--ink-600); }
.nowrap { white-space: nowrap; }

/* Job ids are dotted namespaces; dimming the prefix makes the group readable
   without adding a badge that would repeat information already in the id. */
.jobid .ns { color: var(--ink-600); }
.jobid .leaf { color: var(--ink-100); }

/* ─────────────────────────────── status ─────────────────────────────────── */

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  display: inline-block;
  flex: none;
}
.dot.success { background: var(--ok); }
.dot.running { background: var(--run); animation: pulse 2s ease-in-out infinite; }
.dot.queued  { background: var(--warn); }
.dot.failed, .dot.timeout { background: var(--fail); }
.dot.cancelled, .dot.skipped, .dot.idle, .dot.historical { background: var(--idle); }

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgb(78 168 222 / 0.55); }
  50%      { box-shadow: 0 0 0 5px rgb(78 168 222 / 0); }
}

.status { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }

.pill {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid var(--line);
  color: var(--ink-400);
}
.pill.on { border-color: rgb(63 185 138 / 0.4); color: var(--ok); }
.pill.off { border-color: rgb(224 96 94 / 0.35); color: var(--fail); }
.pill.warn { border-color: rgb(224 163 62 / 0.4); color: var(--warn); }

/* ─────────────────────────────── controls ──────────────────────────────── */

.btn {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--panel-800);
  color: var(--ink-100);
  border-radius: var(--r);
  padding: 6px 12px;
  cursor: pointer;
  font-size: 12px;
  white-space: nowrap;
  transition: background 120ms ease, border-color 120ms ease;
}
.btn:hover:not(:disabled) { background: #26344a; border-color: #35476a; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.primary { background: var(--signal); border-color: var(--signal); color: #16202f; font-weight: 600; }
.btn.primary:hover:not(:disabled) { background: #edb457; border-color: #edb457; }
.btn.danger { border-color: rgb(224 96 94 / 0.4); color: var(--fail); background: transparent; }
.btn.danger:hover:not(:disabled) { background: rgb(224 96 94 / 0.12); }
.btn.sm { padding: 3px 9px; font-size: 11px; }

input[type='text'], input[type='password'], input[type='search'], select, textarea {
  width: 100%;
  background: #0d1420;
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--ink-100);
  padding: 7px 10px;
}
input::placeholder, textarea::placeholder { color: var(--ink-600); }
textarea { resize: vertical; min-height: 68px; }

label.field { display: block; margin-bottom: 12px; }
label.field > span {
  display: block;
  font-size: 9.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-600);
  margin-bottom: 5px;
}
label.check { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; cursor: pointer; }
label.check input { width: auto; }

.toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.toolbar input[type='search'], .toolbar select { width: auto; min-width: 180px; }

/* ─────────────────────────────── meters ────────────────────────────────── */

.meters { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

.meter-label {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  color: var(--ink-400);
  margin-bottom: 5px;
}
.meter-label b { color: var(--ink-100); font-weight: 600; }

.bar {
  height: 6px;
  border-radius: 3px;
  background: #0d1420;
  border: 1px solid var(--line-soft);
  overflow: hidden;
}
.bar > i { display: block; height: 100%; background: var(--run); transition: width 400ms ease; }
.bar > i.warn { background: var(--warn); }
.bar > i.crit { background: var(--fail); }

.spark { width: 100%; height: 42px; display: block; }

/* ─────────────────────────────── logs ──────────────────────────────────── */

.logbox {
  background: #0a1017;
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 12px 14px;
  font-size: 11.5px;
  line-height: 1.6;
  max-height: 62vh;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--ink-300);
}
.logbox .err { color: var(--fail); }
.logbox .warnline { color: var(--warn); }
.logbox .ts { color: var(--ink-600); }

/* ─────────────────────────────── drawer ────────────────────────────────── */

.drawer-scrim {
  position: fixed;
  inset: 0;
  background: rgb(6 10 16 / 0.62);
  z-index: 40;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(760px, 100%);
  background: var(--panel-950);
  border-left: 1px solid var(--line);
  z-index: 41;
  display: flex;
  flex-direction: column;
  animation: slide 180ms ease;
}
@keyframes slide { from { transform: translateX(22px); opacity: 0; } }

.drawer-head {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.drawer-head h3 { font-size: 16px; }
.drawer-body { padding: 20px; overflow: auto; flex: 1; display: flex; flex-direction: column; gap: 18px; }

.kv { display: grid; grid-template-columns: 148px 1fr; gap: 5px 14px; font-size: 12px; }
.kv dt { color: var(--ink-600); }
.kv dd { margin: 0; word-break: break-word; }

/* ─────────────────────────────── misc ──────────────────────────────────── */

.empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--ink-400);
}
.empty b { display: block; color: var(--ink-100); font-family: var(--sans); font-size: 14px; margin-bottom: 5px; }

.banner {
  border: 1px solid rgb(224 163 62 / 0.35);
  background: rgb(224 163 62 / 0.08);
  color: var(--warn);
  border-radius: var(--r);
  padding: 10px 14px;
  font-size: 12px;
}
.banner.bad { border-color: rgb(224 96 94 / 0.35); background: rgb(224 96 94 / 0.08); color: var(--fail); }

.toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--panel-800);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 9px 16px;
  z-index: 60;
  animation: rise 160ms ease;
  max-width: min(520px, calc(100vw - 40px));
}
.toast.bad { border-color: rgb(224 96 94 / 0.5); color: var(--fail); }
@keyframes rise { from { transform: translate(-50%, 8px); opacity: 0; } }

.grid-2 { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

@media (max-width: 880px) {
  .shell { grid-template-columns: 1fr; grid-template-areas: 'head' 'nav' 'main'; }
  .sidenav { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .sidenav-foot { display: none; }
  .masthead { padding: 10px 14px; }
  main { padding: 14px; }
  .kv { grid-template-columns: 1fr; }
  .kv dt { margin-top: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
