/* An operator console for paid GPU work. Two things drive the design:
   the numbers are the content, and one of them is money burning per hour.
   So: quiet chrome, monospace for every machine-supplied value, and colour
   reserved for state that changes what you should do next. */

:root {
  --bg: #fbfbfd;
  --panel: #ffffff;
  --sunken: #f4f5f8;
  --line: #e3e5ea;
  --line-strong: #cdd1d9;
  --ink: #14171c;
  --ink-2: #4a5160;
  --ink-3: #838b99;
  --accent: #1b62d6;
  --accent-ink: #ffffff;
  --violet: #7b3fd4;
  --violet-bg: #f3edfd;
  --ok: #12793f;
  --warn: #9a6206;
  --bad: #c02a26;
  --ok-bg: #e8f5ec;
  --warn-bg: #fdf3e2;
  --bad-bg: #fdecea;
  --shadow: 0 1px 2px rgba(20, 23, 28, .06), 0 4px 16px rgba(20, 23, 28, .04);
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d1015;
    --panel: #14181f;
    --sunken: #0a0d12;
    --line: #232935;
    --line-strong: #333c4c;
    --ink: #e8ecf3;
    --ink-2: #a3adbd;
    --ink-3: #6c7789;
    --accent: #5b9bff;
    --accent-ink: #06101f;
    --violet: #b18aff;
    --violet-bg: #1d1630;
    --ok: #46c07a;
    --warn: #d9a13c;
    --bad: #ff6b62;
    --ok-bg: #10251a;
    --warn-bg: #2a1f0d;
    --bad-bg: #2c1512;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 28px rgba(0, 0, 0, .25);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 14px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}

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

.shell { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 0 24px; height: 56px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  position: sticky; top: 0; z-index: 20;
}
.brand { font-weight: 600; letter-spacing: -.01em; font-size: 14px; white-space: nowrap; }
.brand small { display: block; font-weight: 400; color: var(--ink-3); font-size: 11px; letter-spacing: 0; }
.topbar .spacer { flex: 1; }

.columns {
  display: grid;
  grid-template-columns: minmax(360px, 420px) minmax(0, 1fr);
  gap: 0;
  flex: 1;
  align-items: start;
}
.rail {
  border-right: 1px solid var(--line);
  padding: 20px;
  display: flex; flex-direction: column; gap: 16px;
  position: sticky; top: 56px;
  max-height: calc(100vh - 56px);
  overflow-y: auto;
}
.stage-col { padding: 20px 24px; display: flex; flex-direction: column; gap: 16px; min-width: 0; }

@media (max-width: 1000px) {
  .columns { grid-template-columns: 1fr; }
  .rail { position: static; max-height: none; border-right: 0; border-bottom: 1px solid var(--line); }
}

/* ---------- surfaces ---------- */

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.card > header {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
}
.card > header h2 {
  margin: 0; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3);
}
.card > header .spacer { flex: 1; }
.card .body { padding: 14px; display: flex; flex-direction: column; gap: 12px; }

/* ---------- form ---------- */

.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field label { font-size: 12px; font-weight: 500; color: var(--ink-2); }
.field .hint { font-size: 11.5px; color: var(--ink-3); line-height: 1.45; }

input[type="text"], input[type="password"], select {
  font: 400 13px/1.4 var(--mono);
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  padding: 8px 10px;
  width: 100%;
  transition: border-color .12s, box-shadow .12s;
}
input::placeholder { color: var(--ink-3); }
input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
input.invalid { border-color: var(--bad); }

.segmented {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 3px; gap: 3px;
}
.segmented button {
  font: 500 12.5px/1 var(--sans);
  color: var(--ink-2);
  background: transparent;
  border: 0; border-radius: 6px;
  padding: 8px 6px; cursor: pointer;
  transition: background .12s, color .12s;
}
.segmented button:hover:not([aria-pressed="true"]) { color: var(--ink); }
.segmented button[aria-pressed="true"] {
  background: var(--panel); color: var(--ink);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}

button.btn {
  font: 500 13px/1 var(--sans);
  padding: 9px 14px;
  border-radius: 7px;
  border: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  transition: background .12s, border-color .12s, opacity .12s;
}
button.btn:hover:not(:disabled) { border-color: var(--ink-3); }
button.btn:disabled { opacity: .45; cursor: not-allowed; }
button.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
button.btn.danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, var(--line-strong)); }
button.btn.wide { width: 100%; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- state ---------- */

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  font: 500 11.5px/1 var(--sans);
  padding: 5px 9px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink-2); background: var(--sunken);
  white-space: nowrap;
}
.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.chip.ok { color: var(--ok); background: var(--ok-bg); border-color: color-mix(in srgb, var(--ok) 28%, transparent); }
.chip.warn { color: var(--warn); background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 28%, transparent); }
.chip.bad { color: var(--bad); background: var(--bad-bg); border-color: color-mix(in srgb, var(--bad) 28%, transparent); }
.chip.live .dot { animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

.notice {
  font-size: 12.5px; line-height: 1.5;
  padding: 10px 12px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--sunken); color: var(--ink-2);
  white-space: pre-wrap; word-break: break-word;
}
.notice.ok { color: var(--ok); background: var(--ok-bg); border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
.notice.bad { color: var(--bad); background: var(--bad-bg); border-color: color-mix(in srgb, var(--bad) 25%, transparent); }
.notice.warn { color: var(--warn); background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 25%, transparent); }

/* ---------- the GPU verdict, the one number the page exists to compute ---------- */

.verdict { display: flex; align-items: baseline; gap: 12px; }
.verdict .value {
  font: 600 30px/1 var(--mono);
  letter-spacing: -.02em;
}
.verdict .unit { font-size: 12px; color: var(--ink-3); }

.derivation {
  font: 400 11.5px/1.7 var(--mono);
  color: var(--ink-3);
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 9px 11px;
  white-space: pre-wrap;
}

dl.kv { margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 5px 14px; align-items: baseline; }
dl.kv dt { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
dl.kv dd {
  margin: 0; font: 400 12.5px/1.45 var(--mono);
  overflow-wrap: anywhere;
}

/* ---------- stages ---------- */

.stages { display: flex; gap: 0; align-items: stretch; overflow-x: auto; }
.stage {
  flex: 1; min-width: 108px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-right: 0;
  background: var(--panel);
}
.stage:first-child { border-radius: 9px 0 0 9px; }
.stage:last-child { border-right: 1px solid var(--line); border-radius: 0 9px 9px 0; }
.stage .name { font-size: 12px; font-weight: 500; }
.stage .note { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.stage[data-state="active"] { background: color-mix(in srgb, var(--accent) 8%, var(--panel)); border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
.stage[data-state="active"] .name { color: var(--accent); }
.stage[data-state="done"] .name { color: var(--ok); }
.stage[data-state="failed"] { background: var(--bad-bg); }
.stage[data-state="failed"] .name { color: var(--bad); }
.stage[data-state="pending"] .name { color: var(--ink-3); }

/* ---------- log ---------- */

.logwrap { display: flex; flex-direction: column; min-height: 0; flex: 1; }
pre.log {
  margin: 0;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  border-top: 0;
  padding: 12px 14px;
  height: 58vh;
  min-height: 280px;
  overflow: auto;
  font: 400 12px/1.6 var(--mono);
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--ink-2);
}
pre.log .l-err { color: var(--bad); }
pre.log .l-ok { color: var(--ok); }
pre.log .l-stage { color: var(--accent); font-weight: 600; }
pre.log .l-metric { color: var(--ink); }

/* ---------- runs table ---------- */

table.runs { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.runs th {
  text-align: left; font-weight: 500; font-size: 11px;
  text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3);
  padding: 0 10px 7px 0; border-bottom: 1px solid var(--line);
}
table.runs td { padding: 9px 10px 9px 0; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.runs tr:last-child td { border-bottom: 0; }
table.runs td.mono { font-family: var(--mono); font-size: 12px; }
table.runs a { color: var(--accent); text-decoration: none; }
table.runs a:hover { text-decoration: underline; }
.empty { color: var(--ink-3); font-size: 12.5px; padding: 14px 0; }

/* ---------- gate ---------- */

.gate { display: grid; place-items: center; min-height: 100vh; padding: 24px; }
.gate .card { width: 100%; max-width: 380px; }

/* ---------- stepper ----------
   The form is a sequence, not a wall: you cannot name a repo before you know
   what task it will train, and you should not be asked for a write-scoped
   token until the rest is settled. Each step stays collapsed to its result
   once satisfied, so the page shows what is decided and what is still open. */

.steps { display: flex; flex-direction: column; gap: 10px; }

.step {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  overflow: hidden;
  transition: border-color .15s, box-shadow .15s, opacity .15s;
}
.step[data-state="active"] { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); box-shadow: var(--shadow); }
.step[data-state="done"] { border-color: color-mix(in srgb, var(--ok) 32%, var(--line)); }
.step[data-state="locked"] { opacity: .55; }

.step > button.head {
  all: unset;
  box-sizing: border-box;
  display: flex; align-items: center; gap: 11px;
  width: 100%; padding: 12px 14px;
  cursor: pointer;
}
.step[data-state="locked"] > button.head { cursor: not-allowed; }

.step .num {
  flex: 0 0 auto;
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  font: 600 12px/1 var(--sans);
  background: var(--sunken); color: var(--ink-3);
  border: 1px solid var(--line-strong);
}
.step[data-state="active"] .num { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.step[data-state="done"] .num { background: var(--ok); color: #fff; border-color: var(--ok); }

.step .titles { flex: 1; min-width: 0; }
.step .titles strong { display: block; font-size: 13.5px; font-weight: 600; letter-spacing: -.005em; }
.step .titles span {
  display: block; font-size: 12px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.step[data-state="done"] .titles span { color: var(--ok); font-family: var(--mono); font-size: 11.5px; }

.step .caret { color: var(--ink-3); font-size: 11px; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.step .panel { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 12px; }
.step .panel::before { content: ""; display: block; border-top: 1px solid var(--line); margin-bottom: 2px; }

/* The launch step is the one destructive-ish action on the page, so it reads
   as a summary of everything above it rather than a lone button. */
.launch { display: flex; flex-direction: column; gap: 10px; }
.launch dl.kv dd { color: var(--ink); }
.cost {
  display: flex; align-items: baseline; gap: 8px;
  font: 600 15px/1 var(--mono); color: var(--warn);
}
.cost small { font: 400 11.5px/1.4 var(--sans); color: var(--ink-3); }

/* ---------- run list ----------
   More than one person can drive this console, and a log with no owner on it
   is a log you cannot trust. Every run carries its repo, its commit and the
   Hugging Face account it will publish under, and the log panel names the run
   it is showing rather than being an anonymous stream. */

.runlist { display: flex; flex-direction: column; gap: 8px; }

.runrow {
  all: unset;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 4px 12px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.runrow:hover { border-color: var(--line-strong); }
.runrow[aria-current="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, var(--panel));
}
.runrow .who {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
  font: 400 12px/1.4 var(--mono); color: var(--ink-2);
  min-width: 0;
}
.runrow .who b { font-weight: 600; color: var(--ink); }
.runrow .who .sep { color: var(--ink-3); }
.runrow .meta {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center;
  font-size: 11.5px; color: var(--ink-3);
}
.runrow .actions { grid-column: 1 / -1; display: flex; gap: 12px; font-size: 12px; }
.runrow .actions a { color: var(--accent); text-decoration: none; }
.runrow .actions a:hover { text-decoration: underline; }

/* ---------- how a run works ----------
   This replaces a paragraph that asked people to hold three facts in their head
   at once: which image each stage needs, which pod it runs on, and what
   survives afterwards. Shown as the shape of the run, those facts are simply
   visible: grouped bands are one pod, the band's footer says when it dies, and
   the volume sits underneath all of them, outliving every band. */

.lifecycle { display: flex; flex-direction: column; gap: 8px; }

.machine {
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  overflow: hidden;
  background: var(--panel);
}
.machine.trainer { border-left-color: var(--violet); }
.machine.volume { border-left-color: var(--ok); }

.machine > .top {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 8px 11px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.machine.trainer > .top { background: var(--violet-bg); }
.machine.volume > .top { background: var(--ok-bg); }

.machine .top b { font-size: 12.5px; font-weight: 600; }
.machine .top code {
  font: 400 11px/1.4 var(--mono); color: var(--ink-2);
  overflow-wrap: anywhere;
}
.machine .top .gpus {
  margin-left: auto; font: 600 11.5px/1 var(--mono); color: var(--ink-2);
  white-space: nowrap;
}

.machine .stages-in {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 9px 11px;
}
.machine .stages-in span {
  font: 500 11.5px/1 var(--sans);
  padding: 5px 9px; border-radius: 6px;
  background: var(--sunken); border: 1px solid var(--line); color: var(--ink-2);
}

.machine > .fate {
  padding: 7px 11px;
  border-top: 1px dashed var(--line);
  font-size: 11.5px; color: var(--ink-3);
}
.machine.volume > .fate { color: var(--ok); }

/* ---------- run page ----------
   A log belongs to one run, so it lives on that run's page rather than in a
   permanent panel on the home view. On the home view it was a single stream
   with no owner, rewritten every time somebody clicked something else. */

.runpage { padding: 20px 24px; display: flex; flex-direction: column; gap: 16px; max-width: 1100px; margin: 0 auto; width: 100%; }

.back {
  all: unset;
  display: inline-flex; align-items: center; gap: 7px;
  font: 500 13px/1 var(--sans); color: var(--ink-2);
  cursor: pointer; padding: 6px 2px;
}
.back:hover { color: var(--accent); }

.runhead {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 14px;
  padding: 14px 16px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 11px;
  box-shadow: var(--shadow);
}
.runhead h1 {
  margin: 0; font: 600 16px/1.3 var(--mono); letter-spacing: -.01em;
  overflow-wrap: anywhere;
}
.runhead .sub { font: 400 12.5px/1.4 var(--mono); color: var(--ink-3); overflow-wrap: anywhere; }
.runhead .spacer { flex: 1 1 auto; }
.runhead .acts { display: flex; gap: 8px; }

/* ---------- run list controls ----------
   A list that only grows is a list nobody reads. Filter by outcome, search by
   the things a run is actually identified by, and page through the rest. */

.listbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
.listbar input[type="text"] { flex: 1 1 200px; min-width: 160px; }

.filters { display: flex; gap: 4px; flex-wrap: wrap; }
.filters button {
  font: 500 11.5px/1 var(--sans);
  padding: 6px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink-2);
  transition: border-color .12s, color .12s, background .12s;
}
.filters button:hover { color: var(--ink); }
.filters button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.filters button .n { opacity: .65; margin-left: 5px; font-variant-numeric: tabular-nums; }

.pager { display: flex; align-items: center; gap: 10px; justify-content: flex-end; margin-top: 10px; }
.pager span { font: 400 12px/1 var(--mono); color: var(--ink-3); }
.pager button {
  font: 500 12px/1 var(--sans); padding: 6px 11px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--panel); color: var(--ink);
}
.pager button:disabled { opacity: .4; cursor: not-allowed; }
