/* 00-tokens.css */
@layer reset, tokens, base, components, utilities;

/* Fonts: Atkinson Hyperlegible Next for the interface, Atkinson Hyperlegible
   Mono for titles, code, shas, refs and keys. Both are embedded (static/fonts,
   SIL OFL 1.1), latin subset, variable weight. The asset loader turns the
   relative font and icon references into hashed URLs. */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url(/-/static/fonts/atkinson-next.18b2a1a39a2f.woff2) format("woff2");
  font-weight: 200 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url(/-/static/fonts/atkinson-next-italic.4a5037bfaf66.woff2) format("woff2");
  font-weight: 200 800; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible Mono";
  src: url(/-/static/fonts/atkinson-mono.2706b1ee4f45.woff2) format("woff2");
  font-weight: 200 800; font-style: normal; font-display: swap;
}

/* Palette: grays, in four surface levels, so that blocks read apart without
   hue. Dark: each level is lighter than the one below it; light: each is
   whiter. Hue is kept for code, diffs and verdicts, and one accent, the teal
   of Despair, marks where you are and what is alive: the current tab, the row
   cursor, links in prose, open folders. */
@layer tokens {
  :root {
    /* the system's scheme, unless the theme switch forces one
       (html[data-theme], set by store.js) */
    color-scheme: light dark;
    &[data-theme="light"] { color-scheme: light; }
    &[data-theme="dark"] { color-scheme: dark; }

    /* surfaces, bottom to top */
    --bg-canvas: light-dark(#f3f3f3, #050505); /* the page */
    --bg-inset:  light-dark(#f8f8f8, #020202); /* code, fields: sunk into a surface */
    --bg-surface:light-dark(#ffffff, #0c0c0c); /* cards, header, rail blocks */
    --bg-raised: light-dark(#ececec, #151515); /* hover, buttons, panel rows */
    --bg-strong: light-dark(#dedede, #212121); /* selected row, pressed button */
    --bg-overlay:light-dark(#ffffff, #0f0f0f); /* dialogs */
    --backdrop:  light-dark(rgb(0 0 0 / .25), rgb(0 0 0 / .7));

    --border:        light-dark(#dddddd, #1c1c1c);
    --border-strong: light-dark(#c2c2c2, #303030);

    --ink:      light-dark(#1b1b1b, #d6d6d6);
    --ink-hi:   light-dark(#000000, #fafafa);
    --ink-dim:  light-dark(#4d4d4d, #a3a3a3);
    --ink-mute: light-dark(#616161, #8c8c8c);
    --focus:    light-dark(#000000, #ffffff);
    --on-ink:   light-dark(#ffffff, #050505); /* text on a filled ink button */

    /* Colour, sparingly, from the owner's Despair theme. Light values are the
       same hues darkened to AA. */
    --teal:    light-dark(#2f6b6b, #7db5b5);
    --accent:  var(--teal); /* the one accent of the interface */
    --teal-2:  light-dark(#355f5f, #5a8585);
    --red:     light-dark(#a8404b, #d96c75);
    --rose:    light-dark(#6b6570, #a7a2a9);

    --syn-plain:   var(--ink);
    --syn-keyword: var(--teal);
    --syn-string:  var(--rose);
    --syn-comment: light-dark(#5c5f63, #6e7277);
    --syn-number:  var(--teal-2);
    --syn-func:    var(--ink-hi);
    --syn-type:    var(--teal-2);
    --syn-punct:   var(--ink-dim);

    --add: light-dark(#dcebeb, #0c1616);
    --del: light-dark(#f2dfe1, #1d0e10);

    --font: "Atkinson Hyperlegible Next", system-ui, sans-serif;
    --mono: "Atkinson Hyperlegible Mono", ui-monospace, "Cascadia Mono", "DejaVu Sans Mono", Menlo, Consolas, monospace;
    --fs: 15px;
    --fs-code: 13px;
    --fs-s: 13px;
    --fs-xs: 12px;
    --fs-2xs: 11px;
    --lh: 24px;
    --lh-code: 20px;

    /* spacing scale */
    --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;
    --r: 8px;   /* cards, dialogs */
    --r-s: 6px; /* buttons, fields */

    --pad: var(--s5);
    --stick: 0px;     /* top offset of sticky headers inside the content */
    --measure: 80ch;  /* reading width of prose */
    --rail: 340px;
    --page: 1320px;
    --shadow: 0 1px 2px rgb(0 0 0 / .06), 0 8px 32px rgb(0 0 0 / .18);

    /* names used by the code, diff and merge request sheets */
    --paper: var(--bg-canvas);
    --paper-alt: var(--bg-raised);
    --row: var(--bg-raised);
    --sel: var(--bg-strong);
    --rule: var(--border);
  }
}
/* 10-base.css */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; }
  body, h1, h2, h3, h4, p, ul, ol, dl, dd, figure, pre { margin: 0; }
  ul, ol { padding: 0; list-style: none; }
  table { border-collapse: collapse; border-spacing: 0; }
  th, td { padding: 0; text-align: left; font-weight: inherit; }
  button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
  button { background: none; border: 0; padding: 0; cursor: pointer; text-align: inherit; }
  input { background: transparent; border: 0; }
  summary { cursor: pointer; }
  dialog { color: inherit; border: 0; padding: 0; max-width: none; max-height: none; }
  img { max-width: 100%; }
}

@layer base {
  /* a cross-document fade between pages, where the browser has it */
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 120ms; }
  /* the snapshots fade over this layer: transparent, it shows a white canvas
     for a frame when the new page is a little late */
  ::view-transition { background: var(--bg-canvas); }
  @media (prefers-reduced-motion: reduce) {
    @view-transition { navigation: none; }
  }

  html { background: var(--bg-canvas); scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
  body {
    min-height: 100dvh;
    display: flex; flex-direction: column;
    font: var(--fs) / var(--lh) var(--font);
    color: var(--ink);
    background: var(--bg-canvas);
    tab-size: 4;
    -webkit-font-smoothing: antialiased;
  }
  h1, h2, h3, h4 { font-family: var(--mono); font-weight: 700; color: var(--ink-hi); letter-spacing: -.01em; }
  h1 { font-size: 22px; line-height: 30px; }
  h2 { font-size: 17px; line-height: 26px; }
  h3, h4 { font-size: var(--fs); }
  b, strong { font-weight: 700; }
  small { font-size: var(--fs-s); }
  code, pre, kbd, samp { font-family: var(--mono); }
  a { color: inherit; text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }
  a:hover { text-decoration-color: var(--accent); color: var(--ink-hi); }
  hr { border: 0; border-top: 1px solid var(--border); margin: var(--s5) 0; }
  ::selection { background: var(--ink-hi); color: var(--on-ink); }

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

  [hidden] { display: none !important; }

  kbd {
    display: inline-block; min-width: 20px; padding: 0 5px;
    font: 600 var(--fs-xs) / 18px var(--mono); text-align: center; color: var(--ink-dim);
    background: var(--bg-canvas); border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: 4px;
  }

  .skip {
    position: absolute; left: var(--s2); top: var(--s2); z-index: 30; padding: var(--s1) var(--s3);
    background: var(--ink-hi); color: var(--on-ink); border-radius: var(--r-s);
    transform: translateY(-200%);
  }
  .skip:focus { transform: none; }

  main { min-width: 0; }
  main:focus-visible { outline: none; }

  @media (prefers-reduced-motion: no-preference) {
    a, button, tr, li, summary, .btn { transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease; }
  }
}

@layer utilities {
  /* what does nothing without scripts waits for ermite.js, which sets html.js */
  html:not(.js) [data-js], html:not(.js) .filter { display: none; }
  .dim { color: var(--ink-dim); }
  .mute { color: var(--ink-mute); }
  .nowrap { white-space: nowrap; }
  .num { text-align: right; font-variant-numeric: tabular-nums; }
  .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .rule { border-top: 1px solid var(--border); }
}
/* 20-shell.css */
@layer components {
  /* buttons: one shape for links and buttons that act */
  .btn {
    display: inline-flex; align-items: center; gap: var(--s2); white-space: nowrap;
    height: 32px; padding: 0 var(--s3);
    font: 600 var(--fs-s) / 1 var(--font); color: var(--ink); text-decoration: none;
    background: var(--bg-raised); border: 1px solid var(--border-strong); border-radius: var(--r-s);
    cursor: pointer;
    &:hover { background: var(--bg-strong); color: var(--ink-hi); text-decoration: none; }
    & kbd { margin-right: -4px; }
    &.primary { background: var(--ink-hi); color: var(--on-ink); border-color: var(--ink-hi); }
    &.primary:hover { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
    &.danger:hover { color: var(--red); border-color: var(--red); }
    &.icon { width: 32px; justify-content: center; padding: 0; }
    &[aria-disabled="true"] { opacity: .45; pointer-events: none; }
    &[aria-current="true"], &[aria-pressed="true"] { background: var(--bg-strong); color: var(--ink-hi); border-color: var(--ink-mute); }
  }
  /* icons: SVG files used as masks, so they take the colour of the text */
  .ico { display: inline-block; width: 16px; height: 16px; flex: none; background: currentColor; mask: var(--i) center / contain no-repeat; }
  .i-branch { --i: url(/-/static/icons/branch.eae224ff4088.svg); }
  .i-search { --i: url(/-/static/icons/search.bb4a44c71891.svg); }
  .i-file { --i: url(/-/static/icons/file.8f5e0219262a.svg); }
  .i-chevron { --i: url(/-/static/icons/chevron.8eb2eb585d7a.svg); }
  .i-tag { --i: url(/-/static/icons/tag.a56485bf04ef.svg); }
  .i-user { --i: url(/-/static/icons/user.59c742dea2a1.svg); }
  .i-key { --i: url(/-/static/icons/key.046a2d2422a2.svg); }
  .i-log-in { --i: url(/-/static/icons/log-in.94f6c50f2dad.svg); }
  .i-log-out { --i: url(/-/static/icons/log-out.bf6af5ac1a7a.svg); }
  .i-cards { --i: url(/-/static/icons/cards.5c878f7ba52a.svg); }
  .i-split { --i: url(/-/static/icons/split.00f3426f5d99.svg); }
  .i-compact { --i: url(/-/static/icons/compact.ce9cbf94d431.svg); }
  .i-refresh-cw { --i: url(/-/static/icons/refresh-cw.a70af81ed5b7.svg); }
  .i-mailbox { --i: url(/-/static/icons/mailbox.391b3b7bef7f.svg); }
  .i-sun-moon { --i: url(/-/static/icons/sun-moon.30131c8a127b.svg); }
  .i-sun { --i: url(/-/static/icons/sun.111ee6e722dc.svg); }
  .i-moon { --i: url(/-/static/icons/moon.6ccafab8a7f1.svg); }

  .pill {
    display: inline-flex; align-items: center; height: 18px; padding: 0 var(--s2); margin-left: var(--s1);
    font: 600 var(--fs-2xs) / 1 var(--mono); color: var(--ink-dim); vertical-align: 1px;
    background: var(--bg-raised); border: 1px solid var(--border-strong); border-radius: 999px; white-space: nowrap;
    /* a link pill: no underline; the border lightens on hover and focus */
    &:is(a) { text-decoration: none; cursor: pointer; transition: border-color .12s; }
    &:is(a):hover, &:is(a):focus-visible { text-decoration: none; border-color: var(--ink-dim); }
    &.tag::before { content: ""; width: 6px; height: 6px; margin-right: 6px; border: 1.5px solid currentColor; border-radius: 1px; transform: rotate(45deg); }
    &.new { color: var(--teal); border-color: currentColor; }
    /* the signature of a commit: the protocol, then the verdict, always as text
       (colour never carries it alone). Verified takes the accent, a signature
       that cannot be vouched for keeps the neutral pill with the ink of a
       warning, a bad one is red, "unsigned" (commit page) is dim. */
    &.sig { gap: 5px; }
    &.sig .sig-proto { font-weight: 700; letter-spacing: .02em; }
    &.sig-ok { color: var(--teal); border-color: currentColor; }
    &.sig-warn { color: var(--ink-hi); border-style: dashed; }
    &.sig-bad { color: var(--red); border-color: currentColor; }
    &.sig-none { color: var(--ink-mute); border-style: dotted; font-weight: 400; }
  }
  /* Why a signature is or is not verified, as text: a title alone is not
     reachable by keyboard, touch or every screen reader. */
  .sig-why { display: block; margin-top: 2px; }
  .count {
    display: inline-block; min-width: 22px; padding: 0 7px; margin-left: var(--s1);
    font: 600 var(--fs-xs) / 20px var(--font); text-align: center; color: var(--ink-dim);
    background: var(--bg-raised); border-radius: 999px; vertical-align: 1px;
  }

  /* header: identity, path and actions on top, the repository tabs below.
     --hdr-h is its height, the offset of the sticky bars of the diffs. */
  body { --hdr-h: 57px; }
  body:has(.hdr .tabs) { --hdr-h: 101px; }
  /* A row the cursor scrolls to (j / k, scrollIntoView) stops below the
     sticky header, not under it. */
  [data-rows] > * { scroll-margin-top: calc(var(--hdr-h) + var(--s3)); scroll-margin-bottom: var(--s3); }
  .hdr {
    position: sticky; top: 0; z-index: 20;
    background: var(--bg-surface); border-bottom: 1px solid var(--border);
  }
  .hdr-top {
    display: flex; align-items: center; gap: var(--s4);
    max-width: var(--page); margin: 0 auto; height: 56px; padding: 0 var(--pad);
  }
  .brand {
    display: flex; align-items: center; flex: none; text-decoration: none;
    &:hover { text-decoration: none; }
  }
  /* the hermit by his fire: a grey picture in its own rounded square */
  .brand-mark { width: 32px; height: 32px; flex: none; background: url(/-/static/icons/brand.afac4ac794c3.svg) center / contain no-repeat; }
  /* the inbox, right of the logo on the home page: its number in a darker badge */
  .inbox-btn {
    flex: none;
    & .count { margin-left: 0; color: var(--ink-hi); background: var(--bg-canvas); box-shadow: inset 0 0 0 1px var(--border); }
  }
  .crumbs {
    min-width: 0; flex: 1 1 auto; overflow: hidden;
    & ol { display: flex; align-items: center; min-width: 0; font-family: var(--mono); font-size: var(--fs); }
    & li { display: flex; align-items: center; min-width: 0; white-space: nowrap; }
    & li:last-child { overflow: hidden; }
    & li::before { content: "/"; padding: 0 var(--s2); color: var(--border-strong); }
    & a, & span { overflow: hidden; text-overflow: ellipsis; color: var(--ink-dim); text-decoration: none; }
    & a:hover { color: var(--ink-hi); text-decoration: underline; }
    & [aria-current] { color: var(--ink-hi); font-weight: 700; }
  }
  .hdr-acts { display: flex; align-items: center; gap: var(--s2); margin-left: auto; flex: none; }
  .ref {
    font-family: var(--mono); max-width: 28ch;
    & .ref-name { overflow: hidden; text-overflow: ellipsis; }
    & .sha { font-weight: 400; color: var(--ink-mute); }
  }
  .search {
    min-width: 220px; justify-content: flex-start; color: var(--ink-mute); font-weight: 400;
    background: var(--bg-inset);
    & .search-label { flex: 1; }
  }
  .owner {
    display: flex; align-items: center; gap: var(--s2);
    & .owner-badge {
      display: inline-flex; align-items: center; gap: 6px; max-width: 20ch; padding: 0 var(--s1);
      font: 600 var(--fs-s) / 1 var(--mono); color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
  }

  .tabs {
    max-width: var(--page); margin: 0 auto; padding: 0 var(--pad);
    overflow-x: auto; scrollbar-width: none;
    & ul { display: flex; gap: var(--s1); }
    & a {
      position: relative; display: flex; align-items: center; gap: var(--s2); height: 44px; padding: 0 var(--s3);
      color: var(--ink-dim); text-decoration: none; white-space: nowrap; font-weight: 600;
    }
    & a::after { content: ""; position: absolute; left: var(--s2); right: var(--s2); bottom: -1px; height: 2px; border-radius: 2px; }
    & a:hover { color: var(--ink-hi); }
    & a:hover::after { background: var(--border-strong); }
    & a[aria-current] { color: var(--ink-hi); }
    & a[aria-current]::after { background: var(--accent); }
    & kbd { opacity: .55; }
    & a:hover kbd, & a:focus-visible kbd, & a[aria-current] kbd { opacity: 1; }
  }

  /* work area: content and rail, centred, the page scrolls */
  .work {
    flex: 1; width: 100%; max-width: var(--page); margin: 0 auto;
    padding: var(--s5) var(--pad) var(--s7);
    display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s5); align-items: start;
    /* .work grows to fill the page (flex: 1): without this, the rows share the
       spare height and a short content pushes the rail down */
    align-content: start;
  }
  .work.has-rail { grid-template-columns: minmax(0, 1fr) var(--rail); }
  /* the wide mode (w, ermiteWide): every page takes the whole width of the
     screen; the rail goes to the right edge, the content takes the rest */
  html.wide :is(.work, .hdr-top, .tabs, .foot) { max-width: none; }
  .rail { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; }
  .work-lede { grid-column: 1 / -1; margin-bottom: calc(-1 * var(--s2)); }
  main > * + * { margin-top: var(--s4); }

  /* blocks: a surface with a header; rail sections are blocks too */
  .card, .rail section {
    background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r);
    min-width: 0;
  }
  .card-h, .rail h2 {
    display: flex; align-items: center; gap: var(--s2);
    padding: var(--s3) var(--s4); border-bottom: 1px solid var(--border);
    font-size: var(--fs); line-height: 20px;
    & a { margin-left: auto; font: 600 var(--fs-s) / 1 var(--font); color: var(--ink-dim); text-decoration: none; }
    & a:hover { color: var(--ink-hi); text-decoration: underline; }
  }
  .rail section > :not(h2) { margin: var(--s3) var(--s4); }
  .rail section > .list { margin: var(--s2) 0; }
  .rail section > p + p { margin-top: calc(-1 * var(--s2)); }

  /* newest tag, a row of About in the summary rail: one line of text like
     the rows above it ("v0.9.0 · 36h ago · 9 tags") */
  .kv dd.latest-tag {
    & a { color: inherit; text-decoration: none; }
    & .tag-name { font-weight: 700; color: var(--ink-hi); }
    & a:hover { color: var(--ink-hi); text-decoration: underline; }
  }

  .kv {
    display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: var(--s4); row-gap: var(--s1);
    font-size: var(--fs-s);
    & dt { color: var(--ink-mute); }
    & dd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
  }
  .outline {
    font-size: var(--fs-s);
    & a { display: block; padding: 2px var(--s2); margin: 0 calc(-1 * var(--s2)); border-radius: 4px; color: var(--ink-dim); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    & a:hover { background: var(--bg-raised); color: var(--ink-hi); }
    & .l1 { font-weight: 700; color: var(--ink); }
    & .l3 { padding-left: var(--s5); }
    & .l4, & .l5, & .l6 { padding-left: var(--s6); }
  }

  /* footer: version and source (AGPL §13), then shortcuts and theme */
  .foot {
    display: flex; flex-wrap: wrap; gap: var(--s4); align-items: center;
    width: 100%; max-width: var(--page); margin: 0 auto; padding: var(--s4) var(--pad) var(--s5);
    font-size: var(--fs-s); color: var(--ink-mute);
    &::before { content: ""; flex-basis: 100%; height: 1px; margin-bottom: var(--s2); background: var(--border); }
    & a { color: var(--ink-dim); }
    & .foot-keys { margin-left: auto; color: var(--ink-dim); }
    & .foot-keys:hover { color: var(--ink-hi); }
    & .foot-theme {
      display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
      margin: -6px 0; color: var(--ink-dim); border-radius: var(--r-s);
    }
    & .foot-theme:hover { color: var(--ink-hi); background: var(--bg-raised); }
  }

  /* hint: bottom right, only while it has something to say */
  .hint {
    position: fixed; right: var(--s4); bottom: var(--s4); z-index: 25;
    display: flex; gap: var(--s3); align-items: center;
    padding: var(--s2) var(--s3); font: 600 var(--fs-s) / 18px var(--mono); color: var(--ink-hi);
    background: var(--bg-overlay); border: 1px solid var(--border-strong); border-radius: var(--r); box-shadow: var(--shadow);
    pointer-events: none;
    & > :empty { display: none; }
    & > [role="status"] { display: contents; }
    & .hint-live { color: var(--red); }
  }
  /* empty, the badge is out of sight but stays a status region (display: none
     would drop it from the accessibility tree and its next message would not be
     announced) */
  .hint:not(:has(.hint-nav:not(:empty), .hint-sel:not(:empty), .hint-flash:not(:empty), .hint-live:not(:empty))) {
    width: 1px; height: 1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); box-shadow: none;
  }

  @media (max-width: 1080px) {
    /* the rail goes under the content, in two columns while there is room */
    .work.has-rail { grid-template-columns: minmax(0, 1fr); }
    .rail { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); align-items: start; }
    .search { min-width: 0; }
    .search .search-label, .search kbd { display: none; }
    .search { width: 32px; padding: 0; justify-content: center; }
  }
  @media (max-width: 720px) {
    :root { --pad: var(--s4); }
    .hdr-top { gap: var(--s3); height: 52px; }
    .crumbs li:not(:last-child) { display: none; }
    .ref .sha, .owner .owner-badge { display: none; }
    .ref { max-width: 16ch; }
    .work { padding-top: var(--s4); }
    .rail { grid-template-columns: minmax(0, 1fr); }
    .tabs kbd { display: none; }
    .list .c-who, .list .c-desc, .list .c-sub, .list .c-ref, .list .c-size, .list .c-lang { display: none; }
  }
}
/* 25-panel.css */
@layer components {
  /* dialogs: the "go to" palette, the ref switcher and the keys, centred over a backdrop */
  .modal {
    position: fixed; inset: 0; margin: 12vh auto auto; z-index: 40;
    width: min(640px, calc(100vw - 2 * var(--s4))); max-height: min(70dvh, 560px);
    display: none; flex-direction: column;
    background: var(--bg-overlay); color: var(--ink);
    border: 1px solid var(--border-strong); border-radius: var(--r); box-shadow: var(--shadow);
    overflow: hidden; overscroll-behavior: contain;
    &[open] { display: flex; }
    &::backdrop { background: var(--backdrop); }
    &#panel-help { width: min(820px, calc(100vw - 2 * var(--s4))); }
  }
  @media (prefers-reduced-motion: no-preference) {
    .modal[open] { animation: modal-in 120ms ease-out; }
    @keyframes modal-in { from { opacity: 0; transform: translateY(-6px) scale(.99); } }
  }
  .panel-head {
    display: flex; align-items: center; gap: var(--s3); flex: none;
    padding: var(--s3) var(--s4); border-bottom: 1px solid var(--border);
    & h2 { font-size: var(--fs); flex: 1; }
    & input { flex: 1; min-width: 0; height: 32px; font-size: 16px; }
    & input::placeholder { color: var(--ink-mute); opacity: 1; }
  }
  .panel-x { color: var(--ink-mute); font-size: var(--fs-s); display: flex; gap: var(--s2); align-items: center; }
  .panel-x:hover { color: var(--ink-hi); }
  .panel-foot {
    display: flex; gap: var(--s4); flex: none; padding: var(--s2) var(--s4);
    border-top: 1px solid var(--border); background: var(--bg-surface);
    font-size: var(--fs-xs); color: var(--ink-mute);
    & span { display: flex; gap: var(--s1); align-items: center; }
  }
  .modal > ul, .modal > .panel-cols, .modal > .keys { overflow-y: auto; padding: var(--s2); }

  .panel-cols {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--s2);
    & h2 { font: 600 var(--fs-xs) / 1 var(--font); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-mute); padding: var(--s3) var(--s3) var(--s2); }
    & li a {
      display: flex; align-items: center; gap: var(--s2); padding: 6px var(--s3); border-radius: var(--r-s);
      font-family: var(--mono); font-size: var(--fs-s); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    & li a:hover, & li a:focus-visible { background: var(--bg-raised); color: var(--ink-hi); }
    & li a[aria-current] { font-weight: 700; color: var(--ink-hi); box-shadow: inset 2px 0 0 var(--accent); }
    & .mark { display: inline-block; width: 1ch; color: var(--teal); }
  }

  .cmd-list {
    & li a {
      display: flex; align-items: center; gap: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--r-s);
      text-decoration: none; color: var(--ink);
    }
    & li a:hover { background: var(--bg-raised); }
    & li[data-cursor] a { background: var(--bg-strong); color: var(--ink-hi); box-shadow: inset 2px 0 0 var(--accent); }
    & .lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: var(--fs-s); }
    & .k { flex: none; font-size: var(--fs-xs); color: var(--ink-mute); }
    & .dir { color: var(--ink-dim); }
    & strong { color: var(--ink-hi); font-weight: 700; }
    & mark { background: none; color: var(--teal); font-weight: 700; text-decoration: underline; }
  }

  .keys {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); column-gap: var(--s5); row-gap: var(--s1);
    padding: var(--s3) var(--s4) var(--s4) !important;
    & > div { display: grid; grid-template-columns: 130px 1fr; gap: var(--s3); align-items: baseline; padding: var(--s1) 0; border-bottom: 1px solid var(--border); }
    & dt { display: flex; flex-wrap: wrap; gap: var(--s1); min-width: 0; }
    & dd { color: var(--ink-dim); font-size: var(--fs-s); min-width: 0; overflow-wrap: anywhere; }
    @media (max-width: 480px) { & > div { grid-template-columns: minmax(0, 1fr); gap: var(--s1); } }
  }
  /* the preference "single-key shortcuts" of the help dialog */
  .keys-pref {
    flex: none; padding: var(--s3) var(--s4) 0;
    & label { display: flex; align-items: center; gap: var(--s2); cursor: pointer; }
    & input[type=checkbox] { width: 16px; height: 16px; flex: none; accent-color: var(--teal); }
    & p { font-size: var(--fs-s); margin-top: var(--s1); }
  }
}
/* 30-list.css */
@layer components {
  /* tables in a card, with a row cursor (j/k) */
  .list {
    width: 100%; table-layout: fixed;
    background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r);
    border-collapse: separate; overflow: hidden;
    & th {
      height: 40px; padding: 0 var(--s3); white-space: nowrap;
      font: 600 var(--fs-xs) / 1 var(--font); text-transform: uppercase; letter-spacing: .05em; color: var(--ink-mute);
      background: var(--bg-raised); border-bottom: 1px solid var(--border);
    }
    & th a { text-decoration: none; }
    & th a:hover { color: var(--ink-hi); }
    & th[aria-sort="ascending"], & th[aria-sort="descending"] { color: var(--ink-hi); }
    & td { height: 40px; padding: 0 var(--s3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-top: 1px solid var(--border); }
    & tbody tr:first-child td { border-top: 0; }
    & tbody tr:hover { background: var(--bg-raised); }
    /* the cursor: the row raised, framed by one even line. The frame is drawn
       on the cells (a row takes no radius), so it can follow the card's
       curve when the row sits at a corner. */
    & tbody tr[data-cursor] > td {
      background: var(--bg-raised); border-top-color: transparent;
      box-shadow: inset 0 1px var(--accent), inset 0 -1px var(--accent);
    }
    & tbody tr[data-cursor] > td:first-child { box-shadow: inset 1px 0 var(--accent), inset 0 1px var(--accent), inset 0 -1px var(--accent); }
    & tbody tr[data-cursor] > td:last-child { box-shadow: inset -1px 0 var(--accent), inset 0 1px var(--accent), inset 0 -1px var(--accent); }
    & > tbody:first-child > tr[data-cursor]:first-child > td:first-child { border-top-left-radius: calc(var(--r) - 1px); }
    & > tbody:first-child > tr[data-cursor]:first-child > td:last-child { border-top-right-radius: calc(var(--r) - 1px); }
    & > tbody:last-child > tr[data-cursor]:last-child > td:first-child { border-bottom-left-radius: calc(var(--r) - 1px); }
    & > tbody:last-child > tr[data-cursor]:last-child > td:last-child { border-bottom-right-radius: calc(var(--r) - 1px); }
    & tbody tr[hidden] { display: none; }
    & td > a { text-decoration: none; }
    & td > a:first-child { color: var(--ink-hi); }
    & tr:hover td > a:first-child, & tr[data-cursor] td > a:first-child { text-decoration: underline; }
    & .c-sha, & .c-ref, & .c-kind, & .c-size, & .c-n { font-family: var(--mono); font-size: var(--fs-s); }
    & .c-sha a { color: var(--ink-dim); }
    & .c-when, & .c-who { font-size: var(--fs-s); }
    & .c-sub { color: var(--ink-dim); }
  }

  /* home: the repositories as rows in a vertical list; the page is a stack of
     sections, so others can sit beside or below */
  .home {
    display: flex; flex-direction: column; gap: var(--s5);
    & .home-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3) var(--s4); margin-bottom: var(--s4); }
    & .home-bar .filter { flex: 1 1 260px; }
    & .sort { display: flex; align-items: center; gap: var(--s1); font-size: var(--fs-s); }
    & .sort > .mute { margin-right: var(--s1); }
    & .sort a {
      display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 var(--s2);
      color: var(--ink-dim); text-decoration: none; border: 1px solid transparent; border-radius: var(--r-s);
    }
    & .sort a:hover { color: var(--ink-hi); background: var(--bg-raised); }
    & .sort a[aria-current="true"] { color: var(--ink-hi); background: var(--bg-raised); border-color: var(--border-strong); }
  }
  /* a row: name, description and facts on the left; the state of the latest
     run at the top right, the newest commits under it. Stacked on a phone. */
  .repos {
    display: flex; flex-direction: column; gap: var(--s3);
    margin: 0; padding: 0; list-style: none;
    & .repo {
      display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-areas: "main head" "main recent";
      grid-template-rows: auto 1fr; column-gap: var(--s6); row-gap: var(--s3); min-width: 0;
      padding: var(--s4); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r);
    }
    & .repo:hover { background: var(--bg-raised); border-color: var(--border-strong); }
    & .repo[data-cursor] { background: var(--bg-raised); border-color: var(--accent); }
    & .repo[hidden] { display: none; }
    & .repo-main { grid-area: main; display: flex; flex-direction: column; gap: var(--s2); min-width: 0; }
    & .repo-name { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s1) var(--s2); font-family: var(--mono); font-size: 17px; line-height: 26px; overflow-wrap: anywhere; }
    & .repo-name a { color: var(--ink-hi); text-decoration: none; }
    & .repo:hover .repo-name a:not(.pill), & .repo[data-cursor] .repo-name a:not(.pill) { text-decoration: underline; }
    & .repo-name .pill { margin-left: 0; }
    & .repo-name a.pill { display: block; line-height: 18px; min-width: 0; max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: normal; }
    & .repo-name .repo-release { color: var(--accent); }
    & .repo-name .repo-license { color: var(--ink-dim); }
    & .repo-activity { display: inline-flex; align-items: center; flex: none; color: var(--accent); }
    /* Every card has the same height: two lines of description, one of topics
       (reserved when there are none), five of commits. */
    & .repo-desc {
      color: var(--ink-dim); min-height: calc(2 * var(--lh));
      display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
    }
    & .repo-desc.mute { color: var(--ink-mute); font-style: italic; }
    /* topics: small quiet chips, as on GitHub, on one line. The chips that do
       not fit wrap out of sight; ermite.fit (ermite.js) puts a … chip after
       the last one shown, the hidden topics in its title. */
    & .repo-topics {
      display: flex; flex-wrap: wrap; gap: 6px; height: 22px; overflow: hidden;
      margin: 0; padding: 0; list-style: none;
    }
    & .repo-topics li {
      flex: none; padding: 1px 9px; border: 1px solid var(--border-strong); border-radius: 999px;
      font-family: var(--mono); font-size: 12px; line-height: 18px; color: var(--teal); background: var(--bg-raised);
    }
    & .repo-topics li[hidden] { display: none; }
    & .repo-topics li.more { padding: 0; }
    & .repo-topics li.more button {
      padding: 1px 7px; border: 0; border-radius: 999px; background: none; cursor: pointer;
      font: inherit; line-height: 18px; color: var(--ink-mute);
    }
    & .repo-topics li.more button:hover { color: var(--accent); }
    & .repo-topics[data-open] { height: auto; }
    /* the pulse: the commits per day over 90 days, smoothed, under the text */
    & .repo-pulse { margin: auto 0 0; padding-top: var(--s2); }
    /* as tall as a drawn pulse: the padding comes on top of the ratio */
    & div.repo-pulse { aspect-ratio: 600 / 64; box-sizing: content-box; }
    & .repo-pulse svg { display: block; width: 100%; height: auto; overflow: visible; }
    & .pulse-grid { fill: none; stroke: var(--border); stroke-width: 1; stroke-dasharray: 2 4; }
    & .pulse-stop-top { stop-color: var(--teal); stop-opacity: .32; }
    & .pulse-stop-bottom { stop-color: var(--teal); stop-opacity: 0; }
    & .pulse-line { fill: none; stroke: var(--teal); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
    & .pulse-dot { fill: var(--teal); stroke: var(--bg-surface); stroke-width: 1.5; }
    & .repo:hover .pulse-dot, & .repo[data-cursor] .pulse-dot { stroke: var(--bg-raised); }
    & .repo-pulse:not([data-live]) .pulse-line { stroke: var(--ink-mute); }
    & .repo-pulse:not([data-live]) .pulse-dot { fill: var(--ink-mute); }
    & .repo-pulse:not([data-live]) .pulse-stop-top { stop-color: var(--ink-mute); stop-opacity: .18; }
    /* the right column: figures, then the CI state, over the commits */
    & .repo-head { grid-area: head; display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3) var(--s5); min-width: 0; }
    /* the figures: a small label over a mono value, side by side */
    & .repo-stats { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5); margin: 0; min-width: 0; }
    & .repo-stats div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
    & .repo-stats dt { font-size: 11px; line-height: 14px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-mute); white-space: nowrap; }
    & .repo-stats dd { margin: 0; font-family: var(--mono); font-size: 15px; line-height: 20px; color: var(--ink-hi); font-variant-numeric: tabular-nums; white-space: nowrap; }
    & .repo-stats .rs-tag dd { max-width: 18ch; overflow: hidden; text-overflow: ellipsis; }
    & .repo-stats dd.mute { color: var(--ink-mute); }
    & .repo-stats dd a { color: inherit; text-decoration: none; }
    & .repo-stats dd a:hover { text-decoration: underline; }
    & .repo-ci {
      flex: none; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
      font-size: var(--fs-s); color: var(--ink-dim); text-decoration: none; white-space: nowrap;
    }
    & .repo-ci:hover { color: var(--ink-hi); text-decoration: underline; }
    & .repo-ci .ck { margin: 0; }
    & .repo-commits {
      grid-area: recent; min-width: 0; margin: 0; padding: 0; list-style: none; font-size: var(--fs-s);
      min-height: calc(5 * (var(--lh) + 4px)); /* five rows, full or not */
    }
    & p.repo-commits { font-style: italic; }
    & .repo-commits li { display: flex; align-items: baseline; gap: var(--s2); min-width: 0; padding: 2px 0; }
    & .rc-sha { flex: none; font-family: var(--mono); color: var(--ink-dim); text-decoration: none; }
    & .rc-sha:hover { color: var(--ink-hi); text-decoration: underline; }
    & .rc-subject { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-hi); }
    & .repo-commits time { flex: none; white-space: nowrap; }
    /* a full list goes on: its last commit fades */
    & .repo-commits[data-full] li:last-child { opacity: .65; }
    @media (max-width: 720px) {
      & .repo { grid-template-columns: minmax(0, 1fr); grid-template-areas: "main" "head" "recent"; grid-template-rows: none; }
      & .repo-head { flex-wrap: wrap; }
      & .repo-commits { min-height: 0; }
    }
  }
  /* Home layouts. The server renders "cards" (the rules above); a script
     sets .home[data-layout] from the stored choice. The rows carry no markup
     of their own for a layout, so a row swapped in by a live update fits. */
  .home .layout-switch { display: flex; align-items: center; gap: 2px; }
  .home .layout-switch .btn {
    width: 28px; height: 28px; color: var(--ink-dim); background: none; border-color: transparent; border-radius: var(--r-s);
    &:hover { color: var(--ink-hi); background: var(--bg-raised); }
    &[aria-pressed="true"] { color: var(--ink-hi); background: var(--bg-raised); border-color: var(--border-strong); }
  }
  .home .home-bar .sort { margin-left: auto; }

  /* split: two denser cards side by side. Name and CI state on top, the
     description, the pulse as a band from edge to edge, the figures in one
     row and the two newest commits. One column on a narrow screen. */
  .home[data-layout="split"] {
    & .repos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); }
    & .repo {
      grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s3); row-gap: 0;
      grid-template-areas: "name ci" "desc desc" "topics topics" "pulse pulse" "stats stats" "recent recent";
      grid-template-rows: auto 1fr auto auto auto auto;
      overflow: hidden;
    }
    & .repo-main, & .repo-head { display: contents; }
    & .repo-name { grid-area: name; align-self: center; font-size: 16px; }
    & .repo-ci { grid-area: ci; align-self: center; }
    & .repo-desc { grid-area: desc; margin-top: var(--s2); }
    & .repo-topics { grid-area: topics; margin-top: var(--s2); }
    & .repo-topics:empty { display: none; }
    & .repo-pulse { grid-area: pulse; margin: var(--s3) calc(-1 * var(--s4)) 0; padding: 0; border-block: 1px solid var(--border); }
    /* one row while it fits; a narrow card wraps the figures instead of
       letting them overlap */
    & .repo-stats { grid-area: stats; flex-wrap: wrap; justify-content: space-between; gap: var(--s2) var(--s3); margin-top: var(--s3); }
    & .repo-stats div { flex: none; }
    & .repo-stats dd { font-size: var(--fs); }
    & .repo-stats .rs-tag dd { max-width: 12ch; }
    & .repo-commits { grid-area: recent; min-height: calc(2 * (var(--lh) + 4px)); margin-top: var(--s2); }
    & .repo-commits li:nth-child(n+3) { display: none; }
    & .repo-commits[data-full] li:last-child { opacity: 1; }
    & .repo-commits[data-full] li:nth-child(2) { opacity: .65; }
  }
  @media (max-width: 900px) {
    .home[data-layout="split"] .repos { grid-template-columns: minmax(0, 1fr); }
  }

  /* compact: a line per repository. Name, description, figures, CI mark and
     a small pulse sit in one grid row; the commits and topics are left out.
     The rows share the columns of the list (subgrid): the name column is as
     wide as the longest name, the figures line up, and the description takes
     what is left. */
  .home[data-layout="compact"] {
    & .repos {
      display: grid; grid-template-columns: fit-content(18rem) minmax(0, 1fr) auto auto 140px;
      gap: var(--s2) var(--s4);
    }
    & .repo {
      grid-column: 1 / -1; grid-template-columns: subgrid;
      grid-template-areas: "name desc stats ci pulse";
      /* normal: the row takes the gaps of the list */
      grid-template-rows: none; column-gap: normal; row-gap: 0; align-items: center;
      padding: var(--s2) var(--s4);
    }
    & .repo-main, & .repo-head { display: contents; }
    & .repo-topics, & .repo-commits { display: none; }
    /* min-width 0: a long name is cut, it does not widen the column past its cap */
    & .repo-name { grid-area: name; min-width: 0; flex-wrap: nowrap; gap: var(--s2); font-size: var(--fs); line-height: 24px; overflow-wrap: normal; }
    & .repo-name a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    & .repo-name .pill { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    & .repo-name a.pill { max-width: 12ch; }
    & .repo-desc {
      grid-area: desc; display: block; min-height: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      font-size: var(--fs-s); color: var(--ink-mute);
    }
    /* figures inline, the value before its label; the label of the date and
       of the tag is left to screen readers */
    & .repo-stats { grid-area: stats; flex-wrap: nowrap; gap: var(--s3); overflow: hidden; }
    & .repo-stats div { flex-direction: row; align-items: baseline; gap: 4px; flex: none; }
    & .repo-stats dt { order: 1; font-size: var(--fs-xs); line-height: 16px; letter-spacing: 0; text-transform: none; }
    & .repo-stats dd { font-size: var(--fs-xs); line-height: 16px; color: var(--ink-dim); }
    & .repo-stats .rs-active dt, & .repo-stats .rs-tag dt {
      position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
    }
    & .repo-stats .rs-tag dd { max-width: 10ch; }
    /* the CI state is its mark; the word is in the tooltip and for screen readers */
    & .repo-ci { grid-area: ci; justify-self: center; }
    /* the pulse: the same curve, small, with a bigger dot to stay seen */
    & .repo-pulse { grid-area: pulse; width: 100%; height: 100%; min-height: 18px; margin: 0; padding: 0; }
    & div.repo-pulse { aspect-ratio: auto; box-sizing: border-box; }
    & .repo-pulse svg { position: relative; top: 50%; transform: translateY(-50%); }
    & .pulse-grid { display: none; }
    & .pulse-dot { r: 9px; stroke: none; }
  }
  @media (max-width: 1100px) {
    .home[data-layout="compact"] .repos { grid-template-columns: fit-content(14rem) minmax(0, 1fr) auto auto 96px; column-gap: var(--s3); }
    .home[data-layout="compact"] .repo-stats .rs-tag { display: none; }
  }
  /* on a phone: name and CI state on a line, the description and the figures
     under it; the pulse is dropped */
  @media (max-width: 720px) {
    .home[data-layout="compact"] .repo {
      grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name ci" "desc desc" "stats stats"; column-gap: var(--s3); row-gap: 2px;
    }
    .home[data-layout="compact"] .repo-pulse { display: none; }
    .home[data-layout="compact"] .repo-stats .rs-tag { display: flex; }
  }
  .list.passkeys {
    & .c-name { width: auto; font-weight: 600; }
    & .c-when { width: 120px; font-size: var(--fs-s); }
    & .c-sync { width: 80px; font-size: var(--fs-s); }
    & .c-act { width: 110px; text-align: right; }
  }
  .passkey-add {
    display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; margin-top: var(--s4);
    & input {
      flex: 1; min-width: 12ch; max-width: 320px; height: 32px; padding: 0 var(--s3);
      background: var(--bg-surface); border: 1px solid var(--border-strong); border-radius: var(--r-s);
    }
    & input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-color: transparent; }
    & input::placeholder { color: var(--ink-mute); opacity: 1; }
  }
  .list.commits, .list.refs {
    & .c-sha { width: 96px; }
    & .c-who { width: 140px; }
    & .c-when { width: 100px; }
  }

  /* filter: a search field above a list */
  .filter {
    position: relative; display: flex; max-width: 420px;
    &::before {
      content: ""; position: absolute; left: 11px; top: 10px; width: 16px; height: 16px; pointer-events: none;
      background: var(--ink-mute); mask: url(/-/static/icons/search.bb4a44c71891.svg) center / contain no-repeat;
    }
    &::after {
      content: "/"; position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
      font: 600 var(--fs-xs) / 18px var(--mono); color: var(--ink-mute); padding: 0 6px;
      border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: 4px; pointer-events: none;
    }
    & input {
      flex: 1; min-width: 0; height: 36px; padding: 0 36px 0 34px;
      background: var(--bg-surface); border: 1px solid var(--border-strong); border-radius: var(--r-s);
    }
    & input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-color: transparent; }
    & input::placeholder { color: var(--ink-mute); opacity: 1; }
    &:focus-within::after { display: none; }
  }

  /* file finder: the results replace the tree while the field has a query */
  #finder {
    & #finder-status { padding: var(--s3) var(--s4) var(--s2); font-size: var(--fs-s); }
    & #finder-list { padding: 0 var(--s2) var(--s2); }
  }

  /* the Files view: the finder on top, the tree in a card under it */
  .tree-find {
    display: flex; align-items: center; gap: var(--s4); margin-bottom: var(--s3);
    & .filter { flex: 1; max-width: none; }
    & .filter::before { top: 14px; left: 14px; }
    & .filter::after { right: 12px; }
    & .filter input { height: 44px; padding-left: 42px; font-size: var(--fs); background: var(--bg-surface); }
  }
  .tree-keys { flex: none; color: var(--ink-mute); font-size: var(--fs-xs); white-space: nowrap; }
  .tree-card {
    background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden;
  }
  .tree-head {
    display: flex; align-items: center; gap: var(--s3); min-height: 40px; padding: 0 var(--s4);
    background: var(--bg-raised); border-bottom: 1px solid var(--border); font-size: var(--fs-s);
    & .tree-path { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 700 var(--fs-s) / 1 var(--mono); color: var(--ink-hi); }
    & .tree-up { flex: none; font: 600 var(--fs-s) / 1 var(--mono); color: var(--ink-dim); text-decoration: none; }
    & .tree-up:hover { color: var(--ink-hi); text-decoration: underline; }
    & .tree-count { flex: none; color: var(--ink-mute); }
  }
  .tree-card > :is(.lede, .note) { margin: var(--s3) var(--s4); }

  /* The tree: one flat list, a row per entry, each as deep as --depth says
     (files.js sets it on the rows it opens in place). A row draws, from the
     left: a vertical guide per level above it, the branch tick to its node,
     the node, its name; then size, last commit and date, which are secondary. */
  ul.tree {
    --indent: 22px; --rowh: 32px; --guide: var(--border-strong);
    & > li {
      display: grid; grid-template-columns: minmax(0, 1fr) 72px minmax(0, 1.2fr) 96px; align-items: center;
      min-height: var(--rowh); padding-right: var(--s4); font-size: var(--fs-s);
    }
    & > li:hover, & > li[data-cursor] { background: var(--bg-raised); }
    & > li[data-cursor] { outline: 1px solid var(--accent); outline-offset: -1px; }
    & > li:focus-visible { outline-offset: -2px; border-radius: 0; }
    & .t-main { display: flex; align-items: stretch; min-width: 0; min-height: var(--rowh); padding-left: var(--s3); }
    & .t-twig {
      flex: none; width: calc(var(--depth, 0) * var(--indent));
      background: repeating-linear-gradient(90deg,
        transparent 0 calc(var(--indent) / 2), var(--guide) calc(var(--indent) / 2) calc(var(--indent) / 2 + 1px),
        transparent calc(var(--indent) / 2 + 1px) var(--indent));
    }
    & .t-node { position: relative; flex: none; width: var(--indent); }
    & .t-node::before, & .t-node::after { content: ""; position: absolute; }
    /* the branch tick, from the guide of the directory to this node */
    & .t-node::before { top: 50%; left: calc(var(--indent) / -2); right: calc(50% + 6px); height: 1px; background: var(--guide); }
    & > li[data-depth="0"] .t-node::before { display: none; }
    /* an open directory continues its guide down, to its first entry */
    & > li[aria-expanded="true"] .t-node {
      background: linear-gradient(var(--guide), var(--guide)) center bottom / 1px calc(50% - 8px) no-repeat;
    }
    /* the node: a ring for a file, a chevron for a directory (it turns down
       once open), a diamond for a link, a square for a submodule */
    & .t-node::after {
      top: 50%; left: 50%; width: 7px; height: 7px; margin: -4px 0 0 -4px;
      background: var(--bg-surface); border: 1px solid var(--ink-mute); border-radius: 50%;
    }
    & > li:hover .t-node::after, & > li[data-cursor] .t-node::after { background: var(--bg-raised); border-color: var(--ink-hi); }
    & > li[data-kind="dir"] .t-node::after {
      width: 16px; height: 16px; margin: -8px 0 0 -8px; border: 0; border-radius: 0; background: var(--ink-dim);
      mask: url(/-/static/icons/chevron.8eb2eb585d7a.svg) center / contain no-repeat; transform: rotate(-90deg);
    }
    & > li[data-kind="dir"][aria-expanded="true"] .t-node::after { transform: none; background: var(--accent); }
    & > li[data-kind="link"] .t-node::after { border-radius: 1px; transform: rotate(45deg); }
    & > li[data-kind="module"] .t-node::after { border-radius: 1px; }
    & > li[aria-busy="true"] .t-node { opacity: .4; }
    & .t-name {
      align-self: center; min-width: 0; padding: 4px var(--s1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      font-family: var(--mono); font-size: var(--fs); color: var(--ink); text-decoration: none; cursor: pointer;
    }
    & > li[data-kind="dir"] .t-name { font-weight: 700; color: var(--ink-hi); }
    & > li[data-kind="link"] .t-name, & > li[data-kind="module"] .t-name { color: var(--ink-dim); cursor: default; }
    & > li:hover .t-name, & > li[data-cursor] .t-name { text-decoration: underline; }
    & .t-size { padding-right: var(--s4); text-align: right; font: var(--fs-xs) / 1 var(--mono); color: var(--ink-mute); font-variant-numeric: tabular-nums; }
    & .t-sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-dim); }
    & .t-sub a { color: inherit; text-decoration: none; }
    & .t-sub a:hover { color: var(--ink-hi); text-decoration: underline; }
    & .t-when { text-align: right; white-space: nowrap; color: var(--ink-mute); font-size: var(--fs-xs); }
    & > li.tree-more { grid-template-columns: minmax(0, 1fr); }
    & > li.tree-more .t-name { font-size: var(--fs-s); font-weight: 400; color: var(--ink-dim); text-decoration: underline; }
    & > li.tree-more .t-node::after { display: none; }
  }
  @media (max-width: 900px) {
    ul.tree > li { grid-template-columns: minmax(0, 1fr) 64px 80px; }
    ul.tree .t-sub { display: none; }
  }
  @media (max-width: 720px) {
    .tree-keys { display: none; }
    ul.tree { --indent: 18px; }
    ul.tree > li { grid-template-columns: minmax(0, 1fr) 72px; }
    ul.tree .t-size { display: none; }
  }

  /* section headings inside a page */
  .rule-h {
    display: flex; align-items: center; gap: var(--s2); margin-top: var(--s5);
    font-size: var(--fs);
    & > :first-child { color: var(--ink-hi); }
  }
  main > .rule-h:first-child { margin-top: 0; }

  /* empty / 404 / error / sign in: one card in the middle */
  .state {
    max-width: 560px; margin: var(--s7) auto 0 !important; padding: var(--s6);
    background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r);
    & .eyebrow { font: 700 var(--fs-s) / 1 var(--mono); color: var(--ink-mute); text-transform: uppercase; letter-spacing: .08em; margin-bottom: var(--s2); }
    & h1 { margin-bottom: var(--s3); }
    & p.dim { color: var(--ink-dim); }
    & .state-act { margin-top: var(--s5); }
    & .state-back { margin-top: var(--s5); display: flex; gap: var(--s4); font-size: var(--fs-s); }
    & .clone { margin-top: var(--s4); }
  }

  /* copyable shell lines */
  .clone {
    display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s2); min-width: 0;
    & .clone-line {
      min-width: 0;
      display: flex; gap: var(--s2); align-items: center; padding: var(--s1) var(--s1) var(--s1) var(--s3);
      background: var(--bg-inset); border: 1px solid var(--border); border-radius: var(--r-s);
      font-size: var(--fs-code);
    }
    & .clone-line > .mute { user-select: none; font-family: var(--mono); }
    & code { flex: 1; min-width: 0; overflow-x: auto; white-space: pre; scrollbar-width: none; }
    & .copy { height: 26px; padding: 0 var(--s2); font-size: var(--fs-xs); }
  }
}
/* 40-summary.css */
@layer components {
  .lede { max-width: var(--measure); color: var(--ink-dim); font-size: 16px; }

  /* key/value facts */
  .facts {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); column-gap: var(--s5);
    & > div { display: grid; grid-template-columns: 120px 1fr; min-width: 0; }
    & dt { color: var(--ink-mute); }
    & dd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  }

  .tagged { color: var(--ink); font-weight: 700; white-space: nowrap; }
  .list.commits .c-subject { overflow: hidden; text-overflow: ellipsis; }

  .readme .prose { padding: var(--s5) var(--s6) var(--s6); }
  /* .card-h.doc-tabs, not .doc-tabs: .card-h pushes its links to the right
     with :is(.card-h, .rail h2) a, which weighs as .rail h2 a */
  .card-h.doc-tabs {
    display: flex; flex-wrap: wrap; gap: var(--s4);
    & a { margin-left: 0; color: var(--ink-dim); }
    & a[aria-current] { color: var(--teal); text-decoration: underline; text-underline-offset: 5px; }
  }

  /* rendered Markdown */
  .prose {
    max-width: var(--measure); line-height: 1.65; overflow-wrap: break-word;
    & h1, & h2, & h3, & h4 { margin: 1.6em 0 0; }
    & h1 { font-size: 26px; line-height: 34px; padding-bottom: var(--s2); border-bottom: 1px solid var(--border); }
    & h2 { font-size: 20px; line-height: 28px; padding-bottom: var(--s1); border-bottom: 1px solid var(--border); }
    & h3 { font-size: 17px; }
    & > :first-child { margin-top: 0; }
    & p, & ul, & ol, & pre, & table, & blockquote { margin-top: var(--s4); }
    & ul { list-style: disc; }
    & ul, & ol { padding-left: var(--s5); }
    & ol { list-style: decimal; }
    & li + li { margin-top: var(--s1); }
    & li::marker { color: var(--ink-mute); }
    & a { color: var(--accent); text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent); }
    & a:hover { color: var(--accent); text-decoration-color: currentColor; }
    & li > ul, & li > ol, & li > p { margin-top: var(--s1); }
    & pre {
      padding: var(--s3) var(--s4); overflow-x: auto;
      background: var(--bg-inset); border: 1px solid var(--border); border-radius: var(--r-s);
      font-size: var(--fs-code); line-height: var(--lh-code);
    }
    & :not(pre) > code {
      padding: 1px 5px; font-size: .88em; overflow-wrap: anywhere;
      background: var(--bg-raised); border: 1px solid var(--border); border-radius: 4px;
    }
    & blockquote { padding-left: var(--s4); border-left: 3px solid color-mix(in srgb, var(--accent) 45%, var(--border-strong)); color: var(--ink-dim); }
    & table { display: block; overflow-x: auto; border: 1px solid var(--border); border-radius: var(--r-s); font-size: var(--fs-s); line-height: 20px; }
    & th, & td { padding: 6px var(--s3); white-space: nowrap; vertical-align: top; border-top: 1px solid var(--border); }
    & th { background: var(--bg-raised); border-top: 0; font-weight: 700; }
    & td code { white-space: nowrap; }
    & hr { margin: var(--s5) 0; }
    & .alt { color: var(--ink-mute); }
    & img { display: none; }
  }
}
/* 50-code.css */
@layer components {
  /* page title for a file: name, then its actions as plain words */
  .file-h {
    display: flex; gap: var(--s4); align-items: center; flex-wrap: wrap; font-size: 18px;
    & > span:first-child { overflow-wrap: anywhere; }
    & .acts { margin-left: auto; display: flex; gap: var(--s2); }
  }
  .notice {
    padding: var(--s3) var(--s4); max-width: var(--measure); font-size: var(--fs-s);
    background: var(--bg-surface); border: 1px solid var(--border-strong); border-left: 3px solid var(--ink-hi); border-radius: var(--r-s);
  }
  .note { color: var(--ink-dim); font-size: var(--fs-s); }
  .pad { padding: var(--s3) var(--s4); }

  /* source view: gutter numbers are links (selectable lines), lines span the full width */
  .code {
    overflow-x: auto; padding: var(--s3) 0; font-family: var(--mono);
    background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r);
    font-size: var(--fs-code); line-height: var(--lh-code);
    & code { display: grid; min-width: max-content; }
    & .line { padding-right: var(--pad); border-left: 2px solid transparent; }
    & .line:hover { background: var(--row); }
    & .line.sel { background: var(--sel); border-left-color: var(--focus); }
    & .ln {
      display: inline-block; width: 8ch; padding-right: 2ch; text-align: right; /* 8ch: a multiple of tab-size, so tabs after the gutter keep their width */
      color: var(--ink-mute); text-decoration: none; user-select: none;
    }
    & .ln:hover, & .sel .ln { color: var(--ink-hi); }
  }
  .source > summary { color: var(--ink-dim); font-size: var(--fs-s); }
  .source[open] > summary { margin-bottom: var(--s3); }
  .img-view { padding: var(--s4); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); }

  /* commit header, like `git show` */
  .show {
    padding: var(--s5); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r);
    & h1 { max-width: var(--measure); overflow-wrap: anywhere; }
    & .msg { margin-top: var(--s3); white-space: pre-wrap; max-width: var(--measure); color: var(--ink-dim); font-size: var(--fs-s); }
    & .show-kv { margin-top: var(--s4); }
    & .show-kv dd { white-space: normal; overflow-wrap: anywhere; }
  }
  .diff-tools {
    display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
    position: sticky; top: var(--hdr-h, 0px); z-index: 5; padding: var(--s2) 0; background: var(--bg-canvas);
    & .grow { flex: 1; }
  }

  /* one file of a diff */
  .dfile { --lnw: 4ch; }
  .lnw-2 { --lnw: 2ch; } .lnw-3 { --lnw: 3ch; } .lnw-4 { --lnw: 4ch; } .lnw-5 { --lnw: 5ch; } .lnw-6 { --lnw: 6ch; } .lnw-7 { --lnw: 7ch; }
  .dfile {
    margin-top: var(--s3); scroll-margin-top: calc(var(--hdr-h, 0px) + var(--bar-h, 48px) + 8px);
    /* a file far from the screen is neither laid out nor painted: a diff of
       hundreds of files scrolls and switches layout like a short one. The
       browser remembers the last size it rendered (auto). */
    content-visibility: auto; contain-intrinsic-size: auto 480px;
    & > summary {
      /* under the diff tools, whose height --bar-h is (two lines when they
         wrap: the merge request bar on a narrow screen) */
      position: sticky; top: calc(var(--hdr-h, 0px) + var(--bar-h, 48px)); z-index: 4;
      background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--r) var(--r) 0 0; padding: var(--s2) var(--s3);
      font-family: var(--mono); font-size: var(--fs-s);
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis; list-style: none;
    }
    &:not([open]) > summary { border-radius: var(--r); }
    & > summary::-webkit-details-marker { display: none; }
    & > summary::before { content: "▸ "; }
    &[open] > summary::before { content: "▾ "; }
    & .st { font-weight: bold; }
    & .p { font-weight: bold; }
    & > .note { border: 1px solid var(--border); border-top: 0; border-radius: 0 0 var(--r) var(--r); background: var(--bg-surface); }
  }
  .dt {
    width: max-content; min-width: 100%; font-family: var(--mono);
    font-size: var(--fs-code); line-height: var(--lh-code);
    & td { padding: 0; vertical-align: top; }
    /* the gutter is as wide as the largest line number of the file (lnw-N on
       .dfile), plus 1ch on each side */
    & .ln { width: calc(var(--lnw) + 2ch); min-width: calc(var(--lnw) + 2ch); padding: 0 1ch; text-align: right; color: var(--ink-mute); user-select: none; }
    & .m { width: 2ch; text-align: center; user-select: none; color: var(--ink-dim); }
    & .tx { white-space: pre; }
    /* the hunk headers and the hidden lines stay quiet: a faint band between
       the code, so that the eye keeps reading */
    & .hunk td, & .gap td { background: color-mix(in srgb, var(--paper-alt) 35%, var(--paper)); }
    & .hunk td { color: var(--ink-mute); padding: 0 1ch; }
    /* a run of hidden lines: the whole row loads them */
    & .gap td { padding: 0; }
    & .gap button {
      display: block; width: 100%; padding: 2px 1ch; text-align: left; cursor: pointer;
      font: inherit; color: var(--ink-mute); background: none; border: 0;
      border-block: 1px dashed color-mix(in srgb, var(--border) 60%, transparent);
    }
    & .gap button:hover, & .gap button:focus-visible { color: var(--ink-hi); background: var(--bg-strong); }
    & .gap button:disabled { cursor: progress; opacity: .6; }
    & .add, & tr.add td { background: var(--add); }
    & .del, & tr.del td { background: var(--del); }
    & .add.m, & tr.add .m { color: var(--teal); font-weight: bold; }
    & .del.m, & tr.del .m { color: var(--red); font-weight: bold; }
    & tr.add .ln, & .ln.add { color: var(--teal); }
    & tr.del .ln, & .ln.del { color: var(--red); }
    & .none { background: var(--paper-alt); }
  }
  .dscroll { overflow-x: auto; background: var(--bg-surface); border: 1px solid var(--border); border-top: 0; border-radius: 0 0 var(--r) var(--r); }
  /* split: a fixed layout takes its widths from the colgroup (the first row is
     the hunk header, which spans all columns); long lines wrap in their half */
  .spl {
    width: 100%; table-layout: fixed;
    & .c-ln { width: calc(var(--lnw) + 2ch); } & .c-m { width: 2.5ch; }
    & .tx, & .hunk td { white-space: pre-wrap; overflow-wrap: anywhere; }
    & td.ln:nth-child(4) { border-left: 1px solid var(--border); }
  }
  #diffs[data-diff="unified"] .spl, #diffs[data-diff="split"] .uni { display: none; }

  /* diff table of contents in the rail: one line a file, the name first and
     its directory dimmed after it (cut from its start when long), the
     comments, the counts */
  .files {
    font-size: var(--fs-s); position: relative; /* the offsets of its links count from it (ermite.js) */
    & li[hidden] { display: none; }
    & a {
      /* centred, not on the baseline: the smaller counts on a baseline sit
         a pixel below the row, enough to give the list a scroll bar */
      display: grid; grid-template-columns: 1.5ch minmax(0, 1fr) auto auto; column-gap: var(--s2); align-items: center;
      height: 26px; line-height: 26px; padding: 0 var(--s2); margin: 0 calc(-1 * var(--s2));
      border-radius: 4px; border: 1px solid transparent; text-decoration: none; font-family: var(--mono); color: var(--ink);
    }
    & a:hover { background: var(--bg-raised); }
    & a:hover .p { text-decoration: underline; }
    & a[aria-current="true"] { background: var(--row); border-color: var(--ink-mute); }
    & a[aria-current="true"] .p { font-weight: bold; color: var(--ink-hi); }
    & .st { color: var(--ink-mute); font-weight: bold; }
    & .st[data-st="A"] { color: var(--teal); }
    & .st[data-st="D"] { color: var(--red); }
    & .nm { overflow: hidden; white-space: nowrap; display: flex; min-width: 0; }
    /* the name gives way last: the directory shrinks first, down to its
       ellipsis, before the name is cut */
    & .nm .p { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    /* cut from the start (rtl), the path itself kept in its order (bdi) */
    & .nm .d { flex: 0 1000 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; color: var(--ink-mute); padding-left: 1ch; }
    & .nm .d bdi { direction: ltr; }
    & .cn { font: 600 var(--fs-xs) / 16px var(--font); padding: 0 6px; border-radius: 999px; background: var(--ink-hi); color: var(--on-ink); align-self: center; }
    & .cn.done { background: var(--bg-strong); color: var(--ink-dim); }
    & .n { color: var(--ink-dim); font-size: var(--fs-xs); white-space: nowrap; }
  }

  @media (max-width: 700px) {
    .diff-tools .grow { flex-basis: 100%; height: 0; }
    .file-h .acts { margin-left: 0; }
  }
  .pager { display: flex; gap: var(--s3); justify-content: center; }
  .days section[hidden] { display: none; }
  .list.refs {
    & .c-kind { width: 80px; color: var(--ink-mute); }
    & .c-name { width: 32%; font-family: var(--mono); font-size: var(--fs-s); }
    & .c-sha { width: 96px; }
    & .c-sub { width: auto; }
  }
  /* the commit table inside a rail block: no frame of its own. The id, the
     checks and the date take the width of their text (an empty checks cell
     next to nothing); the subject takes the rest, cut at its end only. */
  .rail .list.commits {
    border: 0; border-radius: 0; background: none; table-layout: auto;
    & td { height: 34px; padding: 0 var(--s2); width: 1%; white-space: nowrap; }
    & td:first-child { padding-left: var(--s3); }
    & td:last-child { padding-right: var(--s4); }
    & .c-who { display: none; }
    & .c-subject { width: auto; max-width: 0; font-size: var(--fs-s); }
    /* the pills are hidden here, the signature one too: the rail is narrow and
       the subject is what the row is for; the commit page shows the badge. */
    & .c-subject .pill { display: none; }
    & .c-ck:empty { padding: 0; }
    & .c-when { text-align: right; }
  }
  .rail section > p { overflow-wrap: anywhere; }
  @media (max-width: 700px) {
    /* the name takes what the fixed columns leave */
    .list.refs .c-name { width: auto; }
  }
}

@layer components {
  .gallery section { margin-top: var(--s6); }
  .gallery .rule-h > :last-child { font-weight: normal; color: var(--ink-mute); order: 2; }
  .gallery .rule-h::after { order: 1; }
  .gallery .files { max-width: var(--rail); }
  .linkish { text-decoration: underline; text-decoration-color: var(--rule); text-underline-offset: 3px; }
  .linkish:hover { text-decoration-color: currentColor; }
}

@layer components {
  /* counts and bars: + in teal, - in red, everywhere a change is summarised */
  .plus { color: var(--teal); }
  .minus { color: var(--red); }
}
/* 55-diff.css */
@layer components {
  /* an invisible character in code, shown instead of applied (Trojan Source) */
  .inv {
    color: var(--red); font-weight: bold; font-size: var(--fs-s);
    outline: 1px solid var(--red); outline-offset: -1px; padding: 0 2px;
  }
  .eol { color: var(--ink-mute); padding-left: 1ch; user-select: none; }
}

@layer components {
  .sel { outline: 1px solid var(--ink-dim); outline-offset: -1px; }

  /* a range of selected diff lines (shift + click) is one block: one border
     around the run, none between its lines. Each edge is an inset shadow of
     the cells; the top one only on the first line of the run, the bottom one
     only on the last. In split, each side is a block of its own. */
  .dt {
    --sel-edge: var(--ink-dim);
    & .sel { outline: none; }
    & tr.sel > td, & td.sel {
      box-shadow: var(--sel-l, 0 0 transparent), var(--sel-r, 0 0 transparent), var(--sel-t, 0 0 transparent), var(--sel-b, 0 0 transparent);
      --sel-t: inset 0 1px var(--sel-edge); --sel-b: inset 0 -1px var(--sel-edge);
    }
    /* unified: the row is selected */
    & tr.sel > td:first-child { --sel-l: inset 1px 0 var(--sel-edge); }
    & tr.sel > td:last-child { --sel-r: inset -1px 0 var(--sel-edge); }
    & tr.sel + tr.sel > td { --sel-t: 0 0 transparent; }
    & tr.sel:has(+ tr.sel) > td { --sel-b: 0 0 transparent; }
    /* split: the cells of one side (number, mark, text) are selected */
    & td.sel.ln { --sel-l: inset 1px 0 var(--sel-edge); }
    & td.sel.tx { --sel-r: inset -1px 0 var(--sel-edge); }
    & tr:has(> :nth-child(3).sel) + tr > :nth-child(-n + 3).sel,
    & tr:has(> :nth-child(6).sel) + tr > :nth-child(n + 4).sel { --sel-t: 0 0 transparent; }
    & tr:has(> :nth-child(3).sel):has(+ tr > :nth-child(3).sel) > :nth-child(-n + 3).sel,
    & tr:has(> :nth-child(6).sel):has(+ tr > :nth-child(6).sel) > :nth-child(n + 4).sel { --sel-b: 0 0 transparent; }
  }
}
/* 56-chroma.css */
/* Syntax colours of the code view. Generated by scripts/chroma-css.go from
   chroma's token classes; the colours are the --syn-* properties of
   00-tokens.css (the Despair hues, dark and light), none is defined here. */
@layer components {
  .chroma { color: var(--syn-plain); }
  .chroma .c { color: var(--syn-comment); font-style: italic }
  .chroma .c1 { color: var(--syn-comment); font-style: italic }
  .chroma .ch { color: var(--syn-comment); font-style: italic }
  .chroma .cm { color: var(--syn-comment); font-style: italic }
  .chroma .cs { color: var(--syn-comment); font-style: italic }
  .chroma .dl { color: var(--syn-string); font-style: italic }
  .chroma .k { color: var(--syn-keyword); font-weight: bold }
  .chroma .kc { color: var(--syn-keyword); font-weight: bold }
  .chroma .kd { color: var(--syn-keyword); font-weight: bold }
  .chroma .kn { color: var(--syn-keyword); font-weight: bold }
  .chroma .kr { color: var(--syn-keyword); font-weight: bold }
  .chroma .nc { color: var(--syn-type); font-weight: bold }
  .chroma .ne { color: var(--syn-type); font-weight: bold }
  .chroma .nn { color: var(--syn-type); font-weight: bold }
  .chroma .ow { color: var(--syn-punct); font-weight: bold }
  .chroma .s { color: var(--syn-string); font-style: italic }
  .chroma .s1 { color: var(--syn-string); font-style: italic }
  .chroma .s2 { color: var(--syn-string); font-style: italic }
  .chroma .sa { color: var(--syn-string); font-style: italic }
  .chroma .sb { color: var(--syn-string); font-style: italic }
  .chroma .sc { color: var(--syn-string); font-style: italic }
  .chroma .sd { color: var(--syn-string); font-style: italic }
  .chroma .se { color: var(--syn-string); font-weight: bold; font-style: italic }
  .chroma .sh { color: var(--syn-string); font-style: italic }
  .chroma .si { color: var(--syn-string); font-weight: bold; font-style: italic }
  .chroma .sr { color: var(--syn-string); font-style: italic }
  .chroma .ss { color: var(--syn-string); font-style: italic }
  .chroma .sx { color: var(--syn-string); font-style: italic }
  .chroma .line { display: block; }

  /* an invisible character in code, shown instead of applied (Trojan Source) */
  .chroma .ctl {
    color: var(--red); font-weight: bold; font-style: normal; font-size: var(--fs-s);
    outline: 1px solid var(--red); outline-offset: -1px; padding: 0 .25ch;
  }
  .img-view { margin-top: var(--lh); & img { max-width: 100%; height: auto; } }
}
/* 60-mr.css */
@layer components {
  /* merge requests: the review page. Hue only where it carries a verdict. */
  .mr-h .show-kv { margin-top: 0; }
  #merge-menu .htmx-indicator { display: none; }
  #merge-menu .htmx-request .htmx-indicator { display: inline; }
  /* one card: the header (title, facts) a shade lighter, the description below */
  .mr-card {
    background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden;
    & > .mr-h { background: var(--bg-raised); border: 0; border-radius: 0; padding-bottom: var(--s3); }
    & > .mr-desc.prose { border: 0; border-top: 1px solid var(--border); border-radius: 0; }
  }

  .mr-footer {
    border-top: 1px solid var(--border); padding: var(--s2) var(--s4);
    /* the shade of the card header; the card's overflow clips the corners */
    background: var(--bg-raised);
    font-size: var(--fs-s);
    /* the tabs are buttons: a thin border, the count in a darker badge;
       the open one in the teal accent */
    & [data-mr-tabs] { display: flex; flex-wrap: wrap; gap: var(--s2); }
    & [data-mr-tabs] button {
      display: inline-flex; align-items: center; gap: var(--s1);
      padding: 2px var(--s2); border: 1px solid var(--border-strong); border-radius: var(--r-s);
      color: var(--ink-dim); text-decoration: none; cursor: pointer;
    }
    & [data-checks-label] { color: var(--ink-dim); font-size: var(--fs-xs); }
    & [data-mr-tabs] .count { margin-left: 0; color: var(--ink-hi); background: var(--bg-canvas); box-shadow: inset 0 0 0 1px var(--border); }
    & [data-mr-tabs] button:hover { background: var(--bg-strong); color: var(--ink-hi); }
    & [data-mr-tabs] button[aria-expanded="true"] { border-color: var(--teal); color: var(--teal); background: var(--bg-surface); }
    & [data-mr-panel] { padding-block-start: var(--s2); overflow-x: auto; }
    & [hidden] { display: none; }
    /* Without scripts both panels remain visible; disclosure controls use data-js. */
    & section h2 { font-size: var(--fs-s); color: var(--ink-dim); }
    & table { width: 100%; border-collapse: collapse; }
    & th, & td { text-align: left; padding: var(--s2); border-bottom: 1px solid var(--border); }
    & th { color: var(--ink-dim); font-weight: 500; }
    & tbody tr:last-child > :is(td, th) { border-bottom: 0; }
  }
  .merge-settings { font-size: var(--fs-s); color: var(--ink-dim); }
  .merge-settings h2 { font-size: var(--fs-s); }

  .mr-state[data-state="open"]::before { content: "● "; color: var(--teal); }
  .mr-state[data-state="merged"]::before { content: "✓ "; color: var(--teal); }
  .mr-state[data-state="closed"]::before { content: "✗ "; color: var(--red); }
  .mr-state[data-state="draft"]::before { content: "◌ "; color: var(--ink-dim); }
  /* the description: Markdown as a README, as wide as the header card above;
     the text inside keeps the reading measure */
  .mr-desc.prose { max-width: none; padding: var(--s4) var(--s5); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); }
  .mr-desc.prose > * { max-width: var(--measure); }
  .mr-desc.prose > pre, .mr-desc.prose > table { max-width: 100%; }

  .since {
    display: inline-flex; flex-wrap: wrap; gap: var(--s1); padding: var(--s1);
    background: var(--bg-raised); border-radius: var(--r-s);
    & a { padding: var(--s1) var(--s3); border-radius: 4px; text-decoration: none; color: var(--ink-dim); font-size: var(--fs-s); }
    & a:hover { color: var(--ink-hi); }
    & a[aria-current] { color: var(--ink-hi); font-weight: 700; background: var(--bg-surface); box-shadow: 0 0 0 1px var(--border-strong); }
    & .mute { font-weight: 400; font-family: var(--mono); }
  }

  /* the bar above the diff of a merge request: the diff tools, the checks and
     the menus of the owner, on one line that follows the review */
  /* the checks and the menus stay on the right, also when they wrap under the
     diff tools; mr.js measures the height of the bar (--mr-bar-h) */
  body:has(.mr-bar) { --bar-h: var(--mr-bar-h, 48px); }
  .mr-bar {
    gap: var(--s2);
    & .mr-acts { display: flex; gap: var(--s2); align-items: center; margin-left: auto; }
    & .mr-ck { margin-left: 0; height: 32px; padding: 0 var(--s2); border-radius: var(--r-s); text-decoration: none; color: var(--ink-dim); font-size: var(--fs-s); }
    & .mr-ck:hover { background: var(--bg-raised); color: var(--ink-hi); }
  }

  /* a menu of the bar: a <details> whose panel opens under its button */
  .menu {
    position: relative;
    & > summary { list-style: none; }
    & > summary::-webkit-details-marker { display: none; }
    & > summary.primary::after { content: ""; width: 0; height: 0; margin-left: 2px; border: 4px solid transparent; border-top-color: currentColor; transform: translateY(2px); }
    & .menu-pop {
      position: absolute; right: 0; top: calc(100% + var(--s1)); z-index: 6; width: 320px; max-width: calc(100vw - 2 * var(--pad));
      display: grid; gap: var(--s3); padding: var(--s3) var(--s4);
      background: var(--bg-surface); border: 1px solid var(--border-strong); border-radius: var(--r); box-shadow: 0 8px 24px rgb(0 0 0 / .18);
      font-size: var(--fs-s);
    }
    & .kv { margin: 0; }
  }
  /* the view menu of a diff: the layout and the fold, one row each */
  .vmenu {
    & > summary::after { content: ""; width: 0; height: 0; margin-left: 2px; border: 4px solid transparent; border-top-color: currentColor; transform: translateY(2px); }
    & .menu-pop { left: 0; right: auto; width: 220px; gap: var(--s1); padding: var(--s2); }
    & .menu-pop .btn { width: 100%; justify-content: flex-start; border-color: transparent; background: none; }
    & .menu-pop .btn:hover { background: var(--bg-raised); }
    & .menu-pop .btn[aria-current="true"] { background: var(--bg-raised); color: var(--ink-hi); }
    & .menu-pop .btn kbd { margin-left: auto; }
  }
  .mmenu {
    & .menu-pop { box-sizing: border-box; min-width: 0; overflow-wrap: anywhere; }
    & .menu-pop > *, & form, & .d-modes, & .d-btns { min-width: 0; max-width: 100%; box-sizing: border-box; }
    & .d-acts { display: grid; gap: var(--s3); }
    & .d-modes label, & .d-check { min-width: 0; }
    & code { overflow-wrap: anywhere; }
    & .d-btns .btn { min-width: 0; max-width: 100%; white-space: normal; }
    & .d-modes { display: grid; gap: var(--s1); border: 0; padding: 0; margin: 0; }
    & .d-modes label, & .d-check {
      display: flex; gap: var(--s2); align-items: center; padding: 4px var(--s2); margin: 0 calc(-1 * var(--s2));
      border-radius: var(--r-s); color: var(--ink); cursor: pointer;
    }
    & .d-modes label:hover, & .d-check:hover { background: var(--bg-raised); }
    & .d-modes label:has(:checked) { background: var(--bg-raised); color: var(--ink-hi); font-weight: 600; }
    & .d-modes kbd, & .d-check kbd { margin-left: auto; }
    & input { accent-color: var(--ink-hi); margin: 0; }
    & .d-check { color: var(--ink-dim); }
    & .d-btns { display: flex; margin-top: var(--s1); }
    & .d-btns .btn { flex: 1; justify-content: center; }
    & .d-draft { color: var(--ink-dim); }
    & .d-note { margin: 0; color: var(--ink-dim); }
    & .d-err { margin: 0; padding: var(--s2) var(--s3); color: var(--ink-hi); border: 1px solid var(--red); border-left-width: 3px; border-radius: var(--r-s); overflow-wrap: anywhere; }
    /* the badge is a live slot, but not a banner */
    & #mr-mergeability:not(:empty) { padding: 0; font-weight: normal; background: none; border: 0; display: grid; gap: var(--s1); }
    & .mg-paths { margin: 0; padding-left: 2ch; max-height: 8em; overflow: auto; }
    & .mg-paths code { overflow-wrap: anywhere; }
    & .d-modes label:has(:disabled) { color: var(--ink-mute); cursor: not-allowed; }
    & .d-modes label:has(:disabled):hover { background: none; }
    & .btn:disabled { opacity: .5; cursor: not-allowed; }
  }
  .badge[data-state] { display: inline-block; padding: 0 var(--s2); border: 1px solid var(--border-strong); border-radius: var(--r-s); font-weight: 600; color: var(--ink-hi); }
  .badge[data-state="up_to_date"] { border-color: var(--teal); color: var(--teal); }
  .badge[data-state="behind"] { border-color: var(--teal-2); }
  .badge[data-state="conflict"] { border-color: var(--red); color: var(--red); }
  .badge[data-state="checking"] { color: var(--ink-dim); border-style: dashed; }
  .note[role="status"] { color: var(--ink-dim); }
  .omenu {
    & > summary { font-size: 18px; line-height: 1; }
    & .menu-pop { width: 280px; }
    & form .btn { width: 100%; justify-content: flex-start; }
    & .btn kbd { margin-left: auto; }
    & .d-or > summary { cursor: pointer; list-style: none; color: var(--ink-mute); }
    & .d-or > summary::-webkit-details-marker { display: none; }
    & .d-or > summary::before { content: "▸ "; }
    & .d-or[open] > summary::before { content: "▾ "; }
    & .d-or > summary:hover { color: var(--ink-hi); }
    & .d-or[open] > .clone { margin-top: var(--s2); }
    & .clone code { white-space: pre-wrap; overflow-wrap: anywhere; }
    & #mr-signing code { overflow-wrap: anywhere; }
  }

  /* the rail of a merge request follows the review: it sticks under the
     header, one screen high, and scrolls on its own to its verdicts. The list of files keeps its own scroll, under a height, so
     that the blocks below it stay in reach. Only on a two-column layout. */
  @media (min-width: 1081px) {
    .rail:has(.r-files) {
      position: sticky; top: calc(var(--hdr-h, 0px) + var(--s4));
      max-height: calc(100dvh - var(--hdr-h, 0px) - var(--s4) * 2);
      overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
    }
    /* the blocks keep their height: the rail scrolls, it does not squeeze them */
    .rail:has(.r-files) > * { flex: none; }
    .rail .r-files > .files { max-height: 55dvh; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  }
  /* on one column the rail goes under the diff: the list of files keeps its
     own scroll, under a height */
  @media (max-width: 1080px) {
    .rail .r-files > .files { max-height: 50dvh; overflow-y: auto; overscroll-behavior: contain; }
  }
  .r-files {
    & > h2 kbd { margin-left: auto; }
    & > h2 .fold { width: 24px; height: 24px; margin: -2px -6px -2px 0; background: none; border-color: transparent; color: var(--ink-dim); }
    & > h2 .fold:hover { color: var(--ink-hi); border-color: var(--border-strong); }
    & > h2 .fold .ico { transition: transform .15s; }
    &[data-folded] > h2 { border-bottom: 0; }
    &[data-folded] > h2 .fold .ico { transform: rotate(-90deg); }
    &[data-folded] > :not(h2) { display: none; }
    & > .ffilter { margin: var(--s2) var(--s3) 0; }
    & > .ffilter input {
      width: 100%; height: 30px; padding: 0 var(--s2); font: inherit; font-size: var(--fs-s); color: inherit;
      background: var(--bg-inset); border: 1px solid var(--border-strong); border-radius: var(--r-s);
    }
    & > .files { margin: var(--s2) 0 !important; padding: 0 var(--s2); }
  }

  /* a file of the diff whose window is not loaded yet: about its room */
  .dlazy {
    display: flex; align-items: center; justify-content: center;
    background: repeating-linear-gradient(var(--bg-surface) 0 var(--lh-code), var(--paper-alt) var(--lh-code) calc(var(--lh-code) * 2));
    border: 1px solid var(--border); border-top: 0; border-radius: 0 0 var(--r) var(--r);
    font-size: var(--fs-s);
    & a { color: var(--ink-mute); }
    &.dlazy-1 { height: 120px; } &.dlazy-2 { height: 360px; } &.dlazy-3 { height: 900px; } &.dlazy-4 { height: 1600px; }
    /* with scripts the window comes by itself: the link of the page without
       scripts would only flash */
    html.js &:not([data-manual]) > a { visibility: hidden; }
    &[data-manual] { height: auto; padding: var(--s3); }
    &[data-manual][data-loading] > a { opacity: .5; }
    & .notice { margin: 0; }
  }
  .dloose {
    padding: var(--s2) var(--s3) var(--s3); background: var(--bg-surface);
    border: 1px solid var(--border); border-top: 0; border-radius: 0 0 var(--r) var(--r);
  }

  .pcommits { font-size: var(--fs-s); display: grid; gap: var(--s1); }
  .pcommits li { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 2px var(--s2); margin: 0 calc(-1 * var(--s2)); border-radius: 4px; }
  .pcommits li a { font-family: var(--mono); }
  .pcommits li[data-new] { background: var(--bg-raised); }
  .pcommits .s { color: var(--ink); }


  /* a note: a ruled block, under its line in the diff and in the list of comments */
  .cmt {
    padding: var(--s3) var(--s4); margin-top: var(--s3); max-width: var(--measure);
    background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--ink-hi); border-radius: var(--r-s);
    white-space: normal; font-family: var(--font); font-size: var(--fs-s); line-height: 22px;
    & p { white-space: normal; }
    & .c-who { font-weight: bold; }
    & .c-state { color: var(--ink-dim); }
    & .c-where { font-size: var(--fs-s); overflow-wrap: anywhere; }
    & .c-act { margin-top: var(--s2); }
    & .c-act button { height: 26px; font-size: var(--fs-xs); }
    &[data-resolved="true"] { border-left-color: var(--border-strong); }
    &[data-resolved="true"] .c-body { color: var(--ink-dim); }
  }
  .dt .fnote td { background: var(--bg-canvas); padding: var(--s2) var(--s3); white-space: normal; }
  .dt .fnote .cmt, .dt .fnote .cform { margin: 0; }
  .dt .fnote .cmt + .cmt, .dt .fnote .cmt + .cform { margin-top: var(--s2); }
  .ln a { color: inherit; text-decoration: none; }
  .ln a:hover, .ln a:focus-visible { text-decoration: underline; color: var(--ink-hi); }

  /* the forms: a comment, a new merge request */
  .cform {
    display: grid; gap: var(--s2); margin-top: var(--s3); max-width: var(--measure);
    font-family: var(--font); font-size: var(--fs-s);
    & label { color: var(--ink-dim); font-weight: 600; }
    & textarea, & input[type="text"] {
      display: block; width: 100%; font: inherit; font-size: var(--fs); color: inherit; resize: vertical;
      background: var(--bg-surface); border: 1px solid var(--border-strong); border-radius: var(--r-s); padding: var(--s2) var(--s3);
    }
    & textarea::placeholder { color: var(--ink-mute); opacity: 1; }
    & .f-btns { display: flex; gap: var(--s2); align-items: center; margin-top: var(--s1); }
  }

  /* the public issue form: counters, field errors, the honeypot out of sight */
  .cform output { justify-self: end; font: var(--fs-s) var(--mono); color: var(--ink-mute); }
  .cform output.warn { color: var(--ink-hi); font-weight: 700; }
  .cform output.over { color: var(--red); font-weight: 700; }
  .cform .f-error { color: var(--red); margin: 0; }
  .cform .hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

  /* the inbox: items awaiting moderation, shown as text */
  .pending-list { display: grid; gap: var(--s3); list-style: none; padding: 0; margin: 0; }
  .pending { padding: var(--s3) var(--s4); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); display: grid; gap: var(--s2); }
  .pending .p-head { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: baseline; color: var(--ink-dim); font-size: var(--fs-s); }
  .pending .p-title { margin: 0; font-weight: 700; color: var(--ink-hi); overflow-wrap: anywhere; }
  .pending .p-body { margin: 0; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
  .pending .p-btns { display: flex; gap: var(--s2); flex-wrap: wrap; }
  .pending .p-btns form { margin: 0; }

  .list.mrs {
    & .c-n { width: 64px; }
    & .c-state { width: 110px; }
    & .c-subject { overflow: hidden; text-overflow: ellipsis; }
    & .c-who { width: 140px; }
    & .c-when { width: 100px; }
    & tr[data-state="open"] .c-state { font-weight: bold; }
    & tr[data-state="open"] .c-state::before { content: "● "; color: var(--teal); }
    & tr[data-state="merged"] .c-state::before { content: "✓ "; color: var(--teal); }
    & tr[data-state="closed"] .c-state::before { content: "✗ "; color: var(--red); }
  }
  #mr-notice:empty { display: none; }

  /* the owner's inbox: counters, repository filter, then the two lists */
  .inbox {
    display: flex; flex-direction: column; gap: var(--s4);
    & .inbox-counts { font-size: var(--fs-l, var(--fs)); color: var(--ink-dim); }
    & .inbox-counts strong { color: var(--ink-hi); font-family: var(--mono); }
    & .since { align-self: flex-start; max-width: 100%; }
  }

  @media (max-width: 700px) {
    .list.mrs .c-who { display: none; }
  }
}

@layer components {
  .c-body { white-space: normal; overflow-wrap: anywhere; }
  .c-body.prose > * { margin-block: .5em; }
  .c-body .ref { font-variant-numeric: tabular-nums; text-decoration: underline; }
  .cmt > .cmt { margin-inline-start: 2ch; }
}
/* 65-ci.css */
@layer components {
  /* CI: runs, jobs, steps, checks and the log. Hue only where it carries a
     verdict, and every mark has its word beside it or in its label. */
  .ck {
    display: inline-block; width: 14px; height: 14px; margin-right: var(--s1); vertical-align: -2px;
    border: 2px solid var(--ink-dim); border-radius: 50%; box-sizing: border-box; flex: none;
  }
  .ck-ok { background: var(--teal); border-color: var(--teal); }
  .ck-bad { background: var(--red); border-color: var(--red); border-radius: 3px; transform: rotate(45deg) scale(.85); }
  .ck-cancelled { border-style: dashed; }
  .ck-skipped { border-color: var(--border-strong); background: var(--bg-raised); }
  .ck-queued { border-style: dotted; }
  .ck-running { border-color: var(--teal); border-top-color: transparent; animation: ck-spin 1s linear infinite; }
  @keyframes ck-spin { to { transform: rotate(360deg); } }
  @media (prefers-reduced-motion: reduce) { .ck-running { animation: none; border-top-color: var(--teal); } }

  .ck-sum { display: inline-flex; align-items: center; gap: var(--s1); margin-left: var(--s2); font-size: var(--fs-xs); white-space: nowrap; }
  /* The lists are table-layout: fixed, where a percentage is only a sliver:
     the check column holds the mark, its count and the padding of the cells;
     the refs list has the mark next to the sha. */
  .c-ck { width: 1%; white-space: nowrap; }
  .list .c-ck { width: 92px; }
  /* the commit table of a rail lays out on its content (50-code.css) */
  .rail .list.commits .c-ck { width: 1%; }
  .list.refs .c-sha { width: 150px; }

  /* the table is fixed: the status column is the icon, its margin and the
     padding of the cells (a percentage would leave a sliver) */
  .runs .c-st { width: calc(14px + var(--s1) + 2 * var(--s3)); }
  /* the recent runs of the summary rail */
  .rruns {
    display: grid; padding: 0; list-style: none; font-size: var(--fs-s);
    & li { display: flex; align-items: center; gap: var(--s1); min-width: 0; padding: 2px 0; }
    & .ck { margin-right: var(--s1); }
    & .rr-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-hi); text-decoration: none; }
    & .rr-name:hover { text-decoration: underline; }
    & .rr-ref { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: var(--s1); font-family: var(--mono); color: var(--ink-dim); text-decoration: none; }
    & time { flex: none; margin-left: auto; padding-left: var(--s2); white-space: nowrap; }
  }
  .runs .c-dur, .runs .c-who { white-space: nowrap; }
  .runs tr[data-new] { background: var(--bg-raised); }

  .run-h { display: flex; align-items: center; gap: var(--s2); margin: 0 0 var(--s4); }
  .run-err, .job-err {
    max-width: var(--measure); padding: var(--s3) var(--s4); margin: 0 0 var(--s4); white-space: pre-wrap; overflow-wrap: anywhere;
    background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--red); border-radius: var(--r-s);
    font: inherit; font-size: var(--fs-s);
  }

  .jobs { display: grid; gap: var(--s4); padding: 0; list-style: none; }
  .jobs > li { padding: var(--s3) var(--s4); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); }
  .job-h { display: flex; align-items: center; gap: var(--s2); font-weight: 700; }
  .steps { display: grid; gap: 2px; padding: 0; margin: var(--s2) 0 0; list-style: none; font-size: var(--fs-s); }
  /* a long step name (a whole shell command) wraps inside the rail; the icon
     stays on its first line and the duration at the right */
  .steps li { display: flex; align-items: flex-start; gap: var(--s1); min-width: 0; }
  .steps li > .ck { flex: none; margin-top: 3px; }
  .steps li > :is(a, span:not(.ck, .dim)) { flex: 1; min-width: 0; overflow-wrap: anywhere; }
  .steps li > .dim { flex: none; margin-left: auto; }
  .attempts { padding: 0; margin: var(--s2) 0 0; list-style: none; font-size: var(--fs-s); }
  .checks { display: grid; gap: var(--s1); padding: 0; margin: 0; list-style: none; font-size: var(--fs-s); }
  .checks li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1); }
  .checks .ck-group { font-size: var(--fs-xs); color: var(--ink-dim); margin-top: var(--s2); }
  .checks .ck-group:first-child { margin-top: 0; }
  .checks .ck-group a { color: inherit; }
  /* the merge rule under the checks: a note about them, not one of them */
  .rail section > .rule-note {
    display: flex; gap: 6px; margin-top: var(--s3); padding-top: var(--s2); border-top: 1px dashed var(--border);
    font-size: var(--fs-xs); font-style: italic; line-height: 1.4; color: var(--ink-mute);
    &::before { content: "i"; flex: none; width: 14px; height: 14px; margin-top: 1px; border: 1px solid currentColor; border-radius: 50%; font: 700 9px / 12px var(--mono); font-style: normal; text-align: center; }
  }

  /* annotations and summaries of a run */
  .annots { margin: 0 0 var(--s4); }
  .annots h3, .summaries h3 { display: flex; align-items: baseline; gap: var(--s2); margin: 0 0 var(--s2); font-size: var(--fs-s); }
  .annot-list { display: grid; gap: var(--s2); padding: 0; margin: 0; list-style: none; }
  .annot {
    display: flex; gap: var(--s2); align-items: flex-start; padding: var(--s2) var(--s3);
    background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--border-strong); border-radius: var(--r-s);
    font-size: var(--fs-s);
  }
  .annot-failure { border-left-color: var(--red); }
  .annot-warning { border-left-style: dashed; border-left-color: var(--ink-dim); }
  .annot-notice { border-left-color: var(--teal); }
  .annot p { margin: 0; }
  .annot-step { flex-basis: 100%; font-weight: 700; }
  .annot:has(.annot-step) { flex-wrap: wrap; }
  .annot-body { min-width: 0; }
  .annot-head { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: baseline; }
  .annot-level { font-weight: 700; }
  .annot-msg { white-space: pre-wrap; overflow-wrap: anywhere; }
  .annot-where { color: var(--ink-dim); font-family: var(--mono); overflow-wrap: anywhere; }
  .an { display: inline-block; flex: none; width: 14px; height: 14px; margin-top: 2px; border: 2px solid var(--ink-dim); box-sizing: border-box; }
  .an-failure { background: var(--red); border-color: var(--red); border-radius: 3px; transform: rotate(45deg) scale(.85); }
  .an-warning { border-radius: 50% 50% 0 0; border-style: dashed; }
  .an-notice { border-radius: 50%; border-color: var(--teal); }
  .summaries { margin: var(--s5) 0 0; }
  .summary { padding: var(--s3) var(--s4); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r); }
  .summary + .summary { margin-top: var(--s3); }
  .summary-step { margin: 0 0 var(--s2); font-size: var(--fs-s); color: var(--ink-dim); }

  .joblog { margin-top: var(--s4); }
  .log {
    margin: 0; padding: var(--s2) 0; list-style: none; overflow-x: auto;
    font: var(--fs-s) / 1.5 var(--mono); background: var(--bg-inset); border: 1px solid var(--border); border-radius: var(--r-s);
  }
  .log .lg { display: flex; gap: var(--s3); padding: 0 var(--s3); white-space: pre-wrap; overflow-wrap: anywhere; }
  .log .lg:target { background: var(--bg-raised); }
  .log .lg time { flex: none; color: var(--ink-dim); user-select: none; }
  .log .lg .t { min-width: 0; }
  .log .group .t { font-weight: 700; }
  .log .endgroup { display: none; }
  .log .error .t { color: var(--red); }
  .joblog .more { margin: var(--s2) 0; font-size: var(--fs-s); }
}
/* 80-live.css */
@layer components {
  /* live updates: a slot is a status region that stays in the page; its banner
     comes and goes as its content. Empty, it is out of the way but still in the
     accessibility tree (display: none would drop the region, and the next banner
     would not be announced). */
  .live-slot:empty { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .live-slot:not(:empty) {
    padding: var(--s3) var(--s4); font-weight: 700;
    background: var(--bg-surface); border: 1px solid var(--border-strong); border-left: 3px solid var(--teal); border-radius: var(--r-s);
  }
  /* A deferred MR refresh must not insert height above a long diff. */
  #mr-refresh-status:has(a) {
    position: fixed; bottom: var(--s4); left: var(--s4); z-index: 24;
    max-width: min(42rem, calc(100vw - 2 * var(--s4))); font-size: var(--fs-s);
  }
  .live-slot a { color: var(--ink-hi); }
}
/* 85-mobile.css */
@layer components {
  .mr-touch-range { display: none; }

  /* MR only: retain the shell's desktop layout and other pages' spacing. */
  @media (max-width: 720px) {
    body:has(#diffs[data-mr]) {
      --pad: 0px;
      --hdr-h: 97px;
      overflow-x: clip;
    }
    body:has(#diffs[data-mr]) .work { padding-inline: 0; margin-inline: 0; gap: var(--s3); }
    body:has(#diffs[data-mr]) main { min-width: 0; padding-inline: 0; }
    body:has(#diffs[data-mr]) :is(.card, .mr-card, .mr-desc, .dfile, .dscroll, .code, .rail section) {
      margin-inline: 0; border-inline: 0; border-radius: 0; min-width: 0; max-width: 100%;
    }
    body:has(#diffs[data-mr]) :is(.mr-h, .mr-desc.prose, .card-h, .mr-footer) { padding-inline: 4px; }
    body:has(#diffs[data-mr]) .mr-footer :is(th, td) { padding-inline: var(--s1); }
    body:has(#diffs[data-mr]) .mr-desc.prose > pre { margin-inline: -4px; padding-inline: 0; max-width: calc(100% + 8px); }
    #diffs[data-mr] .dfile > summary { padding-inline: 0; border-inline: 0; border-radius: 0; }
    #diffs[data-mr] :is(.dscroll, .code) { overflow-x: auto; overscroll-behavior-x: contain; padding-inline: 0; }
    #diffs[data-mr] .dt .ln { width: calc(var(--lnw) + .5ch); min-width: calc(var(--lnw) + .5ch); padding-inline: .25ch; }
    #diffs[data-mr] .dt .m { width: 1ch; }
    #diffs[data-mr][data-diff] .uni { display: table; }
    #diffs[data-mr][data-diff] .spl { display: none; }
    #diffs[data-mr] .fnote td { padding-inline: 0; }
    #diffs[data-mr] :is(.cform, .cmt) { width: min(65ch, calc(100vw - 5rem)); max-width: calc(100vw - 5rem); overflow-wrap: anywhere; }
    body:has(#diffs[data-mr]) :is(input, textarea, select) { font-size: 16px; }
    body:has(#diffs[data-mr]) .f-btns { flex-wrap: wrap; }
    body:has(#diffs[data-mr]) .menu .menu-pop {
      position: fixed; inset: auto 0 0; width: auto; max-width: 100%;
      max-height: 75dvh; overflow-y: auto; border-radius: var(--r) var(--r) 0 0;
      padding-bottom: max(var(--s4), env(safe-area-inset-bottom));
    }
    body:has(#diffs[data-mr]) .mr-bar { position: static; }
    /* A wrapping toolbar has no reliable fixed sticky height. */
    body:has(#diffs[data-mr]) { --bar-h: 0px; }
  }

  @media (pointer: coarse), (hover: none) {
    .mr-touch-range { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
    /* Real, disjoint cells: never expand invisible targets into other lines
       or into the neighbouring old/new gutter. */
    #diffs[data-mr] .dt { line-height: max(var(--lh-code), 40px); }
    #diffs[data-mr] .dt .ln { width: max(calc(var(--lnw) + .5ch), 40px); min-width: 40px; padding: 0; }
    #diffs[data-mr] .spl .c-ln { width: max(calc(var(--lnw) + .5ch), 40px); }
    #diffs[data-mr] .ln a { display: block; width: 100%; min-height: 40px; text-align: center; text-decoration: underline; }
    .mr-touch-range[hidden] { display: none; }
    #diffs[data-mr] .ln a[data-range-start] { outline: 2px solid var(--focus); background: var(--sel); }
    body:has(#diffs[data-mr]) :is(.cform .btn, .menu .btn, .mr-touch-range .btn, .c-act button) { min-height: 40px; height: auto; padding-block: var(--s2); }
    #diffs[data-mr] .cform { scroll-margin-block: calc(var(--hdr-h) + 12px); }
    .mr-footer [data-mr-tabs] button { display: inline-flex; align-items: center; min-height: 40px; }
  }
}
