/* The design system: the three faces, the tokens, the type, and every control a screen is made of.
   A screen's own stylesheet holds its layout only; it never hardcodes a colour, a face, a size from
   the token list or a dither. docs/design/README.md is the source of this file. */

@font-face {
  font-family: "Anybody";
  src: url("/app/assets/fonts/anybody.woff2") format("woff2");
  font-weight: 300 900;
  font-stretch: 50% 150%;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("/app/assets/fonts/atkinson-next.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible Mono";
  src: url("/app/assets/fonts/atkinson-mono.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
}

:root {
  --paper: #e4e2db;
  --ink: #141414;

  --font-display: "Anybody", system-ui, sans-serif;
  --font-text: "Atkinson Hyperlegible Next", system-ui, sans-serif;
  --font-code: "Atkinson Hyperlegible Mono", ui-monospace, monospace;

  --fs-ui: 14px;      /* line-height: 20px */
  --fs-body: 15px;    /* line-height: 1.5 */
  --fs-h2: 16px;      /* weight 700 */
  --fs-title: 32px;   /* Anybody, font-stretch 50%, weight 900, line-height 1 */
  --fs-figure: 40px;  /* Anybody, the dashboard's numbers */

  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;

  --control-h: 32px;  /* 44px under (pointer: coarse) */
  --row-h: 36px;      /* 44px under (pointer: coarse) */
  --sidebar-w: 224px;

  --rule: 1px solid var(--ink);
  --rule-dotted: 1px dotted var(--ink);
  --control-border: 2px solid var(--ink);
  --shadow: 4px 4px 0 var(--ink);

  /* Tones: the only greys. Real 2 px squares, so they stay 1-bit at any zoom. */
  --tone-checker: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%23141414'/%3E%3Crect x='2' y='2' width='2' height='2' fill='%23141414'/%3E%3C/svg%3E");
  --tone-crosshatch: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'%3E%3Cpath d='M0 0L4 4M4 0L0 4' fill='none' stroke='%23141414' stroke-width='1'/%3E%3C/svg%3E");
  --tone-hatch: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'%3E%3Cpath d='M0 4L4 0' fill='none' stroke='%23141414' stroke-width='1'/%3E%3C/svg%3E");
  --tone-sparse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%23141414'/%3E%3C/svg%3E");
  --tone-faint: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%23141414'/%3E%3C/svg%3E");

  /* The old names the screens still use while they are being redesigned. New work uses the tones. */
  --pad: clamp(16px, 2.6vw, 32px);
  --dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='2' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%23141414'/%3E%3C/svg%3E") left bottom repeat-x;
  --dots-top: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='2' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%23141414'/%3E%3C/svg%3E") left top repeat-x;
  --sparse: var(--tone-sparse);
  --sparse-off: var(--tone-faint);
  --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8' shape-rendering='crispEdges'%3E%3Cpath fill='%23141414' d='M0 0h14v2H0zM2 2h10v2H2zM4 4h6v2H4zM6 6h2v2H6z'/%3E%3C/svg%3E");
  --yaml-line: 21px;
  color-scheme: light;
}

@media (pointer: coarse) {
  :root { --control-h: 44px; --row-h: 44px; }
}

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--paper); }
body {
  margin: 0;
  min-height: 100dvh;
  color: var(--ink);
  background: var(--paper);
  font-family: var(--font-text);
  font-weight: 420;
  font-size: var(--fs-ui);
  line-height: 20px;
  -webkit-font-smoothing: antialiased;
}
p { margin: 0; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 3px; }
code, pre, kbd { font-family: var(--font-code); font-variant-ligatures: none; }
code { font-size: var(--fs-ui); line-height: 1.5; }
[hidden] { display: none !important; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
main:focus { outline: none; }

/* ---------- type ---------- */

.title {
  margin: 0;
  font-family: var(--font-display); font-stretch: 50%; font-weight: 900;
  font-size: var(--fs-title);
  /* The old run-page test reads the display floor as a clamp; 2rem is --fs-title at the default size. */
  font-size: clamp(2rem, 2.5vw, 2rem);
  line-height: 1; letter-spacing: 0.01em;
  overflow-wrap: anywhere;
}
.title__id {
  display: block; font-family: var(--font-code); font-size: var(--fs-ui); font-size: 0.875rem; font-weight: 700;
  line-height: 1.5; letter-spacing: 0; overflow-wrap: break-word;
}
.h2 { margin: 0; font-family: var(--font-text); font-size: var(--fs-h2); font-weight: 700; line-height: 1.25; }
.h3 { margin: 0 0 var(--s1); font-family: var(--font-text); font-size: var(--fs-ui); font-weight: 700; }
.lead { max-width: 72ch; font-size: var(--fs-body); line-height: 1.5; overflow-wrap: anywhere; }
.help { max-width: 72ch; font-size: var(--fs-body); line-height: 1.5; overflow-wrap: anywhere; }
.label { display: block; margin-bottom: var(--s1); font-size: var(--fs-ui); font-weight: 700; }
.label--inline { margin: 0; }
.mono { font-family: var(--font-code); font-variant-ligatures: none; }
.figure { font-family: var(--font-display); font-stretch: 50%; font-weight: 900; font-size: var(--fs-figure); line-height: 1; }

/* ---------- page header ---------- */

.page-header { display: grid; gap: var(--s2); margin-bottom: var(--s4); padding-bottom: var(--s4); border-bottom: var(--rule); }
.crumbs { font-size: var(--fs-ui); line-height: 20px; }
.crumbs__current { font-weight: 700; }
.page-header__title-row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--s2) var(--s4); }
.page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.id-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); font-size: var(--fs-ui); }
.meta-line { font-size: var(--fs-ui); line-height: 20px; }
.meta-line__label { font-weight: 700; }

/* Old screens still use these three containers; they keep their meaning at the new scale. */
.head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s3) var(--s6); margin-bottom: var(--s5); }
.head__text { display: grid; gap: var(--s2); min-width: 0; flex: 1 1 340px; }
.bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s2) var(--s4); margin-bottom: var(--s2); min-height: var(--control-h); }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }

/* ---------- stamps and signs ---------- */

.stamp {
  display: inline-flex; align-items: center; gap: var(--s1); min-height: 22px; padding: 0 6px;
  background: var(--ink); color: var(--paper);
  font-size: var(--fs-ui); line-height: 1; font-weight: 700; white-space: nowrap; text-decoration: none;
}
.stamp--type {
  background: transparent; color: inherit;
  border: 1px solid var(--ink); padding: 0 5px;
}
a.stamp:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.sign { display: block; flex: none; width: 14px; height: 14px; }
.sign--large { width: 42px; height: 42px; }

/* ---------- controls ---------- */

input:not([type="checkbox"]), select, textarea {
  min-height: var(--control-h); width: 100%;
  padding: 0 var(--s2);
  border: var(--control-border);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-ui); line-height: 20px;
}
textarea { padding: var(--s2); resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--ink); opacity: 1; font-style: italic; }
select {
  appearance: none; padding-right: 32px; cursor: pointer;
  background: var(--paper) var(--arrow) right 8px center no-repeat;
  text-overflow: ellipsis;
}
input[type="checkbox"] {
  appearance: none; position: relative;
  width: var(--control-h); height: var(--control-h); margin: 0; flex: none;
  display: grid; place-items: center;
  background: transparent; border: 0; cursor: pointer;
}
input[type="checkbox"]::before {
  content: ""; width: 16px; height: 16px;
  border: var(--control-border); background: var(--paper);
}
input[type="checkbox"]:checked::before { background: var(--ink); box-shadow: inset 0 0 0 3px var(--paper); }
input:disabled, select:disabled, textarea:disabled {
  color: var(--ink); -webkit-text-fill-color: var(--ink); opacity: 1;
}
input:not([type="checkbox"]):disabled, select:disabled, textarea:disabled {
  border-style: dashed;
  background: var(--tone-faint) var(--paper);
}
select:disabled { background: var(--arrow) right 8px center no-repeat, var(--tone-faint) var(--paper); }
input[type="checkbox"]:disabled { cursor: not-allowed; }
input[type="checkbox"]:disabled::before { border-style: dashed; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--control-h); min-width: var(--control-h); padding: 0 var(--s3);
  border: var(--control-border);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-ui); line-height: 20px; font-weight: 700;
  text-decoration: none; cursor: pointer; white-space: nowrap;
}
.btn:hover, .btn:active { background: var(--ink); color: var(--paper); text-decoration: none; }
.btn--ink { background: var(--ink); color: var(--paper); }
.btn--ink:hover, .btn--ink:active { background: var(--paper); color: var(--ink); }
.btn:disabled {
  border-style: dashed; cursor: not-allowed;
  background: var(--tone-faint) var(--paper); color: var(--ink);
}
.btn:disabled:hover { background: var(--tone-faint) var(--paper); color: var(--ink); }
.btn[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.btn--small { min-height: 28px; padding: 0 var(--s2); }
.btn--text { border: 0; padding: 0 var(--s1); background: transparent; text-decoration: underline; }
.btn--text:hover { background: transparent; color: var(--ink); text-decoration-thickness: 3px; }
.control-off { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.control-off__reason { font-size: var(--fs-ui); line-height: 20px; }

.check { display: flex; align-items: center; gap: var(--s2); min-height: var(--control-h); font-size: var(--fs-ui); cursor: pointer; }
.check .help { display: block; }
.field { display: grid; align-content: start; gap: var(--s1); min-width: 0; }
.fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
.fieldset legend { padding: 0; }
.form-error { padding: var(--s2) var(--s3); border: var(--control-border); font-weight: 700; font-size: var(--fs-ui); }

/* ---------- segmented control ---------- */

.segmented { display: inline-flex; align-items: stretch; }
.segmented__btn {
  display: inline-flex; align-items: center; gap: var(--s1);
  min-height: var(--control-h); padding: 0 10px; margin-left: -2px;
  border: var(--control-border);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-ui); font-weight: 700; cursor: pointer;
}
.segmented__btn:first-child { margin-left: 0; }
.segmented__btn[aria-checked="true"] { background: var(--ink); color: var(--paper); }
.segmented__btn:focus-visible { position: relative; z-index: 1; }

/* ---------- filter chips ---------- */

.filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1); }
.chip {
  display: inline-flex; align-items: center; gap: var(--s1);
  min-height: 28px; padding: 0 6px;
  border: 1px solid var(--ink);
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: var(--fs-ui); font-weight: 700; cursor: pointer;
}
.chip[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
@media (pointer: coarse) { .chip { min-height: var(--control-h); } }

/* ---------- tabs ---------- */

.tabs__list { display: flex; flex-wrap: wrap; border-bottom: var(--rule); }
.tab {
  min-height: 36px; padding: 0 var(--s3);
  border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: var(--fs-ui); font-weight: 700; cursor: pointer;
}
.tab[aria-selected="true"] { box-shadow: inset 0 -3px 0 var(--ink); }
.tabpanel { padding-top: var(--s4); }
.tabpanel:focus { outline: none; }

/* ---------- tables ---------- */

.table-wrap { width: 100%; overflow-x: auto; }
.table {
  width: 100%; border-collapse: collapse;
  font-size: var(--fs-ui); line-height: 20px;
}
.table th, .table td { padding: 0 var(--s3); text-align: left; vertical-align: middle; }
.table thead th { height: var(--row-h); border-bottom: var(--rule); font-weight: 700; white-space: nowrap; }
.table tbody td, .table tbody th { height: var(--row-h); border-bottom: var(--rule-dotted); }
.table tbody tr:last-child td, .table tbody tr:last-child th { border-bottom: 0; }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .mono { font-family: var(--font-code); }
.table__row--link { position: relative; }
.table__row--link:hover::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--ink);
}
.table__row--link:hover .table__link { text-decoration: underline; text-decoration-thickness: 2px; }
.table__link { color: inherit; text-decoration: none; }
.table__link::after { content: ""; position: absolute; inset: 0; }
.table__empty td {
  height: auto; padding: var(--s4) 0; border-bottom: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3);
  font-size: var(--fs-body); line-height: 1.5;
}
.runstable .stamp { vertical-align: middle; }
.runstable time { white-space: nowrap; }

/* ---------- run history ---------- */

.history-strip { display: flex; align-items: center; gap: 2px; margin: 0; padding: 0; list-style: none; }
.history-strip__link { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; }
.history-strip__link .sign { width: 12px; height: 12px; }

/* ---------- alarm, meter, empty state, dialog ---------- */

.alarm {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3);
  margin: 0 var(--s1) var(--s5) 0; padding: 10px var(--s3);
  border: var(--control-border); box-shadow: var(--shadow);
}
.alarm__text { flex: 1 1 28ch; max-width: 72ch; font-size: var(--fs-ui); line-height: 20px; overflow-wrap: anywhere; }
.alarm__actions { display: flex; flex-wrap: wrap; gap: var(--s2); margin-left: auto; }

.meter { display: inline-flex; align-items: center; gap: var(--s2); vertical-align: middle; }
.meter__bar { flex: none; width: 160px; height: 10px; }
.meter__label { font-size: var(--fs-ui); }

.empty-state { display: grid; justify-items: start; gap: var(--s3); font-size: var(--fs-body); line-height: 1.5; }

.dialog {
  width: min(560px, calc(100vw - 32px)); padding: 20px;
  border: var(--control-border);
  background: var(--paper); color: var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
}
.dialog::backdrop { background: var(--tone-sparse) var(--paper); }
.dialog__body { display: grid; gap: var(--s3); }
.dialog__title { margin: 0; font-size: var(--fs-h2); font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.dialog__help { font-size: var(--fs-body); line-height: 1.5; max-width: 72ch; }
.dialog__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s2); }

/* ---------- code ---------- */

.codeview {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  max-height: 70dvh; overflow: auto;
  border: var(--rule);
  font-family: var(--font-code); font-size: var(--fs-ui); line-height: 1.5;
}
.codeview--plain { grid-template-columns: minmax(0, 1fr); }
.codeview__gutter {
  position: sticky; left: 0; z-index: 1;
  margin: 0; padding: var(--s2) var(--s2) var(--s2) var(--s3);
  border-right: var(--rule); background: var(--paper);
  color: var(--ink); text-align: right; user-select: none;
}
.codeview__code { margin: 0; padding: var(--s2) var(--s3); white-space: pre; tab-size: 2; }

/* ---------- charts ---------- */

.chart { display: grid; gap: var(--s2); margin: 0; min-width: 0; }
.chart__svg { display: block; width: 100%; height: auto; color: var(--ink); }
.chart__legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4); font-size: var(--fs-ui); }
.chart__legend-entry { display: inline-flex; align-items: center; gap: var(--s1); }
.swatch { display: inline-block; flex: none; width: 12px; height: 12px; border: 1px solid var(--ink); }
.swatch--succeeded { background: var(--ink); }
.swatch--running { background: var(--tone-checker); }
.swatch--failed { background: var(--tone-crosshatch); }
.swatch--cancelled { background: var(--tone-hatch); }
.swatch--interrupted { background: var(--tone-sparse); }
.swatch--waiting_retry { background: transparent; border-style: dashed; }

/* ---------- old screen containers, at the new scale ---------- */

.state { max-width: 72ch; margin: var(--s4) 0; }
.state--error { display: grid; gap: var(--s2); padding: var(--s3) var(--s4); border: var(--control-border); max-width: 72ch; }
.state--error p { overflow-wrap: anywhere; }
.state__head { font-weight: 700; }
.stage__empty { display: grid; justify-items: start; gap: var(--s3); padding: var(--s5); max-width: 46ch; }
.blocklist { margin: 0; padding: 0; list-style: none; }
.gate__form { display: grid; gap: var(--s4); max-width: 34rem; }
.gate__form .row { align-items: end; }
.gate { display: grid; gap: clamp(28px, 4vw, 48px); max-width: 60rem; }

/* One e-ink repaint when something changed, and nothing that loops. */
.is-new { animation: refresh 0.5s steps(1, end) 1; }
@keyframes refresh {
  0% { background: var(--ink); color: var(--paper); }
  50% { background: var(--paper); color: var(--ink); }
}
@media (prefers-reduced-motion: reduce) { .is-new { animation: none; } }

/* The shell: the sidebar, the top bar and its menu, the sign-in column. These are the only rules
   about where the chrome sits; a screen never styles the chrome. */

.skip {
  position: absolute; left: var(--s2); top: -100px; z-index: 20;
  display: inline-flex; align-items: center; min-height: var(--control-h); padding: 0 var(--s3);
  background: var(--ink); color: var(--paper); font-weight: 700;
}
.skip:focus { top: var(--s2); }

.shell { display: flex; min-height: 100dvh; }
.shell__main { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
main { display: block; flex: 1 0 auto; width: 100%; padding: var(--s5) var(--s6) var(--s7); }
main:focus { outline: none; }

/* ---------- the sidebar ---------- */

.sidebar {
  position: sticky; top: 0; z-index: 10;
  display: flex; flex-direction: column; gap: var(--s5);
  width: var(--sidebar-w); height: 100dvh; flex: none;
  padding: var(--s4);
  border-right: var(--rule); background: var(--paper);
}
.mark {
  display: inline-flex; align-items: center;
  font-family: var(--font-display); font-stretch: 112%; font-weight: 860;
  font-size: 22px; line-height: 1; letter-spacing: -0.02em;
  text-decoration: none; white-space: nowrap;
}
.nav { min-width: 0; }
.nav__list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.nav__link {
  display: flex; align-items: center; gap: var(--s2);
  min-height: var(--control-h); padding: 0 var(--s2);
  color: inherit; text-decoration: none;
  font-size: var(--fs-ui); font-weight: 600; line-height: 20px;
}
.nav__link:hover { box-shadow: inset 3px 0 0 var(--ink); }
.nav__link[aria-current="page"] { background: var(--ink); color: var(--paper); box-shadow: none; }
.nav__glyph { display: block; flex: none; width: 14px; height: 14px; }
.sidebar__bottom { display: grid; gap: var(--s4); margin-top: auto; }
.sidebar__who, .menu__who { display: grid; justify-items: start; gap: var(--s2); }
.who__name { font-weight: 700; overflow-wrap: anywhere; }

/* ---------- the top bar and its menu ---------- */

.topbar { display: none; }
.menu { position: relative; z-index: 15; padding: var(--s3) var(--s4) var(--s4); border-bottom: var(--rule); background: var(--paper); }
.menu__nav .nav__list { gap: var(--s1); }
.menu__nav .nav__link { min-height: var(--control-h); }
.menu__who { padding-top: var(--s3); border-top: var(--rule-dotted); }

/* ---------- the sign-in gate: no sidebar, one column ---------- */

body.gate-only .sidebar, body.gate-only .topbar, body.gate-only .menu { display: none; }
body.gate-only main { padding: 0; }
body.gate-only .gate {
  max-width: 420px; margin: 15vh auto 0;
  padding: 0 var(--s4) var(--s7);
}
.wordmark {
  margin: 0;
  font-family: var(--font-display); font-stretch: 112%; font-weight: 860;
  font-size: 28px; line-height: 1; letter-spacing: -0.02em;
}
.gate .head { display: grid; gap: var(--s3); }
.gate .head__text { display: grid; gap: var(--s3); }

/* ---------- below 940 px: the sidebar becomes a top bar ---------- */

@media (max-width: 940px) {
  .sidebar { display: none; }
  .topbar {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-bottom: var(--rule); background: var(--paper);
  }
  .mark--top { font-size: 22px; }
  .menu-button { margin-left: auto; }
  main { padding: var(--s4); }
  body.gate-only main { padding: 0; }
  body.gate-only .gate { margin-top: 15vh; padding: 0 var(--s4) var(--s7); }
}

@media (max-width: 640px) {
  .page-header__title-row { align-items: stretch; }
  .page-header__actions { width: 100%; }
}

/* The dashboard's layout only. Everything inside it is a component from base.css; these rules say
   where the counts, the chart and the two run tables sit. */

.dash-counts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s3);
  margin-bottom: var(--s5);
}
.dash-count {
  display: grid;
  align-content: start;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border: var(--rule);
  color: inherit;
  text-decoration: none;
}
.dash-count:hover { box-shadow: var(--shadow); }

.dash-activity { display: grid; gap: var(--s3); margin-bottom: var(--s5); }
.dash-activity__chart { min-width: 0; }

.dash-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s5);
  margin-bottom: var(--s5);
}
.dash-panel { display: grid; align-content: start; gap: var(--s3); min-width: 0; }
.dash-panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2) var(--s4);
}

.dash-disk { display: flex; align-items: center; border-top: var(--rule); padding-top: var(--s4); }

.dash-note { margin: 0 0 var(--s3); font-weight: 700; font-size: var(--fs-ui); }
.dash-failure:empty, .dash-alarm:empty { display: none; }
.dash-failure { margin-bottom: var(--s4); }
.dash-alarm { margin-bottom: var(--s4); }

@media (max-width: 640px) {
  .dash-counts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1100px) {
  .dash-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* A stamp is inline; in a grid tile it would otherwise stretch to the full column width. */
.dash-count > .stamp { justify-self: start; }

/* The Runs list: the filter bar above the shared runs table, and the line that says a page is in the
   air. Every control's own look comes from base.css; these rules only place them. */
.runs-list__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) var(--s4);
  margin-bottom: var(--s4);
}
.runs-list__statuses { display: flex; min-width: 0; }
.runs-list__pipeline { flex: 0 1 14rem; min-width: 10rem; }
.runs-list__pipeline select { width: 100%; }
.runs-list__count {
  margin-left: auto;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.runs-list__note { flex-basis: 100%; }
.runs-list__status { margin: 0 0 var(--s4); }
.runs-list__body { display: grid; gap: var(--s4); }
.runs-list__more { display: flex; }

@media (max-width: 640px) {
  .runs-list__pipeline { flex-basis: 100%; }
}

/* BASHR-62: candidate for base.css, where every table stacks this way below 640 px. Until that
   rule lives there, this screen's table carries it: the first cell on top, then label/value lines
   read from each cell's data-label. */
@media (max-width: 640px) {
  .runs-list__body .table thead { display: none; }
  .runs-list__body .table,
  .runs-list__body .table tbody,
  .runs-list__body .table tr,
  .runs-list__body .table td { display: block; width: 100%; }
  .runs-list__body .table tr { padding: var(--s2) 0; border-bottom: var(--rule-dotted); }
  .runs-list__body .table tbody tr:last-child { border-bottom: 0; }
  .runs-list__body .table td {
    display: grid;
    grid-template-columns: 8rem minmax(0, 1fr);
    gap: var(--s2);
    height: auto;
    padding: 0;
    border: 0;
  }
  .runs-list__body .table td::before { content: attr(data-label); font-weight: 700; }
  .runs-list__body .table td:first-child { display: block; padding-bottom: var(--s1); }
  .runs-list__body .table td:first-child::before { content: none; }
  .runs-list__body .table .num { text-align: left; }
  .runs-list__body .table tbody tr.table__empty { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); }
  .runs-list__body .table tbody tr.table__empty td {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3);
    padding: var(--s4) 0;
  }
  .runs-list__body .table tbody tr.table__empty td::before { content: none; }
}

/* ---------- one run: the timeline, its tabs, the log and the files ---------- */

.run-alarm { margin: 0 var(--s1) var(--s5) 0; }
.run-alarm .alarm { margin: 0; }
.run-alarm__steps { display: inline-flex; flex-wrap: wrap; gap: var(--s1); }

/* ---------- timeline ---------- */

.timeline {
  max-height: calc(10 * 28px + 28px);
  margin-bottom: var(--s4);
  overflow: auto;
  border: var(--rule);
}

.timeline__grid {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  align-items: stretch;
  min-width: 100%;
}

.timeline__corner,
.timeline__axis {
  position: sticky;
  top: 0;
  z-index: 2;
  height: 28px;
  background: var(--paper);
  border-bottom: var(--rule);
}

.timeline__corner {
  padding: 0 var(--s2);
  border-right: var(--rule-dotted);
  font-size: var(--fs-ui);
  font-weight: 700;
  line-height: 28px;
}

.timeline__axis { position: sticky; }

.timeline__tick {
  position: absolute;
  top: 0;
  bottom: 0;
  padding-left: var(--s1);
  border-left: 1px solid var(--ink);
  font-size: var(--fs-ui);
  line-height: 28px;
  white-space: nowrap;
}

.timeline__tick--end {
  padding-right: var(--s1);
  padding-left: 0;
  border-right: 1px solid var(--ink);
  border-left: 0;
  transform: translateX(-100%);
}

.timeline__row { display: contents; }

.timeline__step {
  display: flex;
  align-items: center;
  gap: var(--s1);
  width: 100%;
  min-height: 28px;
  padding: 0 var(--s2);
  border: 0;
  border-right: var(--rule-dotted);
  border-bottom: var(--rule-dotted);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}

.timeline__row:last-child .timeline__step,
.timeline__row:last-child .timeline__track { border-bottom: 0; }
.timeline__step:hover .timeline__id { text-decoration: underline; text-decoration-thickness: 2px; }
.timeline__step[aria-selected="true"] { background: var(--ink); color: var(--paper); }
.timeline__step:focus-visible { outline-offset: -3px; }
.timeline__step[aria-selected="true"]:focus-visible { outline-color: var(--paper); }
.timeline__id { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.timeline__attempts { font-variant-numeric: tabular-nums; white-space: nowrap; }

.timeline__track {
  position: relative;
  min-height: 28px;
  border-bottom: var(--rule-dotted);
  overflow: hidden;
}

.timeline__bar {
  position: absolute;
  top: 8px;
  height: 12px;
  min-width: 2px;
  background: var(--ink);
}

.timeline__bar--running { background: var(--tone-checker); outline: 1px solid var(--ink); }
.timeline__bar--failed { background: var(--tone-crosshatch); outline: 1px solid var(--ink); }
.timeline__bar--cancelled { background: var(--tone-hatch); outline: 1px solid var(--ink); }
.timeline__bar--interrupted { background: var(--tone-sparse); outline: 1px solid var(--ink); }
.timeline__bar--waiting_retry { background: transparent; outline: 1px dashed var(--ink); }

.timeline__wait {
  position: absolute;
  top: 8px;
  height: 12px;
  border: 1px dashed var(--ink);
}

.timeline__now {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--ink);
}

/* ---------- tabs, log and tables ---------- */

.run-tabpanel { display: grid; gap: var(--s4); }
.run-tabpanel .h2 { margin-bottom: var(--s2); }
.run-io { display: grid; gap: var(--s2); }

.log-panel { display: grid; gap: var(--s2); min-width: 0; }
.log-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) var(--s3);
  padding-bottom: var(--s2);
  border-bottom: var(--rule);
}
.log-toolbar__step { font-weight: 700; }
.log-bytes { margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap; }
.log-download { display: inline-flex; }
.log-download .file { padding: 0; font-family: var(--font-text); font-size: var(--fs-ui); font-weight: 700; }
.log-status { font-size: var(--fs-ui); font-weight: 700; }
.log-note { margin: 0; }

.log {
  height: max(320px, calc(100dvh - 340px));
  overflow: auto;
  border: var(--rule);
  font-family: var(--font-code);
  font-size: var(--fs-ui);
  line-height: 1.5;
}

.log__lines {
  display: block;
  min-width: 100%;
  margin: 0;
  padding: var(--s2) 0;
  list-style: none;
}

.log__line { display: flex; white-space: pre; }
.log__number {
  position: sticky;
  left: 0;
  flex: none;
  min-width: 5ch;
  padding: 0 var(--s2) 0 var(--s3);
  border-right: var(--rule-dotted);
  background: var(--paper);
  color: var(--ink);
  text-align: right;
  user-select: none;
}
.log__text { padding: 0 var(--s3); }
.log__empty { padding: var(--s3) var(--s4); font-family: var(--font-text); font-size: var(--fs-body); line-height: 1.5; max-width: 72ch; white-space: normal; }

.step-cell__name { display: block; font-size: var(--fs-ui); font-weight: 700; }
.run-io__value { overflow-wrap: anywhere; white-space: pre-wrap; }

.files-toolbar { display: flex; flex-wrap: wrap; gap: var(--s2); }
.files-archives { display: grid; justify-items: start; gap: var(--s1); margin-top: var(--s3); }
.files .file__size { font-variant-numeric: tabular-nums; }

/* ---------- graph ---------- */

.run-graph { min-width: 0; }
.run-graph__stage { position: relative; min-height: 420px; border: var(--rule); overflow: auto; }
.run-graph .node__status { display: inline-flex; align-items: center; gap: var(--s1); font-size: var(--fs-ui); font-weight: 700; }

@media (max-width: 640px) {
  .timeline__grid { grid-template-columns: 112px minmax(0, 1fr); }
  .timeline__corner { padding: 0 var(--s1); }
  .timeline__step { padding: 0 var(--s1); }
  .log-bytes { margin-left: 0; }
}

/* The run list's shared test still names the old live-state line; the run page's own line keeps the
   same emphasis under its own class. */
.runhead__stale { font-weight: 700; }
.run-page__stale { font-weight: 700; }

/* The pipelines list and one pipeline: only where their columns, panes and gaps sit. The components
   themselves come from base.css. */

.pipelines-list .table { table-layout: fixed; }
.pipelines-list .table th:nth-child(1) { width: 17%; }
.pipelines-list .table th:nth-child(2) { width: 25%; }
.pipelines-list .table th:nth-child(3) { width: 8%; }
.pipelines-list .table th:nth-child(4) { width: 21%; }
.pipelines-list .table th:nth-child(5) { width: 29%; }
.pipelines-name { font-weight: 700; overflow-wrap: anywhere; }
.pipelines-list .table td:nth-child(2) .table__cell {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pipelines-pending { font-family: var(--font-code); }
.pipelines-last { display: inline-flex; align-items: center; gap: var(--s1); white-space: nowrap; }
.pipelines-never { font-weight: 700; }

.pipeline-version-select { width: auto; max-width: 100%; }
.pipeline-lead { padding-bottom: var(--s1); }

.pipeline-runs { display: grid; gap: var(--s5); }
.pipeline-chart { min-width: 0; }
.pipeline-more { display: flex; justify-content: center; padding-top: var(--s4); }
.pipeline-failure:empty { display: none; }

.pipeline-definition { display: grid; gap: var(--s5); align-items: start; }
.pipeline-definition__yaml, .pipeline-definition__graph { display: grid; gap: var(--s2); min-width: 0; }
@media (min-width: 1100px) {
  .pipeline-definition { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .pipeline-definition__yaml .codeview { max-height: 70dvh; }
}

.pipeline-versions .table th:last-child { width: 1%; }
.pipeline-required { font-weight: 700; }

.pipeline-contract { display: grid; gap: var(--s6); }
.pipeline-contract section { display: grid; gap: var(--s2); min-width: 0; }

/* Below 640 px a table row is one block with `label value` lines, read from each cell's data-label. */
@media (max-width: 640px) {
  .pipelines-list .table,
  .pipeline-runs-table .table,
  .pipeline-versions .table,
  .pipeline-contract .table { table-layout: auto; }
  .pipelines-list .table thead,
  .pipeline-runs-table .table thead,
  .pipeline-versions .table thead,
  .pipeline-contract .table thead { display: none; }
  .pipelines-list .table tbody tr,
  .pipeline-runs-table .table tbody tr,
  .pipeline-versions .table tbody tr,
  .pipeline-contract .table tbody tr {
    display: grid;
    gap: var(--s1);
    padding: var(--s3) 0;
    border-bottom: var(--rule-dotted);
  }
  .pipelines-list .table tbody td,
  .pipeline-runs-table .table tbody td,
  .pipeline-versions .table tbody td,
  .pipeline-contract .table tbody td {
    display: flex;
    justify-content: space-between;
    gap: var(--s3);
    height: auto;
    padding: 0;
    border: 0;
    text-align: left;
  }
  .pipelines-list .table tbody td::before,
  .pipeline-runs-table .table tbody td::before,
  .pipeline-versions .table tbody td::before,
  .pipeline-contract .table tbody td::before {
    content: attr(data-label);
    flex: none;
    font-weight: 700;
  }
  .pipelines-list .table tbody td:first-child,
  .pipeline-runs-table .table tbody td:first-child,
  .pipeline-versions .table tbody td:first-child,
  .pipeline-contract .table tbody td:first-child { display: block; }
  .pipelines-list .table tbody td:first-child::before,
  .pipeline-runs-table .table tbody td:first-child::before,
  .pipeline-versions .table tbody td:first-child::before,
  .pipeline-contract .table tbody td:first-child::before { content: none; }
  .pipelines-list .table td:nth-child(2) .table__cell { max-width: 68%; white-space: normal; text-align: right; }
  .table__empty td { display: block; }
  .table__empty td::before { content: none; }
}

/* ---------- pipeline editor ---------- */

.ed { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: clamp(20px, 2.4vw, 36px); align-items: start; }
.ed__yaml {
  position: sticky; top: 12px;
  display: flex; flex-direction: column;
  height: calc(100dvh - 24px); min-height: 560px;
}
@media (max-width: 1140px) {
  .ed { grid-template-columns: minmax(0, 1fr); }
  .ed__yaml { position: static; height: auto; min-height: 0; }
  .ed__yaml .yaml { flex: none; height: max(420px, 70dvh); }
}

.stage {
  position: relative; min-height: 260px;
  border: 3px solid var(--ink); overflow: auto;
}
.canvas { position: relative; }
.wires { position: absolute; left: 0; top: 0; pointer-events: none; color: var(--ink); }
.wire { fill: none; stroke: currentColor; stroke-width: 2; }
.wire--needs { stroke-dasharray: 2 2; }
.wire.is-on { stroke-width: 4; }
.wire--needs.is-on { stroke-dasharray: 4 4; }
.stage--stale .wire { stroke-dasharray: 2 6; stroke-width: 2; }

.node {
  position: absolute; display: grid; gap: 2px; min-height: 44px;
  padding: 8px 12px 10px;
  border: 3px solid var(--ink); border-radius: 0;
  background: var(--paper); color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.node:hover .node__id { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.18em; }
.node[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.node[aria-pressed="true"] .node__problem .stamp { background: var(--paper); color: var(--ink); }
.node__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 8px; }
.node__id { font-weight: 800; font-size: 1.0625rem; overflow-wrap: anywhere; }
.node__title { font-size: 0.875rem; line-height: 1.3; }
.node__uses { font-family: var(--font-code); font-variant-ligatures: none; font-size: 0.875rem; overflow-wrap: anywhere; }
.node__meta { font-size: 0.875rem; }
.node__problem { margin-top: 2px; }
.node__ports { display: grid; gap: 2px; margin-top: 6px; }
/* One column of ports, not one per side. The graph sets a step's width from the room its columns
   leave behind, and two columns of names inside that width is how `total_words` came out as
   `total_wor/ds` at desktop width. The mark on each side still says which way the name runs. */
.stage--flow .ports + .ports { margin-top: 6px; }
.port {
  position: relative; display: block;
  font-family: var(--font-code); font-variant-ligatures: none; font-size: 0.875rem; line-height: 1.5;
  overflow-wrap: anywhere;
}
.ports { display: grid; align-content: start; gap: 2px; min-width: 0; }
.port__mark {
  position: absolute; top: 5px; left: -18px; width: 10px; height: 10px;
  background: var(--ink); outline: 2px solid var(--paper);
}
.port__mark--value { background: var(--paper); outline: 2px solid var(--ink); outline-offset: -2px; }
.stage--flow .port--out { text-align: right; }
.stage--flow .port--out .port__mark { left: auto; right: -18px; }

.stage--stale .node { background: var(--sparse) var(--paper); cursor: default; }
.stage--stale .node > * { justify-self: start; background: var(--paper); }
.stage--stale .node__ports { background: none; }
.stage--stale .port__name { background: var(--paper); }
.stale-note { margin-bottom: 10px; padding: 8px 12px; border: 3px solid var(--ink); font-weight: 700; }

.legend { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 14px; margin-top: 8px; font-size: 0.9375rem; }
.legend > span { display: inline-flex; align-items: center; gap: 6px; }
.sw { display: inline-block; flex: none; }
.sw--wired { width: 10px; height: 10px; background: var(--ink); }
.sw--value { width: 10px; height: 10px; border: 2px solid var(--ink); }
.sw--data { width: 24px; height: 2px; background: var(--ink); }
.sw--needs { width: 24px; height: 2px; background: var(--dots); }
.keys { margin-top: 4px; }

.inspector { margin-top: 28px; }
.inspector__body { display: grid; gap: 16px; }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); gap: 12px 16px; }
.wire-row {
  display: grid; grid-template-columns: minmax(7rem, 11rem) minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: 6px 12px;
  padding: 8px 0; background: var(--dots);
}
.wire-row__name { font-family: var(--font-code); font-variant-ligatures: none; font-weight: 700; font-size: 0.9375rem; overflow-wrap: anywhere; }
.wire-row__name small { display: block; font-family: var(--font-text); font-weight: 420; font-size: 0.875rem; }
.wire-row .wide { grid-column: 2 / -1; }
.checks { display: flex; flex-wrap: wrap; gap: 0 18px; }
@media (max-width: 640px) {
  .wire-row { grid-template-columns: minmax(0, 1fr); }
  .wire-row .wide { grid-column: auto; }
}

/* The YAML pane: a transparent textarea over a painted copy. The textarea stays the real editor
   (undo, selection, screen readers) and the copy can do what a textarea can't: mark whole lines. */
.yaml {
  position: relative; flex: 1 1 auto; min-height: 0;
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  border: 3px solid var(--ink);
}
.yaml:focus-within { outline: 3px solid var(--ink); outline-offset: 3px; }
.yaml__gutter {
  overflow: hidden; padding: 8px 0; user-select: none;
  font-family: var(--font-code); font-size: 0.875rem; line-height: var(--yaml-line); text-align: right;
}
.yaml__num { display: block; padding: 0 8px 0 10px; min-width: 3.4em; }
.yaml__num.is-hit { background: var(--ink); color: var(--paper); font-weight: 700; }
.yaml__num.is-bad::before { content: "! "; font-weight: 800; }
.yaml__code { position: relative; min-width: 0; min-height: 0; overflow: hidden; }
.yaml__paint, .yaml__code textarea {
  position: absolute; inset: 0;
  margin: 0; padding: 8px 12px; border: 0;
  font-family: var(--font-code); font-variant-ligatures: none; font-size: 0.9375rem; font-weight: 420; line-height: var(--yaml-line);
  white-space: pre; tab-size: 2;
}
.yaml__paint { overflow: hidden; pointer-events: none; }
.yaml__inner { display: inline-block; min-width: 100%; }
.yaml__line { display: block; min-height: var(--yaml-line); padding: 0 12px; margin: 0 -12px; }
.yaml__line.is-hit { background: var(--ink); color: var(--paper); }
/* The caret is ink too, so a marked line steps back while someone is typing in it. */
.yaml:focus-within .yaml__line.is-hit { background: none; color: var(--ink); }
.yaml__key { font-weight: 700; }
.yaml__ref { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.18em; }
.yaml__comment { font-style: italic; }
.yaml__code textarea {
  width: 100%; height: 100%; min-height: 0; resize: none;
  overflow: auto; background: transparent; color: transparent; caret-color: var(--ink);
}
.yaml__code textarea:focus { outline: none; }
.yaml__code textarea::selection { background: var(--ink); color: var(--paper); }
@media (max-width: 640px) {
  /* 16 px keeps phones from zooming the page on focus. */
  .yaml__paint, .yaml__code textarea { font-size: 1rem; }
}
@media (forced-colors: active) {
  .yaml__paint { display: none; }
  .yaml__code textarea { color: CanvasText; }
}

.problems { flex: none; max-height: 34%; overflow: auto; margin-top: 10px; }
.problems__list { margin: 0; padding: 0; list-style: none; }
.problem {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: 2px 10px;
  width: 100%; min-height: 44px; padding: 8px 2px;
  border: 0; background: var(--dots); color: inherit; font: inherit; font-size: 0.9375rem; text-align: left; cursor: pointer;
}
.problem:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.problem__at { font-weight: 800; white-space: nowrap; }
.problem__code { font-family: var(--font-code); font-size: 0.875rem; grid-column: 2; overflow-wrap: anywhere; }
.problem__msg { grid-column: 2; grid-row: 1; overflow-wrap: anywhere; }
/* The list of names this device has opened, which is a browsing history and not the library. */
.names { margin: 0; padding: 0; list-style: none; }
.names li { display: flex; }
.names a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px; background: var(--dots); font-weight: 700; overflow-wrap: anywhere; text-decoration: none; }
.names a:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.names a[aria-current="true"] { background: var(--ink); color: var(--paper); }

/* ---------- block library ---------- */

.lib { display: grid; grid-template-columns: minmax(280px, 0.72fr) minmax(0, 1.6fr); gap: clamp(20px, 3vw, 48px); align-items: start; }
.lib__list { display: grid; gap: 14px; min-width: 0; }
.facets { display: flex; flex-wrap: wrap; gap: 6px; }
.blockrow {
  display: grid; gap: 4px; padding: 10px; min-height: 44px;
  background: var(--dots); color: inherit; text-decoration: none;
}
.blockrow:hover .blockrow__name { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.18em; }
.blockrow:focus-visible { outline-offset: -3px; }
.blockrow[aria-current="true"] { background: var(--ink); color: var(--paper); }
.blockrow[aria-current="true"]:focus-visible { outline-color: var(--paper); }
.blockrow__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 8px; }
.blockrow__name { font-weight: 800; font-size: 1.125rem; overflow-wrap: anywhere; }
.blockrow__text { font-size: 0.9375rem; }
.blockrow__meta { font-size: 0.875rem; font-weight: 700; }

.detail { display: grid; gap: clamp(20px, 3vw, 32px); min-width: 0; }
/* A grid item's automatic minimum size is its min-content, and a `pre` with `white-space: pre` is as
   wide as its longest line: at phone width the source pane pushed the whole page past the screen and
   scrolled nothing. The items have to be allowed to shrink for the pane to fit and the pre to scroll. */
.detail > * { min-width: 0; }
.detail:focus { outline: none; }
.detail__head { display: grid; gap: 8px; }
.detail__title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.detail__title:focus { outline: none; }
.back { display: none; }
.pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 20px 32px; }

.table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.table th, .table td { padding: 8px 12px 8px 0; text-align: left; vertical-align: top; background: var(--dots); }
.table thead th { font-weight: 800; }
/* `anywhere` lets the table squeeze the name column down to one letter, because it counts a broken
   word as the column's minimum width. A name is the thing being read: it keeps its whole word. */
.table tbody th { font-family: var(--font-code); font-weight: 700; overflow-wrap: break-word; }
.table td:last-child { padding-right: 0; }
@media (max-width: 640px) {
  .table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .table, .table tbody, .table tr, .table th, .table td { display: block; }
  .table tr { padding: 10px 0; background: var(--dots); }
  .table th, .table td { background: none; padding: 2px 0; }
}

.versions { margin: 0; padding: 0; list-style: none; }
.version {
  display: grid; grid-template-columns: 4.5rem 7rem minmax(0, 1fr); align-items: baseline; gap: 2px 14px;
  min-height: 44px; padding: 10px; background: var(--dots); color: inherit; text-decoration: none;
}
.version:hover .version__num { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.18em; }
.version:focus-visible { outline-offset: -3px; }
.version[aria-current="true"] { background: var(--ink); color: var(--paper); }
.version[aria-current="true"]:focus-visible { outline-color: var(--paper); }
.version[aria-current="true"] .stamp { background: var(--paper); color: var(--ink); }
.version__num { font-weight: 800; }
.version__change { display: block; font-size: 0.9375rem; font-weight: 700; }
@media (max-width: 640px) {
  .version { grid-template-columns: auto minmax(0, 1fr); }
  .version__note { grid-column: 1 / -1; }
}

.code {
  margin: 0; padding: 12px 14px; max-height: 70dvh;
  border: 3px solid var(--ink); overflow: auto;
  font-family: var(--font-code); font-variant-ligatures: none; font-size: 0.875rem; line-height: 1.6; white-space: pre;
}

.usedby { margin: 0; padding: 0; list-style: none; }
.usedby a { display: flex; align-items: center; min-height: 44px; padding: 4px 0; background: var(--dots); font-weight: 700; overflow-wrap: anywhere; }

.writer { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 20px 32px; align-items: start; }
.writer textarea {
  height: max(420px, 64dvh); resize: vertical; white-space: pre; overflow: auto;
  font-family: var(--font-code); font-variant-ligatures: none; font-size: 0.9375rem; line-height: 1.5;
}
.writer__side { display: grid; gap: 16px; min-width: 0; }
.declared { margin: 0; padding: 0; list-style: none; font-size: 0.9375rem; }
.declared li { padding: 4px 0; background: var(--dots); overflow-wrap: anywhere; }
@media (max-width: 1100px) { .writer { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .writer textarea { font-size: 1rem; } }

@media (max-width: 980px) {
  .lib { grid-template-columns: minmax(0, 1fr); }
  /* Below this one thing is on screen at a time: the list, or the block you opened. */
  .lib--open .lib__list { display: none; }
  .lib--open .back { display: inline-flex; justify-self: start; }
  .lib:not(.lib--open) .detail { display: none; }
}

/* The settings screen's layout. Its components — the page header, the stamps, the table, the meter,
   the alarm and the dialog — come from ui.ts and keep their own rules. */

.settings { display: grid; min-width: 0; }
.settings__section { display: grid; gap: var(--s3); padding: var(--s3) 0; }
.settings__section + .settings__section { border-top: var(--rule); }
.settings__section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2) var(--s4);
}
.settings__section-body { display: grid; gap: var(--s3); min-width: 0; }

.settings__identity { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.settings__name { font-weight: 700; overflow-wrap: anywhere; }

.settings__facts { display: grid; gap: var(--s2); margin: 0; min-width: 0; }
.settings__fact {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: baseline;
  gap: var(--s4);
  min-width: 0;
}
.settings__fact dt { font-weight: 700; }
.settings__fact dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.settings__licence { font-size: var(--fs-ui); }

.settings__disk { display: grid; gap: var(--s2); min-width: 0; }
.settings__disk-line { font-size: var(--fs-ui); overflow-wrap: anywhere; }
.settings__path { font-size: var(--fs-ui); overflow-wrap: anywhere; }

.settings__tokens { min-width: 0; }
.settings__dialog-form { display: grid; gap: var(--s4); }
.settings__dialog-error:empty { display: none; }
.settings__secret { font-family: var(--font-code); }

@media (max-width: 640px) {
  .settings__fact { grid-template-columns: minmax(0, 1fr); gap: var(--s1); }
}
