@font-face {
  font-family: "Archivo";
  src: url("/fonts/archivo-var.woff2") format("woff2-variations");
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
}
@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-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/fonts/plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

:root {
  --void: #06080a;
  --panel: #0c1013;
  --panel-raised: #121820;
  --hair: #1e262e;
  --hair-bright: #2b3641;

  --ink: #eef2f6;
  --ink-dim: #a6b3bf;
  --ink-faint: #8a97a3;

  --pass: #34d399;
  --pass-deep: #0f7a52;
  --fail: #fb5f6d;
  --fail-deep: #8f2430;
  --warn: #f2b13c;
  --live: #58a6ff;
  --idle: #55636f;

  --glow-pass: 0 0 0 1px rgb(52 211 153 / 0.34), 0 0 14px -2px rgb(52 211 153 / 0.5);
  --glow-fail: 0 0 0 1px rgb(251 95 109 / 0.34), 0 0 14px -2px rgb(251 95 109 / 0.55);

  --mono: "Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: "Archivo", system-ui, -apple-system, sans-serif;

  --gut: clamp(1rem, 4vw, 3rem);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

*,
*::before,
*::after { box-sizing: border-box; }

/* `hidden` only works through the UA rule `[hidden] { display: none }`, and any
   author `display` declaration outranks it. Several rules here set display, so
   without this the key box and the detail panel render while marked hidden. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(120% 70% at 50% -10%, #0e161c 0%, transparent 60%),
    var(--void);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  font-feature-settings: "ss01";
  -webkit-font-smoothing: antialiased;
}

::selection { background: rgb(88 166 255 / 0.28); color: #fff; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--void); }
::-webkit-scrollbar-thumb {
  background: var(--hair-bright);
  border: 3px solid var(--void);
  border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: #3c4a57; }

:focus-visible {
  outline: 2px solid var(--live);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 99;
  background: var(--panel-raised);
  color: var(--ink);
  padding: 0.6rem 1rem;
  border: 1px solid var(--hair-bright);
  font: 500 0.8rem var(--sans);
}
.skip:focus { left: 1rem; top: 1rem; }

/* ---------------------------------------------------------------- top bar */

.bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 3vw, 2rem);
  padding: 0.9rem var(--gut);
  background: rgb(6 8 10 / 0.82);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--hair);
}

.bar__brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex: none;
}

.mark {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: var(--pass);
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 7px rgb(52 211 153 / 0.55));
}

.bar h1 {
  margin: 0;
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -0.028em;
  font-stretch: 108%;
}

.bar__claim {
  margin: 0;
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar__claim b { color: var(--ink); font-weight: 600; }

.bar__tools {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex: none;
}

.tick {
  font: 400 0.7rem var(--mono);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.44rem 0.8rem;
  background: var(--panel-raised);
  color: var(--ink);
  border: 1px solid var(--hair-bright);
  border-radius: 7px;
  font: 500 0.755rem var(--mono);
  cursor: pointer;
  transition: background 160ms var(--ease), border-color 160ms var(--ease), transform 160ms var(--ease);
}
.btn:hover { background: #18212b; border-color: #3a4753; }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: 0.5; cursor: progress; }

.btn__glyph {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.btn--ghost { background: transparent; }

.is-refreshing .btn__glyph { animation: spin 720ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ board */

main {
  padding: clamp(1.5rem, 4vw, 2.75rem) var(--gut) 5rem;
  max-width: 1500px;
  margin: 0 auto;
}

.board__head { max-width: 68ch; margin-bottom: 1.75rem; }
.board__head h2 {
  margin: 0 0 0.35rem;
  font-size: clamp(1.5rem, 3.4vw, 2.05rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  font-stretch: 112%;
  text-wrap: balance;
}
.board__head p {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.9rem;
  text-wrap: pretty;
}

.lanes { display: flex; flex-direction: column; gap: 1px; background: var(--hair); border: 1px solid var(--hair); border-radius: 12px; overflow: hidden; }

/* A lane is a row holding two controls: the open-panel button and the dispatch
   button. The grid lives on the outer element so they do not share a target. */
.lane {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.8rem clamp(0.9rem, 2vw, 1.4rem);
  background: var(--panel);
  border: 0;
  border-inline-start: 2px solid transparent;
  transition: background 150ms var(--ease), border-color 150ms var(--ease);
}
.lane:hover { background: #101820; border-inline-start-color: var(--hair-bright); }
.lane:has(.lane__body[aria-expanded="true"]) { background: #111a22; border-inline-start-color: var(--live); }
.lane--dead { background: rgb(251 95 109 / 0.04); }

.lane__body {
  display: grid;
  grid-template-columns: minmax(15rem, 22rem) 1fr auto;
  align-items: center;
  gap: clamp(0.9rem, 2.4vw, 2rem);
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}

.lane__head { min-width: 0; }
.lane__act { flex: none; }

/* The repo name is a label, not data. Monospace here made it read as machine
   output and flattened the hierarchy against the SHA beneath it, so it takes
   the display face and the measurements keep the mono. */
.lane__name {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.1rem;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 700;
  font-stretch: 106%;
  letter-spacing: -0.02em;
  min-width: 0;
}
.lane__name > span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Raised to a readable 0.8rem. At 0.68rem this was both too small and
   repeated on every one of 74 rows, which made the board unreadable. */
.lane__meta {
  margin: 0;
  font: 400 0.8rem var(--mono);
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.lane__meta em { color: var(--ink); font-style: normal; font-weight: 600; }
.lane__meta .dot {
  display: inline-block;
  width: 3px;
  height: 3px;
  margin: 0 0.45rem;
  border-radius: 50%;
  background: var(--ink-faint);
  vertical-align: middle;
}
.lane__none { color: var(--ink-faint); font-style: italic; }

.lane__right {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font: 400 0.75rem var(--mono);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Pass/fail tally over the runs we can see. Colour plus a number, so it never
   depends on colour alone. */
.tally { display: inline-flex; gap: 0.3rem; }
.tally__pass,
.tally__fail {
  padding: 0.1rem 0.4rem;
  border-radius: 5px;
  font-weight: 600;
}
.tally__pass { color: var(--pass); background: rgb(52 211 153 / 0.1); }
.tally__fail { color: var(--fail); background: rgb(251 95 109 / 0.1); }

.spark { display: inline-flex; gap: 2px; align-items: flex-end; height: 15px; }
.spark__bar { width: 4px; height: 100%; border-radius: 1px; background: var(--idle); }
.spark__bar--passed { background: var(--pass); }
.spark__bar--failed { background: var(--fail); }
.spark__bar--running { background: var(--live); }
.spark__bar--cancelled,
.spark__bar--skipped { background: var(--hair-bright); }

.run-btn {
  padding: 0.4rem 0.8rem;
  background: #131c24;
  color: var(--ink-dim);
  border: 1px solid var(--hair-bright);
  border-radius: 6px;
  font-family: var(--sans);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 150ms var(--ease), color 150ms var(--ease), border-color 150ms var(--ease);
}
.run-btn:hover:not([disabled]) { background: #16212b; color: var(--ink); border-color: var(--live); }
.run-btn[disabled] { opacity: 0.5; cursor: progress; }

/* ---------------------------------------------------------------- sign in */

.signin {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background:
    radial-gradient(120% 70% at 50% -10%, #0e161c 0%, transparent 60%),
    var(--void);
  z-index: 50;
}
.signin__card {
  width: min(24rem, 100%);
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.75rem 1.6rem 1.6rem;
  background: var(--panel);
  border: 1px solid var(--hair-bright);
  border-radius: 14px;
  box-shadow: 0 18px 48px -20px rgb(0 0 0 / 0.85);
}
.mark--lg { width: 30px; height: 30px; }
.signin__card h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  font-stretch: 112%;
  letter-spacing: -0.035em;
}
.signin__sub { margin: -0.45rem 0 0.3rem; font-size: 0.86rem; color: var(--ink-dim); }

.field { display: flex; flex-direction: column; gap: 0.3rem; }
.field span {
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.field input {
  padding: 0.6rem 0.7rem;
  background: var(--void);
  color: var(--ink);
  border: 1px solid var(--hair-bright);
  border-radius: 7px;
  font: 400 0.9rem var(--mono);
}
.field input:focus { border-color: var(--live); outline: none; }

.signin__error {
  margin: 0;
  padding: 0.55rem 0.7rem;
  background: rgb(251 95 109 / 0.09);
  border: 1px solid rgb(251 95 109 / 0.32);
  border-radius: 7px;
  color: #ffc9ce;
  font: 400 0.8rem var(--mono);
}
.btn--wide { justify-content: center; padding: 0.6rem; font-size: 0.85rem; margin-top: 0.15rem; }

/* -------------------------------------------------------------- filters */

.filters { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.1rem; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem;
  background: var(--panel);
  color: var(--ink-dim);
  border: 1px solid var(--hair);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms var(--ease), color 150ms var(--ease), border-color 150ms var(--ease);
}
.chip b { font: 600 0.75rem var(--mono); color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.chip:hover { background: #101820; color: var(--ink); }
.chip.is-on { background: #16212b; color: var(--ink); border-color: var(--hair-bright); }
.chip.is-on b { color: var(--ink); }
.chip.is-empty { opacity: 0.4; }

.search {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.search svg {
  position: absolute;
  left: 0.5rem;
  width: 14px;
  height: 14px;
  fill: none;
  stroke: var(--ink-faint);
  stroke-width: 2;
  stroke-linecap: round;
  pointer-events: none;
}
.search input {
  width: 12rem;
  padding: 0.42rem 0.6rem 0.42rem 1.9rem;
  background: var(--panel-raised);
  color: var(--ink);
  border: 1px solid var(--hair-bright);
  border-radius: 7px;
  font: 400 0.8rem var(--mono);
}
.search input::placeholder { color: var(--ink-faint); }
.search input:focus { border-color: var(--live); outline: none; }

.empty {
  margin: 0;
  padding: 2.5rem 1rem;
  text-align: center;
  color: var(--ink-dim);
  font: 400 0.88rem var(--mono);
}

.lane__id { min-width: 0; }

/* The repo name is a label, not data. Monospace here made it read as machine
   output and killed the hierarchy against the SHA beneath it, so it takes the
   display face and the measurements keep the mono. */
.lane__name {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.15rem;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 700;
  font-stretch: 106%;
  letter-spacing: -0.022em;
}
.lane__name span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lane__meta {
  margin: 0;
  font: 400 0.7rem var(--mono);
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.lane__meta em { color: var(--ink-dim); font-style: normal; }

.lane__right {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  font: 400 0.7rem var(--mono);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ------------------------------------------------------------------ chain */

.chain { display: flex; align-items: center; min-width: 0; overflow: hidden; }

.node { display: flex; align-items: center; flex: none; }

.node__dot {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--idle);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.09);
  flex: none;
}
.node--passed .node__dot { background: var(--pass); box-shadow: var(--glow-pass); }
.node--failed .node__dot { background: var(--fail); box-shadow: var(--glow-fail); }
.node--running .node__dot { background: var(--live); animation: breathe 1.4s var(--ease) infinite; }
.node--queued .node__dot,
.node--skipped .node__dot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--idle); }
.node--cancelled .node__dot { background: var(--warn); }

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 1px rgb(88 166 255 / 0.4), 0 0 0 0 rgb(88 166 255 / 0.5); }
  50% { box-shadow: 0 0 0 1px rgb(88 166 255 / 0.5), 0 0 0 6px rgb(88 166 255 / 0); }
}

.wire {
  height: 2px;
  width: clamp(14px, 2.4vw, 34px);
  background: var(--hair-bright);
  flex: none;
  position: relative;
}
.wire--live { background: linear-gradient(90deg, var(--pass-deep), var(--pass)); }
.wire--dead { background: linear-gradient(90deg, var(--fail-deep), var(--fail)); }
.wire--flow::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--live), transparent);
  animation: sweep 1.1s linear infinite;
}
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

.chain__more {
  margin-left: 0.7rem;
  font: 400 0.72rem var(--mono);
  color: var(--ink-faint);
  white-space: nowrap;
  flex: none;
}

/* With no run there is no chain to draw, and repeating a sentence on every one
   of 74 rows is noise. The lane's meta line already says why. */
.chain__none {
  display: block;
  width: clamp(40px, 6vw, 90px);
  height: 2px;
  border-radius: 2px;
  background: var(--hair);
}

/* ----------------------------------------------------------------- badges */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.24rem 0.6rem 0.24rem 0.5rem;
  border-radius: 999px;
  font: 600 0.68rem var(--mono);
  letter-spacing: 0.01em;
  text-transform: lowercase;
  border: 1px solid var(--hair-bright);
  color: var(--ink-dim);
  background: var(--panel-raised);
  white-space: nowrap;
}
.badge::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.badge--passed { color: var(--pass); border-color: rgb(52 211 153 / 0.32); background: rgb(52 211 153 / 0.07); }
.badge--failed { color: var(--fail); border-color: rgb(251 95 109 / 0.32); background: rgb(251 95 109 / 0.07); }
.badge--running { color: var(--live); border-color: rgb(88 166 255 / 0.32); background: rgb(88 166 255 / 0.07); }
.badge--cancelled { color: var(--warn); border-color: rgb(242 177 60 / 0.3); background: rgb(242 177 60 / 0.07); }
.badge--idle { color: var(--ink-faint); }

/* ------------------------------------------------------------------ empty */

/* Standalone messages that are not a stage. `display: block` matters: reusing
   .stage here put the text in the 13px dot column and wrapped one word a line. */
.notice {
  display: block;
  background: var(--panel);
  border: 1px solid var(--hair);
  border-radius: 12px;
  padding: 0.4rem;
}

.note {
  padding: 0.9rem 1rem;
  max-width: 70ch;
  border: 1px dashed var(--hair-bright);
  border-radius: 9px;
  background: rgb(255 255 255 / 0.012);
  font-family: var(--sans);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--ink-dim);
}
.note code {
  font: 400 0.85em var(--mono);
  color: var(--ink);
  background: #131c24;
  border: 1px solid var(--hair);
  border-radius: 5px;
  padding: 0.1em 0.4em;
}
.note b { color: var(--ink); font-weight: 600; }
.note--bad { border-color: rgb(251 95 109 / 0.34); background: rgb(251 95 109 / 0.045); color: #ffc9ce; }
.note--bad b { color: var(--fail); }

/* ----------------------------------------------------------------- detail */

.detail {
  margin-top: clamp(2rem, 5vw, 3.25rem);
  padding-top: clamp(1.75rem, 4vw, 2.5rem);
  padding-bottom: 3rem;
  border-top: 1px solid var(--hair);
  animation: rise 420ms var(--ease) both;
}
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); filter: blur(4px); }
  to { opacity: 1; transform: none; filter: none; }
}

.detail__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.4rem;
}
.detail__head h2 {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(1.3rem, 2.8vw, 1.7rem);
  font-weight: 700;
  font-stretch: 108%;
  letter-spacing: -0.032em;
  text-wrap: balance;
}
.detail__meta {
  margin: 0.3rem 0 0;
  font: 400 0.755rem var(--mono);
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.detail__meta em { color: var(--ink-faint); font-style: normal; }

.detail__sub {
  margin: 2rem 0 0.7rem;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 700;
  font-stretch: 108%;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.stages { display: grid; gap: 1px; background: var(--hair); border: 1px solid var(--hair); border-radius: 12px; overflow: hidden; }

.stage {
  background: var(--panel);
  padding: 0.95rem clamp(0.9rem, 2vw, 1.3rem);
  display: grid;
  grid-template-columns: 13px minmax(11rem, 17rem) 1fr auto;
  align-items: start;
  gap: 0.9rem;
}
.stage__name { margin: 0; font: 600 0.83rem var(--mono); letter-spacing: -0.015em; }
.stage__dur { font: 400 0.72rem var(--mono); color: var(--ink-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }

.steps { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0; padding: 0; list-style: none; }

.step {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.22rem 0.55rem;
  border-radius: 6px;
  background: #0f161d;
  border: 1px solid var(--hair);
  font: 400 0.7rem var(--mono);
  color: var(--ink-dim);
}
.step::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--idle);
  flex: none;
}
.step--passed { color: #a7e9cd; border-color: rgb(52 211 153 / 0.22); }
.step--passed::before { background: var(--pass); }
.step--failed { color: #ffc0c6; border-color: rgb(251 95 109 / 0.3); background: rgb(251 95 109 / 0.06); }
.step--failed::before { background: var(--fail); }
.step--running { color: #bcd9ff; border-color: rgb(88 166 255 / 0.28); }
.step--running::before { background: var(--live); }
.step--skipped::before { box-shadow: inset 0 0 0 1.5px var(--idle); background: transparent; }

.runs { display: grid; gap: 1px; background: var(--hair); border: 1px solid var(--hair); border-radius: 12px; overflow: hidden; }

.run {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem clamp(0.9rem, 2vw, 1.3rem);
  background: var(--panel);
  text-decoration: none;
  color: inherit;
  transition: background 150ms var(--ease);
}
.run:hover { background: #101820; }

.run__id {
  font: 600 0.72rem var(--mono);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.run__msg {
  font: 400 0.76rem var(--mono);
  color: var(--ink-dim);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.run__msg b { color: var(--ink); font-weight: 600; }
.run__age { font: 400 0.7rem var(--mono); color: var(--ink-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.run--failed { background: rgb(251 95 109 / 0.045); }

/* ------------------------------------------------------------------- boot */

.boot {
  position: fixed;
  inset: auto 0 0 0;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.8rem var(--gut);
  background: var(--panel-raised);
  border-top: 1px solid var(--hair-bright);
  font-family: var(--sans);
  font-size: 0.88rem;
  color: var(--ink-dim);
  transform: translateY(100%);
  transition: transform 320ms var(--ease), opacity 220ms var(--ease);
  z-index: 30;
}
.boot p { margin: 0; }
.boot__dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--warn);
  flex: none;
  animation: breathe 1.4s var(--ease) infinite;
}
.boot--on { transform: none; }
.boot--bad .boot__dot { background: var(--fail); animation: none; }

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

/* ------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .lane { grid-template-columns: 1fr auto; row-gap: 0.6rem; }
  .lane__body { grid-template-columns: 1fr auto; row-gap: 0.7rem; }
  .lane__chain { grid-column: 1 / -1; }
  .gatebox { grid-template-columns: 1fr; }
  .stage { grid-template-columns: 13px 1fr; }
  .stage__head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; }
  .steps { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
  .bar { flex-wrap: wrap; row-gap: 0.6rem; }
  .bar__claim { order: 3; flex-basis: 100%; }
  .lane { grid-template-columns: 1fr; }
  .lane__act { justify-self: start; }
  .lane__right { justify-content: space-between; }
  .run { grid-template-columns: auto 1fr; }
  .run__age { grid-column: 2; }
}