/* Upgrade hub: "the control room". Build brief 06-ui-design.md.
   Motion has a meaning: something moves only when the real thing moves. */

@font-face { font-family: "Space Grotesk"; src: url("../fonts/space-grotesk.woff2") format("woff2"); font-weight: 300 700; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("../fonts/jetbrains-mono.woff2") format("woff2"); font-weight: 100 800; font-display: swap; }

:root {
  --brand-1: #f26d2f;          /* lane A: the orange of mynitro.africa and of the Nitro logo */
  --brand-2: #6ab2b0;          /* lane B: the teal of ioco.tech (primary colour of the site) */
  --bg: #0b0d10;
  --panel-1: #14181d;
  --panel-2: #101317;
  --line: #232a31;
  --line-2: #2f3841;
  --text: #e6edf3;
  --text-2: #8b98a5;
  --text-3: #56616c;
  --success: #3ddc84;
  --warn: #ffb020;
  --error: #ff4d4f;
  --critical: #ff2d55;
  --info: #5aa9ff;
  --old: #6b7785;
  --new: #b388ff;
  --steel: #1c2229;
  --ease: cubic-bezier(.2, .8, .2, 1);
  --head: "Space Grotesk", "Inter", system-ui, sans-serif;
  --body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html { background: var(--bg); color-scheme: dark; }
body {
  margin: 0; min-height: 100vh; background: transparent; color: var(--text);
  font: 400 14px/1.45 var(--body); font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3 { font-family: var(--head); font-weight: 600; margin: 0; letter-spacing: .01em; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--info); }
.mono { font-family: var(--mono); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; border-radius: 2px; }

/* -- background grid, slow drift --------------------------------------- */
.grid-bg { position: fixed; inset: -48px; z-index: -1; pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px);
  background-size: 24px 24px; animation: drift 60s linear infinite; }
.grid-bg::after { content: ""; position: absolute; inset: 0;
  background: radial-gradient(1200px 600px at 50% -10%, rgba(90,169,255,.07), transparent 70%), radial-gradient(900px 500px at 100% 100%, rgba(255,106,19,.04), transparent 70%); }
@keyframes drift { to { transform: translate3d(24px, 24px, 0); } }

/* -- top bar ------------------------------------------------------------ */
.topbar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 20px; padding: 10px 20px;
  background: linear-gradient(#12161b, #0e1115); border-bottom: 1px solid var(--line); }
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.logo { display: flex; align-items: center; gap: 8px; font: 700 15px/1 var(--head); letter-spacing: .14em; white-space: nowrap; }
.logo-mark { width: 26px; height: 26px; flex: none; }
.logo small { display: block; font: 500 9px/1.2 var(--body); letter-spacing: .18em; color: var(--text-2); margin-top: 3px; }
.win-title { color: var(--text-2); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-left: 12px; border-left: 1px solid var(--line); }
.clock { text-align: right; margin-left: auto; line-height: 1.1; white-space: nowrap; }
.clock-label { font: 500 10px/1 var(--body); letter-spacing: .16em; text-transform: uppercase; color: var(--text-3); }
.clock-digits { font: 600 24px/1.15 var(--mono); letter-spacing: .02em; height: 28px; }
.clock-digits span { display: inline-block; }
.clock-digits .roll { animation: roll .35s var(--ease); }
@keyframes roll { from { transform: translateY(70%); opacity: 0; } to { transform: none; opacity: 1; } }
.clock-local { font: 400 11px/1 var(--mono); color: var(--text-2); }

.switch { position: relative; display: flex; background: #0c0f12; border: 1px solid var(--line); border-radius: 4px; padding: 3px; }
.switch button { position: relative; z-index: 1; border: 0; background: none; padding: 7px 16px; font: 500 13px/1 var(--head); color: var(--text-2); white-space: nowrap; transition: color .2s; }
.switch button[aria-pressed="true"] { color: #0b0d10; font-weight: 600; }
.switch button kbd { font: 400 10px var(--mono); opacity: .5; margin-left: 6px; }
.switch .pill { position: absolute; z-index: 0; top: 3px; bottom: 3px; left: 0; width: 10px; border-radius: 3px; background: var(--text);
  transition: transform .35s var(--ease), width .35s var(--ease), background-color .35s; }

.health { display: flex; gap: 12px; flex-wrap: wrap; }
.health .dot { display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-2); cursor: help; white-space: nowrap; }
.health .dot i { width: 8px; height: 8px; border-radius: 50%; background: var(--old); flex: none; }
.health .ok i { background: var(--success); box-shadow: 0 0 6px rgba(61,220,132,.6); }
.health .amber i { background: var(--warn); }
.health .red i { background: var(--error); box-shadow: 0 0 6px rgba(255,77,79,.6); }
.health .off i { background: transparent; border: 1px solid var(--old); }
.chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border: 1px solid var(--line-2); border-radius: 3px;
  font: 500 10.5px/1.2 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-2); white-space: nowrap; }
.chip.role-admin { color: var(--brand-1); border-color: color-mix(in srgb, var(--brand-1) 50%, transparent); }
.chip.amber { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); }
.chip.ai { color: var(--new); border-color: color-mix(in srgb, var(--new) 45%, transparent); }
.chip.ok { color: var(--success); border-color: color-mix(in srgb, var(--success) 45%, transparent); }
.chip.red { color: var(--error); border-color: color-mix(in srgb, var(--error) 50%, transparent); }
.btn { border: 1px solid var(--line-2); background: #171c22; border-radius: 3px; padding: 7px 12px; font: 500 12px/1 var(--head); color: var(--text); transition: border-color .15s, background-color .15s; }
.btn:hover { border-color: #46525e; background: #1c2229; }
.btn.primary { background: var(--brand-1); border-color: var(--brand-1); color: #0b0d10; font-weight: 600; }
.btn.ghost { background: none; color: var(--text-2); }
.btn[disabled] { opacity: .45; cursor: default; }

.dual-line { display: flex; height: 3px; background: #0c0f12; }
.dual-line div { flex: 1; position: relative; overflow: hidden; }
.dual-line i { position: absolute; inset: 0; transform-origin: left; transition: transform .8s var(--ease); }
.dual-line .a i { background: var(--brand-1); }
.dual-line .b i { background: var(--brand-2); }

/* -- layout --------------------------------------------------------------- */
main { padding: 18px 20px 30px; max-width: 1900px; margin: 0 auto; }
.bays { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.below { display: grid; grid-template-columns: 1.6fr 1fr; gap: 18px; margin-top: 18px; }
.lane-cols { display: grid; grid-template-columns: 1.15fr 1fr; gap: 18px; margin-top: 18px; align-items: start; }
.col { display: grid; gap: 18px; min-width: 0; }

.lane-A { --lane: var(--brand-1); }
.lane-B { --lane: var(--brand-2); }

.panel { position: relative; min-width: 0; background: linear-gradient(var(--panel-1), var(--panel-2)); border: 1px solid var(--line); border-radius: 4px; overflow: hidden; }
.panel::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--lane, var(--line-2)); }
.panel-head { display: flex; align-items: center; gap: 10px; padding: 12px 16px 0; }
.panel-head h2 { font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--text-2); display: flex; align-items: center; gap: 8px; }
.panel-head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.panel-body { padding: 12px 16px 16px; }
.icon { width: 16px; height: 16px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: square; }
.stale { filter: grayscale(.8); opacity: .65; }
.nodata { color: var(--text-3); font-size: 12px; padding: 4px 0; }
.demo .panel-head .right, .demo .bay-head .open { margin-right: 38px; }
.demo .panel::after { content: "DEMO DATA"; position: absolute; top: 12px; right: -40px; transform: rotate(45deg); width: 130px; text-align: center;
  font: 600 8px/14px var(--mono); letter-spacing: .14em; color: #0b0d10; background: var(--warn); opacity: .85; pointer-events: none; z-index: 3; }

/* -- lane bay ------------------------------------------------------------ */
.bay-head { display: flex; align-items: baseline; gap: 12px; padding: 16px 18px 0; }
.bay-head h1 { font-size: 22px; }
.bay-head .lane-tag { font: 600 11px var(--mono); letter-spacing: .14em; color: var(--lane); }
.bay-head .open { margin-left: auto; }
.bay-main { display: grid; grid-template-columns: auto 1fr; gap: 22px; padding: 10px 18px 6px; align-items: center; }
.bay-side { display: grid; gap: 12px; min-width: 0; }

.ring { position: relative; width: 230px; height: 230px; flex: none; }
.ring.big { width: 290px; height: 290px; }
.ring svg { width: 100%; height: 100%; display: block; overflow: visible; }
.ring .seg-bg { stroke: var(--steel); fill: none; }
.ring .seg { stroke: var(--lane); fill: none; transition: stroke-dasharray .9s var(--ease); }
.ring .seg.open { stroke: transparent; }
.ring .sweep { stroke: #fff; fill: none; opacity: .5; stroke-dasharray: 5 300; animation: sweep 4s linear infinite; }
@keyframes sweep { from { stroke-dashoffset: 5; } to { stroke-dashoffset: calc(-1 * var(--len)); } }
.ring .pods-bg { stroke: #171c22; fill: none; }
.ring .pods { stroke: var(--success); fill: none; opacity: .8; transition: stroke-dasharray .9s var(--ease); }
.ring .center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.ring .pct { font: 600 58px/1 var(--mono); letter-spacing: -.03em; }
.ring.big .pct { font-size: 74px; }
.ring .pct small { font-size: .42em; color: var(--text-2); margin-left: 2px; }
.ring .steps { font: 400 12px var(--mono); color: var(--text-2); margin-top: 6px; }
.ring .podline { font: 400 10px var(--mono); color: var(--text-3); margin-top: 3px; letter-spacing: .04em; }
.ring.complete .glow { animation: ring-done 1.6s var(--ease) 1; }
.ring .done-mark { color: var(--success); font: 600 12px var(--mono); letter-spacing: .1em; margin-top: 6px; }
@keyframes ring-done { 0% { opacity: 0; transform: rotate(-90deg); } 40% { opacity: 1; } 100% { opacity: 0; transform: rotate(270deg); } }

.rail { display: flex; gap: 2px; padding: 6px 18px 12px; }
.rail .chev { position: relative; flex: 1 1 0; min-width: 0; text-overflow: clip; padding: 7px 6px 7px 16px; font: 500 10.5px/1.2 var(--head); letter-spacing: .04em; white-space: nowrap; overflow: hidden;
  clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 0 100%, 10px 50%); background: var(--steel); color: var(--text-3); }
.rail .chev:first-child { clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 0 100%); padding-left: 10px; }
.rail .chev b { font: 400 9.5px var(--mono); display: block; opacity: .75; }
.rail .done { background: color-mix(in srgb, var(--lane) 78%, #000); color: #0b0d10; }
.rail .current { background: color-mix(in srgb, var(--lane) 22%, var(--steel)); color: var(--text); box-shadow: inset 0 -2px 0 var(--lane); }
.rail .current::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--lane) 55%, transparent), transparent);
  animation: scan 2.4s linear infinite; }
@keyframes scan { from { transform: translateX(-110%); } to { transform: translateX(280%); } }

.now { border-left: 2px solid var(--lane); padding: 2px 0 2px 12px; min-width: 0; }
.now .k { font: 600 10px var(--mono); letter-spacing: .2em; color: var(--lane); display: flex; gap: 10px; align-items: center; }
.now .k span { color: var(--text-3); letter-spacing: .04em; font-weight: 400; }
.now .t { font: 500 15px/1.3 var(--head); margin-top: 3px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.now .id { font: 600 13px var(--mono); color: var(--lane); margin-right: 8px; }
.statusline { font-size: 13px; color: var(--text); min-height: 38px; }
.statusline .chip { margin-left: 6px; vertical-align: 1px; }
.caret::after { content: "▍"; color: var(--lane); animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.counters { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border-top: 1px solid var(--line); }
.counter { background: var(--panel-2); padding: 10px 14px; min-width: 0; }
.counter .k { font: 500 9.5px var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); }
.counter .v { font: 600 20px/1.2 var(--mono); margin-top: 2px; white-space: nowrap; }
.counter .v small { font-size: 12px; color: var(--text-2); font-weight: 400; }
.counter.bad .v { color: var(--error); }
.counter .state { font: 600 11px/1.3 var(--mono); letter-spacing: .06em; margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-running { color: var(--success); } .st-stalled { color: var(--warn); animation: slowblink 1.6s infinite; }
.st-input { color: var(--critical); animation: slowblink 1.6s infinite; } .st-idle { color: var(--text-2); } .st-failed { color: var(--error); }
@keyframes slowblink { 50% { opacity: .35; } }

/* -- component tiles ------------------------------------------------------- */
.mosaic { display: flex; flex-wrap: wrap; gap: 4px; padding: 12px 18px 16px; }
.mosaic .cell { position: relative; width: 22px; height: 22px; border-radius: 2px; overflow: hidden; background: var(--steel); border: 1px solid transparent; }
.cgroups { display: flex; flex-wrap: wrap; gap: 14px 18px; }
.cgroup { min-width: 0; }
.cgroup h3 { font: 500 10px var(--body); letter-spacing: .18em; text-transform: uppercase; color: var(--text-3); margin-bottom: 6px; }
.tiles { display: flex; flex-wrap: wrap; gap: 6px; }
.tile { width: 172px; }
.tile { position: relative; overflow: hidden; border: 1px solid var(--line); border-radius: 3px; background: #12161a; padding: 9px 10px 8px; min-height: 76px; }
.tile .name { font: 500 12.5px/1.2 var(--head); display: flex; gap: 6px; align-items: center; position: relative; z-index: 1; }
.tile .name .lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile .badge { margin-left: auto; font: 600 8.5px/1 var(--mono); letter-spacing: .1em; padding: 2px 4px; border-radius: 2px; border: 1px solid currentColor; flex: none; }
.tile .ver { font: 400 11px var(--mono); color: var(--text-2); margin-top: 5px; position: relative; z-index: 1; white-space: nowrap; }
.tile .ver .to { color: var(--text); display: inline-block; }
.tile .dots { display: flex; gap: 3px; flex-wrap: wrap; margin-top: 7px; position: relative; z-index: 1; }
.pdot { width: 9px; height: 9px; border-radius: 50%; background: var(--old); animation: pop .4s var(--ease); }
.pdot.upgraded { background: var(--success); } .pdot.new { background: var(--new); } .pdot.problem { background: var(--error); }
.pdot.unknown { background: transparent; border: 1px solid var(--old); } .pdot.removed { background: transparent; border: 1px dashed var(--text-3); }
@keyframes pop { from { transform: scale(0); } }

/* states, for tiles and mosaic cells. Each state also has a label or an icon. */
.s-waiting { color: var(--old); }
.s-upgrading { color: var(--info); border-color: color-mix(in srgb, var(--info) 45%, transparent) !important; }
.s-upgrading::before { content: ""; position: absolute; inset: 0 -40px; opacity: .16;
  background: repeating-linear-gradient(-45deg, var(--info) 0 6px, transparent 6px 14px); animation: stripes 1s linear infinite; }
.s-upgrading::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 30%; background: linear-gradient(90deg, transparent, rgba(90,169,255,.28), transparent); animation: scan 2s linear infinite; }
@keyframes stripes { to { transform: translateX(19.8px); } }
.s-upgraded { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent) !important; }
.s-upgraded.cell { background: color-mix(in srgb, var(--success) 55%, #000); }
.s-upgraded::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 50% 50%, rgba(61,220,132,.5), transparent 70%); opacity: 0; animation: glow-once 1.4s var(--ease) 1; pointer-events: none; }
@keyframes glow-once { 30% { opacity: 1; } 100% { opacity: 0; } }
.s-upgraded .ver .to { animation: flap .6s var(--ease) 1; }
@keyframes flap { from { transform: rotateX(90deg); opacity: 0; } to { transform: none; opacity: 1; } }
.s-new { color: var(--new); border-color: color-mix(in srgb, var(--new) 55%, transparent) !important; }
.s-new.cell { background: color-mix(in srgb, var(--new) 45%, #000); }
.s-new::after { content: ""; position: absolute; inset: -1px; border: 1px solid var(--new); border-radius: 3px; animation: pulse-out 2.4s var(--ease) infinite; pointer-events: none; }
@keyframes pulse-out { from { opacity: .9; transform: scale(1); } to { opacity: 0; transform: scale(1.06); } }
.s-problem { color: var(--error); border-color: var(--error) !important; }
.s-problem.cell { background: var(--error); }
.s-problem::before { content: ""; position: absolute; inset: 0; background: rgba(255,77,79,.18); animation: slowblink 1.8s infinite; }
.s-removed { color: var(--text-3); opacity: .55; }
.s-removed .lbl { text-decoration: line-through; }
.s-removed.cell { background: repeating-linear-gradient(45deg, var(--steel) 0 3px, transparent 3px 6px); }
.s-unknown, .s-off { color: var(--text-3); border-style: dotted !important; border-color: var(--line-2) !important; }
.s-tool { color: var(--text-2); }
.s-tool.cell { background: #2a323b; }
.mosaic .cell.s-waiting { background: #2a323b; }
.legend { display: flex; gap: 12px; flex-wrap: wrap; font: 400 10.5px var(--mono); color: var(--text-2); }
.legend span { display: inline-flex; gap: 5px; align-items: center; }

/* -- PCS panel ------------------------------------------------------------- */
.badge-state { font: 600 11px var(--mono); letter-spacing: .14em; padding: 3px 8px; border-radius: 2px; border: 1px solid currentColor; }
.pulse { display: block; width: 100%; height: 56px; margin: 4px 0 8px; background: #0c0f12; border: 1px solid var(--line); border-radius: 2px; }
.kv { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.kv .k { font: 500 9.5px var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); }
.kv .v { font: 600 16px var(--mono); }
.kv .bad { color: var(--error); } .kv .warnc { color: var(--warn); }
.ticker { margin-top: 10px; padding: 6px 10px; background: #0c0f12; border: 1px solid var(--line); border-radius: 2px; font: 400 11.5px/1.4 var(--mono); color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ticker::before { content: "› "; color: var(--lane); }
.conveyor { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--line-2); }
.token { position: relative; overflow: hidden; display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px; border: 1px solid var(--line-2); border-radius: 12px; font: 500 11px var(--mono); color: var(--text-2); animation: slide-in .4s var(--ease); }
.token .gear { width: 12px; height: 12px; }
.token.busy { color: var(--info); border-color: color-mix(in srgb, var(--info) 50%, transparent); }
.token.busy .gear { animation: spin 2s linear infinite; }
.token.done { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent); }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes slide-in { from { opacity: 0; transform: translateY(-8px); } }

/* -- pipeline --------------------------------------------------------------- */
.pipe-head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.pipe-head .job { font: 600 14px var(--mono); }
.stages { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 12px; }
.stage { position: relative; overflow: hidden; padding: 6px 10px 6px 16px; font: 500 10.5px/1.25 var(--head); background: var(--steel); color: var(--text-3);
  clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%, 8px 50%); border-bottom: 2px solid transparent; }
.stage b { display: block; font: 400 9.5px var(--mono); opacity: .8; }
.stage.SUCCESS { background: color-mix(in srgb, var(--success) 60%, #000); color: #06140c; }
.stage.IN_PROGRESS { background: color-mix(in srgb, var(--info) 30%, var(--steel)); color: var(--text); }
.stage.IN_PROGRESS::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; background: linear-gradient(90deg, transparent, rgba(90,169,255,.5), transparent); animation: scan 1.8s linear infinite; }
.stage.FAILED, .stage.UNSTABLE, .stage.ABORTED { background: color-mix(in srgb, var(--error) 70%, #000); color: #fff; }
.stage.PAUSED_PENDING_INPUT { background: color-mix(in srgb, var(--critical) 55%, #000); color: #fff; animation: slowblink 1.6s infinite; }
.stage.slow { border-bottom-color: var(--warn); }
.input-banner { margin: 12px 0 0; padding: 12px 14px; border: 1px solid var(--critical); border-radius: 3px; background: rgba(255,45,85,.14); color: #ffd9e0;
  font: 600 13px/1.4 var(--head); letter-spacing: .06em; display: flex; gap: 10px; align-items: center; animation: slowblink 2s infinite; }
.others { margin-top: 10px; font: 400 11px var(--mono); color: var(--text-3); }

/* -- pods -------------------------------------------------------------------- */
details > summary { list-style: none; cursor: pointer; }
details > summary::-webkit-details-marker { display: none; }
.stack { display: flex; height: 10px; border-radius: 2px; overflow: hidden; background: var(--steel); margin-top: 8px; }
.stack i { transition: flex-grow .8s var(--ease); min-width: 0; }
.stack .upgraded { background: var(--success); } .stack .old { background: var(--old); } .stack .new { background: var(--new); }
.stack .problem { background: var(--error); } .stack .unknown { background: #3a444e; }
.podsum { font: 400 12px var(--mono); color: var(--text-2); display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.podsum b { color: var(--text); font-weight: 600; }
.tabs { display: flex; gap: 2px; margin: 12px 0 8px; border-bottom: 1px solid var(--line); }
.tabs button { background: none; border: 0; border-bottom: 2px solid transparent; padding: 6px 10px; font: 500 12px var(--head); color: var(--text-2); }
.tabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--lane); }
.rows { display: grid; gap: 2px; }
.row { display: grid; grid-template-columns: 44px 1fr auto auto; gap: 10px; align-items: center; padding: 5px 8px; background: #12161a; border-radius: 2px; font: 400 12px var(--mono); animation: slide-in .4s var(--ease); min-width: 0; }
.row .age { color: var(--lane); font-weight: 600; }
.row .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row .nm small { color: var(--text-3); margin-left: 8px; }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.two h4 { font: 500 11px var(--head); letter-spacing: .08em; color: var(--text-2); margin: 0 0 6px; }
.grp { display: flex; justify-content: space-between; gap: 8px; padding: 4px 8px; background: #12161a; border-radius: 2px; margin-bottom: 2px; font-size: 12px; animation: slide-in .4s var(--ease); }
.grp b { font: 600 12px var(--mono); }

/* -- plan -------------------------------------------------------------------- */
.phase-sec { border-top: 1px solid var(--line); }
.phase-sec:first-of-type { border-top: 0; }
.phase-sec > summary { display: flex; align-items: center; gap: 10px; padding: 9px 2px; }
.phase-sec > summary h3 { font-size: 13px; }
.phase-sec > summary .cnt { font: 400 11px var(--mono); color: var(--text-2); margin-left: auto; }
.phase-sec > summary .bar { width: 80px; height: 4px; background: var(--steel); border-radius: 2px; overflow: hidden; }
.phase-sec > summary .bar i { display: block; height: 100%; background: var(--lane); transform-origin: left; transition: transform .6s var(--ease); }
.phase-sec > summary::before { content: "▸"; color: var(--text-3); font-size: 11px; transition: transform .2s; }
.phase-sec[open] > summary::before { transform: rotate(90deg); }
.gtitle { font: 500 10.5px var(--body); letter-spacing: .06em; color: var(--text-3); padding: 8px 2px 3px; }
.step { display: grid; grid-template-columns: auto 62px 1fr auto; gap: 10px; align-items: start; padding: 6px 6px 6px 8px; border-left: 2px solid transparent; border-radius: 2px; }
.step:hover { background: rgba(255,255,255,.025); }
.step.current { border-left-color: var(--lane); background: color-mix(in srgb, var(--lane) 7%, transparent); }
.step .sid { font: 600 11px var(--mono); color: var(--text-2); padding-top: 3px; }
.step .ttl { background: none; border: 0; padding: 2px 0; text-align: left; font: 400 13px/1.35 var(--body); color: var(--text); }
.step .ttl:hover { color: #fff; text-decoration: underline; text-decoration-color: var(--text-3); }
.step.is-done .ttl { color: var(--text-2); }
.step .meta { display: flex; gap: 6px; align-items: center; padding-top: 2px; font: 400 10.5px var(--mono); color: var(--text-3); white-space: nowrap; }
.scope { font: 600 9px var(--mono); letter-spacing: .1em; padding: 2px 4px; border-radius: 2px; border: 1px solid var(--line-2); color: var(--text-3); }
.scope.shared { color: var(--info); border-color: color-mix(in srgb, var(--info) 40%, transparent); }
.tick { position: relative; width: 24px; height: 24px; flex: none; border: 1.5px solid var(--line-2); border-radius: 3px; background: #0c0f12; padding: 0; display: grid; place-items: center; transition: border-color .15s, background-color .2s; }
button.tick:hover { border-color: var(--lane); }
.tick svg { width: 16px; height: 16px; stroke: #0b0d10; stroke-width: 2.5; fill: none; stroke-dasharray: 24; stroke-dashoffset: 24; }
.tick.done { background: var(--lane); border-color: var(--lane); }
.tick.done svg { stroke-dashoffset: 0; transition: stroke-dashoffset .35s var(--ease) .05s; }
.tick.readonly { border-color: transparent; background: none; }
.tick.readonly.done svg { stroke: var(--lane); }
.tick.fresh.milestone::after { content: ""; position: absolute; inset: -10px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, transparent 30%, var(--lane) 32%, transparent 36%), conic-gradient(from 0deg, var(--lane) 0 4%, transparent 4% 12.5%, var(--lane) 12.5% 16.5%, transparent 16.5% 25%, var(--lane) 25% 29%, transparent 29% 37.5%, var(--lane) 37.5% 41.5%, transparent 41.5% 50%, var(--lane) 50% 54%, transparent 54% 62.5%, var(--lane) 62.5% 66.5%, transparent 66.5% 75%, var(--lane) 75% 79%, transparent 79% 87.5%, var(--lane) 87.5% 91.5%, transparent 91.5%);
  -webkit-mask: radial-gradient(circle, transparent 45%, #000 46%); mask: radial-gradient(circle, transparent 45%, #000 46%); animation: burst .8s var(--ease) 1 forwards; }
@keyframes burst { from { transform: scale(.4); opacity: 1; } to { transform: scale(1.7); opacity: 0; } }
.steptext { grid-column: 2 / -1; margin: 4px 0 8px; padding: 10px 12px; background: #0c0f12; border: 1px solid var(--line); border-radius: 3px; font-size: 12.5px; color: var(--text-2); animation: slide-in .3s var(--ease); overflow-x: auto; }
.steptext p { margin: 0 0 8px; white-space: pre-wrap; }
.steptext pre { margin: 0 0 8px; padding: 8px 10px; background: #07090b; border: 1px solid var(--line); border-radius: 2px; font: 400 11.5px/1.5 var(--mono); color: #c9d4de; overflow-x: auto; }
.steptext code { font: 400 11.5px var(--mono); color: #c9d4de; background: #07090b; padding: 1px 4px; border-radius: 2px; }
.steptext pre code { background: none; padding: 0; }

/* -- timeline ------------------------------------------------------------------ */
.filters { display: flex; gap: 4px; flex-wrap: wrap; }
.filters button { background: none; border: 1px solid var(--line-2); border-radius: 12px; padding: 3px 10px; font: 500 11px var(--head); color: var(--text-2); }
.filters button[aria-pressed="true"] { background: var(--text); color: #0b0d10; border-color: var(--text); }
.tl { position: relative; display: grid; gap: 0; }
.tl::before { content: ""; position: absolute; left: 67px; top: 4px; bottom: 4px; width: 1px; background: var(--line-2); }
.ev { position: relative; display: grid; grid-template-columns: 50px 34px 1fr; gap: 0; padding: 7px 0; align-items: start; animation: ev-in .5s var(--ease); }
@keyframes ev-in { from { opacity: 0; transform: translateY(-14px); } }
.ev .time { font: 400 11px/20px var(--mono); color: var(--text-2); }
.ev .src { position: relative; z-index: 1; width: 22px; height: 22px; margin-left: 6px; border-radius: 50%; background: var(--panel-2); border: 1px solid currentColor; display: grid; place-items: center; }
.ev .src .icon { width: 12px; height: 12px; }
.ev .txt { font-size: 13px; line-height: 1.4; min-width: 0; overflow-wrap: anywhere; }
.ev .txt .lane-name { font: 600 10px var(--mono); letter-spacing: .1em; margin-right: 6px; color: var(--lane); }
.ev .chips { display: inline-flex; gap: 4px; margin-left: 6px; vertical-align: 1px; }
.ev .chips .chip { font-size: 9px; padding: 1px 5px; }
.ev .detail { font: 400 11px/1.4 var(--mono); color: var(--text-3); margin-top: 2px; overflow-wrap: anywhere; }
.sev-info { color: var(--info); } .sev-success { color: var(--success); } .sev-warn { color: var(--warn); } .sev-error { color: var(--error); }
.sev-critical { color: var(--critical); }
.sev-critical .src { animation: slowblink 1.6s infinite; }
.ev .txt { color: var(--text); }
.more { margin-top: 8px; }

/* -- Claude panel ---------------------------------------------------------------- */
.claude .lead { color: var(--text-2); font-size: 12.5px; margin: 0 0 12px; }
.claude .spark { width: 18px; height: 18px; color: var(--new); }
.claude .spark.lit { animation: spark 1.2s var(--ease) 1; }
@keyframes spark { 30% { transform: scale(1.5) rotate(40deg); filter: drop-shadow(0 0 6px var(--new)); } }
.claude .nums { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.claude .last { margin-top: 12px; display: grid; gap: 6px; }
.claude .last div { font-size: 12.5px; padding-left: 10px; border-left: 2px solid var(--line-2); color: var(--text-2); }
.claude .last time { font: 400 10.5px var(--mono); color: var(--text-3); margin-right: 8px; }
.cost { margin-top: 12px; font: 400 12px var(--mono); color: var(--text-2); }
.cost .bar { height: 3px; background: var(--steel); margin-top: 5px; border-radius: 2px; overflow: hidden; }
.cost .bar i { display: block; height: 100%; background: var(--new); transform-origin: left; transition: transform .6s var(--ease); }

/* -- admin, messages ----------------------------------------------------------------- */
.admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 18px; }
.admin-grid p { color: var(--text-2); font-size: 13px; margin: 0 0 10px; }
.diff { font: 400 12px/1.5 var(--mono); background: #0c0f12; border: 1px solid var(--line); border-radius: 3px; padding: 10px 12px; margin: 10px 0; }
.diff .add { color: var(--success); } .diff .del { color: var(--error); } .diff .ren { color: var(--warn); }
.warnlist { margin: 0; padding-left: 18px; color: var(--warn); font-size: 12.5px; }
.empty { padding: 40px 20px; text-align: center; color: var(--text-2); }
.empty h1 { font-size: 22px; margin-bottom: 8px; color: var(--text); }
.toast { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 50; padding: 10px 16px; border-radius: 3px; background: #2a1215; border: 1px solid var(--error); color: #ffd6d6; font-size: 13px; animation: slide-in .3s var(--ease); }
.toast.ok { background: #10241a; border-color: var(--success); color: #d5f7e4; }

footer { padding: 14px 20px 22px; text-align: center; font: 400 11px var(--body); color: var(--text-3); letter-spacing: .03em; }
footer b { color: var(--text-2); font-weight: 500; }

/* -- big screen mode ----------------------------------------------------------------- */
.tv .topbar .switch, .tv .topbar .health, .tv .topbar .acts, .tv footer, .tv .only-desk, .tv .bay-head .open { display: none; }
.tv main { max-width: none; padding: 22px 28px; }
.tv { font-size: 16px; }
.tv .ring { width: 300px; height: 300px; } .tv .ring .pct { font-size: 78px; }
.tv .now .t { font-size: 20px; } .tv .statusline { font-size: 16px; } .tv .ev .txt { font-size: 16px; } .tv .counter .v { font-size: 26px; }
.tv .bay-head h1 { font-size: 30px; }
.tv .below { grid-template-columns: 1fr; }
.tv.idle, .tv.idle * { cursor: none !important; }

/* -- login ---------------------------------------------------------------------------- */
.login { min-height: 100vh; display: grid; place-items: center; padding: 20px; position: relative; overflow: hidden; }
.signal { position: fixed; background: linear-gradient(90deg, transparent, var(--brand-2), transparent); height: 1px; width: 220px; opacity: .7; top: 0; left: 0; animation: sig-x 9s linear infinite; }
.signal.v { width: 1px; height: 220px; background: linear-gradient(transparent, var(--brand-1), transparent); animation-name: sig-y; }
@keyframes sig-x { from { transform: translate3d(-240px, var(--p), 0); } to { transform: translate3d(110vw, var(--p), 0); } }
@keyframes sig-y { from { transform: translate3d(var(--p), -240px, 0); } to { transform: translate3d(var(--p), 110vh, 0); } }
.login-card { width: min(420px, 100%); text-align: center; }
.login-card .logo { justify-content: center; font-size: 20px; margin-bottom: 26px; }
.login-card .logo-mark { width: 40px; height: 40px; }
.login-card h1 { font-size: 26px; margin-bottom: 22px; }
.login-card form { display: flex; gap: 8px; }
.login-card input { flex: 1; min-width: 0; padding: 12px 14px; background: #0c0f12; border: 1px solid var(--line-2); border-radius: 3px; font: 400 15px var(--mono); letter-spacing: .1em; }
.login-card input:focus { outline: none; border-color: var(--brand-1); }
.login-card .btn { padding: 12px 22px; font-size: 14px; }
.login-card form.error input { border-color: var(--error); animation: shake .4s 1; }
@keyframes shake { 20% { transform: translateX(-8px); } 40% { transform: translateX(7px); } 60% { transform: translateX(-5px); } 80% { transform: translateX(3px); } }
.login-card .msg { color: var(--error); min-height: 20px; margin: 10px 0 0; font-size: 13px; }
.login-card .sub { color: var(--text-3); font-size: 12px; margin-top: 18px; }

/* -- responsive ----------------------------------------------------------------------- */
@media (max-width: 1279px) {
  .bays, .below, .lane-cols { grid-template-columns: 1fr; }
  .topbar { flex-wrap: wrap; gap: 10px 16px; }
  .win-title { display: none; }
}
@media (max-width: 1500px) { .health .dot span { display: none; } }
@media (max-width: 760px) {
  main { padding: 12px 10px 24px; }
  .bay-main { grid-template-columns: 1fr; justify-items: center; }
  .ring, .ring.big { width: 190px; height: 190px; } .ring .pct, .ring.big .pct { font-size: 46px; }
  .counters { grid-template-columns: 1fr 1fr; }
  .kv { grid-template-columns: 1fr 1fr; }
  .two { grid-template-columns: 1fr; }
  .switch button kbd { display: none; } .switch button { padding: 7px 10px; }
  .step { grid-template-columns: auto 50px 1fr; } .step .meta { grid-column: 2 / -1; }
  .clock-digits { font-size: 18px; height: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .caret::after { content: ""; }
}

/* ring: the one glow sweep when a lane is complete */
.ring .glow { fill: none; stroke: #fff; opacity: 0; transform-box: view-box; transform-origin: 50% 50%; }

.mono, pre, code, .ticker, .steptext pre { font-variant-ligatures: none; }
@media (max-width: 1500px) { .rail .chev { font-size: 9.5px; padding-left: 14px; } }
.acts { display: flex; gap: 8px; align-items: center; }
.tv .topbar .acts { display: none; }

/* -- logos ---------------------------------------------------------------------------------- */
.brand-logo { height: 30px; width: auto; display: block; }
.logo .co { font: 600 10px/1.25 var(--head); letter-spacing: .14em; text-transform: uppercase; color: var(--text-2); }
.lane-logo { height: 40px; width: auto; display: block; flex: none; }
.bay-head { align-items: center; }
.lane-id { display: flex; flex-direction: column; gap: 1px; padding-left: 14px; border-left: 1px solid var(--line-2); }
.bay-head .btn.open { display: inline-flex; align-items: center; gap: 8px; border-color: color-mix(in srgb, var(--lane) 60%, transparent); color: var(--text); }
.bay-head .btn.open:hover { background: color-mix(in srgb, var(--lane) 18%, #171c22); }
.login-card .brand-logo { height: 56px; margin: 0 auto 10px; }
.login-card .co { display: block; font: 600 11px var(--head); letter-spacing: .2em; text-transform: uppercase; color: var(--text-2); margin-bottom: 26px; }

/* -- parts that open: always a button with words ------------------------------------------------ */
.expand-btn { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--line-2); border-radius: 3px; background: #171c22;
  font: 500 11.5px/1 var(--head); color: var(--text); white-space: nowrap; }
.expand-btn::after { content: "▾"; color: var(--lane, var(--text-2)); transition: transform .2s; }
details[open] > summary .expand-btn::after { transform: rotate(180deg); }
summary:hover .expand-btn { border-color: var(--lane, #46525e); background: #1c2229; }
.expander .when-open, .expander[open] > summary .when-closed { display: none; }
.expander[open] > summary .when-open { display: inline; }
.phase-sec > summary .expand-btn { margin-left: 4px; }
.phase-sec > summary::before { content: none; }
.readmore { margin-left: 10px; font: 500 10.5px var(--head); color: var(--lane); white-space: nowrap; opacity: .85; }
.step .ttl:hover .readmore { opacity: 1; text-decoration: underline; }
.hint { margin-top: 10px; font-size: 12px; color: var(--text-3); }
.btn .icon { vertical-align: -3px; }

/* -- big screen button --------------------------------------------------------------------------- */
.tv-exit { display: none; }
.tv .tv-exit { display: inline-flex; align-items: center; gap: 6px; margin-left: 14px; transition: opacity .4s; }
.tv.idle .tv-exit { opacity: 0; }

/* -- pod detail, for each stage -------------------------------------------------------------------- */
.ministage { display: grid; grid-template-columns: 120px 1fr auto; gap: 10px; align-items: center; margin-top: 8px; font: 400 11.5px var(--mono); color: var(--text-2); }
.ministage .stack { margin-top: 0; }
.ministage .ml { font: 500 11px var(--head); color: var(--text); }
.ministage b { color: var(--text); }
.stageblk { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.stageblk:first-of-type { border-top: 0; padding-top: 4px; margin-top: 6px; }
.stagehead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.stagehead h3 { font-size: 14px; }
.stagehead .cnt { margin-left: auto; font: 400 12px var(--mono); color: var(--text-2); }
.stagehead .cnt b { color: var(--success); font-size: 14px; }
.stageblk .two { margin-top: 12px; align-items: start; }
.stageblk h4 b { font: 600 12px var(--mono); color: var(--text); margin-left: 4px; }
.pgrp { margin-bottom: 8px; }
.pgname { font: 500 11px var(--head); color: var(--text-2); letter-spacing: .04em; padding: 2px 0 3px; }
.pgname span { font: 400 10.5px var(--mono); color: var(--text-3); margin-left: 4px; }
.pod { display: grid; grid-template-columns: 12px 1fr auto 16px; gap: 8px; align-items: center; padding: 3px 8px; background: #12161a; border-radius: 2px; margin-bottom: 2px; font: 400 11.5px var(--mono); animation: slide-in .4s var(--ease); }
.pod .pn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pod .pv { color: var(--text-2); }
.pod.c-problem { outline: 1px solid color-mix(in srgb, var(--error) 60%, transparent); }
.pod.c-problem .pv { color: var(--error); }
.pod .pdot { animation: none; }

/* -- compact scale: all elements smaller, the text sizes stay (Paul, 12 November) -------------------- */
main { padding: 12px 14px 22px; }
.topbar { padding: 6px 14px; gap: 14px; }
.brand-logo { height: 24px; }
.lane-logo { height: 30px; }
.bays, .below, .lane-cols, .col, .admin-grid { gap: 12px; }
.below, .lane-cols { margin-top: 12px; }
.panel-head { padding: 9px 12px 0; }
.panel-body { padding: 8px 12px 12px; }
.bay-head { padding: 10px 12px 0; gap: 10px; }
.bay-main { padding: 6px 12px 4px; gap: 16px; }
.bay-side { gap: 8px; }
.ring { width: 176px; height: 176px; }
.ring.big { width: 210px; height: 210px; }
.ring .pct { font-size: 46px; }
.ring.big .pct { font-size: 54px; }
.ring .steps { margin-top: 3px; }
.rail { padding: 4px 12px 8px; }
.rail .chev { padding-top: 4px; padding-bottom: 4px; }
.counter { padding: 6px 12px; }
.counter .state { margin-top: 3px; }
.mosaic { padding: 8px 12px 10px; gap: 3px; }
.mosaic .cell { width: 15px; height: 15px; }
.statusline { min-height: 0; }
.btn { padding: 5px 10px; }
.switch button { padding: 5px 12px; }
.expand-btn { padding: 4px 8px; }
.cgroups { gap: 10px 12px; }
.cgroup h3 { margin-bottom: 4px; }
.tiles { gap: 4px; }
.tile { width: 156px; min-height: 0; padding: 6px 8px 6px; }
.tile .ver { margin-top: 3px; }
.tile .dots { margin-top: 4px; gap: 2px; }
.pdot { width: 7px; height: 7px; }
.pulse { height: 40px; margin: 2px 0 6px; }
.ticker { margin-top: 6px; padding: 4px 8px; }
.conveyor { margin-top: 8px; padding-top: 8px; gap: 4px; }
.token { padding: 2px 7px; }
.stages { margin-top: 8px; gap: 3px; }
.stage { padding: 4px 9px 4px 14px; }
.ev { padding: 4px 0; grid-template-columns: 46px 28px 1fr; }
.ev .src { width: 18px; height: 18px; margin-left: 4px; }
.ev .src .icon { width: 10px; height: 10px; }
.tl::before { left: 59px; }
.phase-sec > summary { padding: 5px 2px; }
.step { padding: 3px 6px 3px 8px; }
.tick { width: 20px; height: 20px; }
.tick svg { width: 13px; height: 13px; }
.pod { padding: 2px 8px; }
.row { padding: 3px 8px; }
.stageblk { margin-top: 10px; padding-top: 10px; }
.claude .lead { margin-bottom: 8px; }
footer { padding: 8px 14px 14px; }
.tv .ring { width: 230px; height: 230px; } .tv .ring .pct { font-size: 60px; }
@media (max-width: 760px) { .ring, .ring.big { width: 160px; height: 160px; } .ring .pct, .ring.big .pct { font-size: 40px; } }

/* the percent in the ring: smaller (Paul, 12 November) */
.ring .pct { font-size: 34px; }
.ring.big .pct { font-size: 40px; }
.tv .ring .pct { font-size: 46px; }
@media (max-width: 760px) { .ring .pct, .ring.big .pct { font-size: 30px; } }
.ring .podline { display: none; }
.tile { width: 176px; }

/* overview: the bottom boxes take the space down to the bottom of the screen */
#app { min-height: 100vh; display: flex; flex-direction: column; }
#app > main { flex: 1 1 auto; width: 100%; display: flex; flex-direction: column; }
#app > main > .below { flex: 1 1 auto; }
#app > main > .below > .panel { display: flex; flex-direction: column; }
#app > main > .below > .panel > .panel-body { flex: 1 1 auto; }

/* use the whole screen: no width limit, and the overview timeline fills its box with events */
main, .tv main { max-width: none; }
#app > main > .below { flex: 1 1 0; min-height: 300px; }
#app > main > .below > .panel { min-height: 0; overflow: hidden; }
#app > main > .below > .panel > .panel-body { min-height: 0; overflow: hidden; }
#app > main > .below > .panel[data-key="timeline"] > .panel-body { -webkit-mask-image: linear-gradient(#000 calc(100% - 34px), transparent); mask-image: linear-gradient(#000 calc(100% - 34px), transparent); }

/* top bar: the New Island Technologies logo, and a smaller window clock (Paul, 12 November) */
.brand-logo { height: 32px; }
.login-card .brand-logo { height: 44px; margin: 0 auto 30px; }
.clock-digits { font-size: 16px; height: auto; line-height: 1.25; }
.clock-label { font-size: 9px; }
.clock-local { font-size: 10px; }
.tv .clock-digits { font-size: 22px; }

/* -- refinement: less colour in the chevrons (Paul, 12 November) ----------------------------------
   Done = a thick outline in the lane colour. Active = the moving gradient. Open = quiet steel. */
.rail .chev, .stage { isolation: isolate; }
.rail .chev.done { background: var(--lane); color: var(--text); }
.rail .chev.done b { color: var(--lane); opacity: 1; }
.rail .chev.done::before { content: ""; position: absolute; inset: 2px 3px 2px 2px; z-index: -1; background: #12161b;
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%, 9px 50%); }
.rail .chev.done:first-child::before { clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%); }
.rail .chev.current { background: color-mix(in srgb, var(--lane) 16%, var(--steel)); }
.rail .chev.open { background: #171c22; }

.stage.SUCCESS { background: var(--success); color: var(--text); }
.stage.SUCCESS b { color: var(--success); opacity: 1; }
.stage.SUCCESS::before { content: ""; position: absolute; inset: 1.5px 2.5px 1.5px 1.5px; z-index: -1; background: #12161b;
  clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 50%, calc(100% - 7px) 100%, 0 100%, 7px 50%); }

/* top bar: logo 15% larger; the title sits in the middle between the logo and the window clock */
.brand-logo { height: 37px; }
.brand { flex: 1 1 auto; }
.win-title { flex: 1 1 auto; text-align: center; border-left: 0; padding-left: 0; font: 500 14px/1.2 var(--head); color: var(--text); letter-spacing: .02em; }
.clock { margin-left: 0; }

/* refinement: the "template" mark is on every row in v1, so it is quiet. The AI and masked marks stay clear. */
.ev .chips .chip:not(.ai):not(.amber), .statusline .chip:not(.ai) { border-color: transparent; color: var(--text-3); padding-left: 0; padding-right: 2px; }
.ev .chips .chip[title^="Notice"] { border-color: var(--line-2); color: var(--text-2); padding: 1px 5px; }

/* no progress bars under the top bar: clear space between the bar and the panels */
main { padding-top: 18px; }

/* the thin bar on top of a lane panel is the progress of the lane */
.panel.prog { border-top-color: var(--line-2); }
.panel.prog::before { right: auto; width: var(--prog, 0%); height: 3px; transition: width .9s var(--ease); }

/* top bar 10% deeper (52 px to 57 px). The elements keep their size and sit in the middle. */
.topbar { min-height: 57px; box-sizing: border-box; align-items: center; }
.topbar > *, .brand, .logo { align-self: center; }
.brand { display: flex; align-items: center; }

/* top bar: the elements are one group in the middle of the bar, not spread to the two edges */
.topbar { justify-content: center; gap: 26px; }
.brand { flex: 0 1 auto; gap: 26px; }
.win-title { flex: 0 1 auto; }

/* overall width slightly narrower: room for a system dock on the left or the right */
:root { --side: clamp(14px, 3.6vw, 96px); }
main, .tv main { padding-left: var(--side); padding-right: var(--side); }
.topbar { padding-left: var(--side); padding-right: var(--side); }
footer { padding-left: var(--side); padding-right: var(--side); }
@media (max-width: 1279px) { :root { --side: 14px; } }

/* balanced space around the app: the same small margin on the left and the right (Paul, 12 November).
   The page can never be wider than the window, so the two sides stay equal. */
:root { --side: clamp(14px, 1.25vw, 40px); }
html, body { max-width: 100%; }
#app { width: 100%; max-width: 100vw; overflow-x: clip; }
#app > * { min-width: 0; max-width: 100%; }
.topbar { flex-wrap: wrap; row-gap: 6px; column-gap: clamp(12px, 1.3vw, 26px); }
.brand { gap: clamp(12px, 1.3vw, 26px); min-width: 0; }
@media (max-width: 1700px) { .health .dot span { display: none; } }
/* less space between the panels and the footer line */
main, .tv main { padding-bottom: 6px; }
footer { padding-top: 6px; padding-bottom: 8px; }

/* equal space on the left, the right and the bottom of the app */
footer { padding-top: 8px; padding-bottom: var(--side); }
/* product names in the colour that people know them by */
footer .p-claude { color: #d97757; }
footer .p-k8s { color: #326ce5; }
footer .p-jenkins { color: #d33833; }
footer .p-gitea { color: #609926; }

/* -- cluster bar: neutral colours, between the lanes and the bottom panels ---------------------------- */
.clusterbar { margin-top: 12px; display: flex; align-items: center; gap: 6px 26px; flex-wrap: wrap; padding: 8px 14px; }
.clusterbar::before { background: var(--line-2); }
.ctitle { display: flex; align-items: center; gap: 8px; font: 600 12px var(--head); letter-spacing: .12em; text-transform: uppercase; color: var(--text-2); margin-right: 6px; }
.ctitle small { font: 400 11px var(--body); letter-spacing: 0; text-transform: none; color: var(--text-3); }
.cm { display: flex; align-items: center; gap: 8px; font: 400 12px var(--body); color: var(--text-2); white-space: nowrap; }
.cm .ck { color: var(--text-2); }
.cm .cv { font: 600 13px var(--mono); color: var(--text); min-width: 34px; }
.cm .cbar { width: 84px; height: 6px; background: var(--steel); border-radius: 3px; overflow: hidden; }
.cm .cbar i { display: block; height: 100%; background: #8b98a5; transform-origin: left; transition: transform .9s var(--ease); }
.cm.hot .cbar i { background: var(--warn); }
.cm.hot .cv { color: var(--warn); }
.cm .icon { width: 13px; height: 13px; vertical-align: -2px; }
.tv .clusterbar { margin-top: 14px; }

/* -- the whole page scales with the window width (set by app.js, for windows of 1280 px and wider) ------- */
#app { zoom: var(--z, 1); min-height: calc(100vh / var(--z, 1)); max-width: calc(100vw / var(--z, 1)); }
.scaled .health .dot span { display: inline; }
.scaled .rail .chev { font-size: 10.5px; padding-left: 16px; }
.scaled .rail .chev:first-child { padding-left: 10px; }
.scaled .win-title { display: block; }
.scaled { --side: 23px; }

.clusterbar { gap: 6px 20px; justify-content: space-between; }
.cm .cbar { width: 64px; }
.cm .cv { min-width: 0; }

/* ring: only "44 / 67" under the percent, a bit lower and smaller */
.ring .steps { font-size: 10.5px; margin-top: 9px; color: var(--text-2); }

/* top bar title 15% smaller (14 px to 12 px) */
.win-title { font-size: 11.9px; }

/* window clock 15% smaller: label, time and local time */
.clock-label { font-size: 7.7px; }
.clock-digits { font-size: 13.6px; }
.clock-local { font-size: 8.5px; }
.tv .clock-digits { font-size: 18.7px; }

/* window clock: the label above and the local time below another 15% smaller. The counter keeps its size. */
.clock-label { font-size: 6.5px; }
.clock-local { font-size: 7.2px; }

/* footer line: the text in the middle, the display area of the browser window on the right */
footer { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; column-gap: 16px; text-align: center; }
footer .f-res { text-align: right; font: 400 11px var(--mono); color: var(--text-3); white-space: nowrap; }
.tv footer { display: none; }
@media (max-width: 760px) { footer { grid-template-columns: 1fr; } footer .f-side:first-child { display: none; } footer .f-res { text-align: center; } }
footer .f-res { color: var(--error); }

/* footer, right side: boxes that open the hub at a popular screen size (admin), then the display area */
footer .f-right { display: flex; justify-content: flex-end; align-items: baseline; gap: 10px; white-space: nowrap; }
.snaps { display: inline-flex; gap: 4px; }
.snap { border: 1px solid var(--line-2); background: #171c22; border-radius: 3px; padding: 2px 6px; font: 400 10.5px/1.3 var(--mono); color: var(--text-2); }
.snap:hover { border-color: var(--error); color: var(--text); }
.snap.on { border-color: var(--error); color: var(--error); }
@media (max-width: 760px) { footer .f-right { justify-content: center; flex-wrap: wrap; } }

/* login page: the screen size boxes and the display area, bottom right */
.login-sizes { position: fixed; right: 24px; bottom: 20px; display: flex; align-items: baseline; gap: 10px; white-space: nowrap; }
.login-sizes .f-res { font: 400 11px var(--mono); color: var(--error); }
@media (max-width: 760px) { .login-sizes { left: 0; right: 0; justify-content: center; flex-wrap: wrap; } }

/* lane logos look the same size: each has its own height, in a box of one height */
.lane-logo-box { display: inline-flex; align-items: center; height: 30px; flex: none; }
/* the lane header in the lane view has the same height as a lane bay in the overview: no jump on a view change */
.mosaic { min-height: 51px; align-content: flex-start; }
.bay-side { min-height: 96px; align-content: center; }

/* footer line: two groups, the credits and the screen size tools. The space on the left, between the two
   groups and on the right is the same. */
footer { display: flex; justify-content: space-evenly; align-items: baseline; column-gap: 0; padding-left: 0; padding-right: 0; }
footer .f-side:first-child { display: none; }
footer .f-text, footer .f-right { flex: 0 0 auto; }
@media (max-width: 760px) { footer { flex-direction: column; align-items: center; row-gap: 6px; padding-left: var(--side); padding-right: var(--side); } }

/* the logo in the top bar goes to the overview */
.logo-btn { background: none; border: 0; padding: 0; cursor: pointer; border-radius: 3px; }
.logo-btn:hover .brand-logo { filter: brightness(1.15); }

/* ==== review of 12 November =====================================================================
   Component tile: the name has the whole first line. The state badge is on the last line, next to the pod dots. */
.tile .name .lbl { flex: 1 1 auto; min-width: 0; }
.tile .foot { display: flex; align-items: center; gap: 6px; margin-top: 4px; position: relative; z-index: 1; }
.tile .foot .dots { margin-top: 0; flex: 1 1 auto; min-width: 0; }

/* NOW card: a link to the current step in the plan of the lane */
.now .k { flex-wrap: wrap; row-gap: 2px; }
.now-link { background: none; border: 0; padding: 0 2px; font: 500 10.5px var(--head); letter-spacing: 0; color: var(--lane); opacity: .85; white-space: nowrap; }
.now-link:hover { opacity: 1; text-decoration: underline; }

/* overview, right column: the milestones above the Claude panel */
#app > main > .below > .side { min-height: 0; overflow: hidden; }
.side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.side > .panel { flex: 0 0 auto; }
.side > .miles { flex: 1 1 auto; min-height: 120px; display: flex; flex-direction: column; }
.miles > .panel-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.mhint { font: 400 11px var(--body); color: var(--text-3); }
.mrow { display: grid; grid-template-columns: minmax(0, 1fr) 84px 84px; column-gap: 12px; align-items: baseline; padding: 5px 0; border-top: 1px solid var(--line); font-size: 13px; }
.mrow.mhead { border-top: 0; padding-top: 0; }
.mrow.mhead .mc { font: 600 10px var(--mono); letter-spacing: .1em; color: var(--lane); }
.mrow .mt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mrow .mt .id { display: inline-block; min-width: 44px; font: 600 11px var(--mono); color: var(--text-2); margin-right: 6px; }
.mrow .mc { font: 400 12px var(--mono); text-align: right; white-space: nowrap; color: var(--text-3); }
.mrow .mc.done { color: var(--lane); }
.mrow .mc.next { color: var(--text); }

/* the overview timeline scrolls in its box (not on the big screen) */
.panel-body { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
body:not(.tv) #app > main > .below > .panel[data-key="timeline"] > .panel-body { overflow-y: auto; padding-bottom: 30px; }

/* cluster bar: in demo mode the last value stays clear of the corner ribbon */
.demo .clusterbar { padding-right: 58px; }

/* admin: the table of the parts of the hub */
.parts { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.parts th { text-align: left; font: 500 9.5px var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); padding: 0 12px 4px 0; }
.parts td { padding: 4px 12px 4px 0; border-top: 1px solid var(--line); color: var(--text-2); white-space: nowrap; }
.parts td:first-child { color: var(--text); }
.parts td:nth-child(2) { font: 600 11.5px var(--mono); }
.warnlist { margin-top: 10px; }
@media (min-width: 761px) { .admin-grid .wide { grid-column: span 2; } }

/* windows narrower than 1280 px: one column. No fixed height for the bottom boxes: the page scrolls.
   The milestones come before the long timeline. */
@media (max-width: 1279px) {
  #app > main > .below { flex: none; min-height: 0; }
  body:not(.tv) #app > main > .below > .panel[data-key="timeline"] > .panel-body { overflow: visible; padding-bottom: 12px; -webkit-mask-image: none; mask-image: none; }
  #app > main > .below > .side { display: contents; }
  .side > .miles { order: 1; min-height: 0; }
  .below > .panel[data-key="timeline"] { order: 2; }
  .side > .claude { order: 3; }
}

/* phone */
@media (max-width: 760px) {
  .topbar { position: static; }
  .health { justify-content: center; gap: 6px 12px; }
  .health .dot span { display: inline; }
  .acts [data-act="tv"], .snaps { display: none; }
  .bay-head { flex-wrap: wrap; }
  .bay-head .btn.open { white-space: nowrap; }
  /* phase rail: only the current phase has its name. A phase that is done has a tick. */
  .rail { gap: 1px; }
  .rail .chev { display: flex; flex-direction: column; justify-content: center; min-height: 34px; padding: 4px 6px 4px 14px; }
  .rail .chev:first-child { padding-left: 8px; }
  .rail .chev:not(.current) .cl, .rail .chev:not(.current) .cn { display: none; }
  .rail .chev.current { flex: 5 1 0; }
  .clusterbar { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 16px; }
  .clusterbar .ctitle { grid-column: 1 / -1; }
  .clusterbar .cm { justify-content: space-between; min-width: 0; }
  .cm .cbar { flex: 1 1 auto; width: auto; min-width: 16px; }
  /* components: the tiles in two columns, one group below the other */
  .cgroups { display: block; }
  .cgroup { margin-bottom: 10px; }
  .tiles { display: grid; grid-template-columns: 1fr 1fr; }
  .tile { width: auto; min-width: 0; }
  .phase-sec > summary .bar { display: none; }
  .mrow { grid-template-columns: minmax(0, 1fr) 62px 62px; column-gap: 8px; }
  .mhint { display: none; }
}
/* demo mode: the lane names of the milestones stay clear of the corner ribbon */
.demo .miles > .panel-body { padding-right: 34px; }
@media (max-width: 760px) { .mrow .mt { white-space: normal; } }
/* Claude panel while the AI writer is off: one line with the count of masked items (and the cost for the admin) */
.claude .kv.one { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.claude .kv.one > div:first-child { display: flex; align-items: baseline; gap: 10px; }
.claude .kv.one .cost { margin-top: 0; }
.mrow { padding: 4px 0; }
