/*
  The entire stylesheet — documented because accounting is the house style:
  max-width for the 1180px container, font family/size, spacing, and a
  color-scheme hint so the browser's own light/dark defaults carry the theme.
  No colors by hand, no flexbox, no grid, no shadows.
  Tables, <details>, <pre> and HTML elements carry the layout.

  Two typefaces, both honest: Manrope (self-hosted, OFL) for reading, and the
  system monospace stack for everything that acts like a terminal — code,
  keys, nav brackets, the ticker, and the ASCII masthead in <pre>.
*/
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  /* The full variable font (OFL, from the foundry download — see
     static/fonts/OFL.txt), woff2-compressed: every glyph Manrope has,
     nothing fetched from a font CDN. Glyphs it lacks (●, █) fall back
     per-character to the stacks below. */
  src: url("fonts/manrope-var.woff2") format("woff2");
}
:root             { --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
                    color-scheme: light dark; }
body              { max-width: 1180px; margin: 0 auto; padding: 0 24px;
                    font-family: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
                    font-size: 16px; line-height: 1.55; font-optical-sizing: auto; }
/* Terminal chrome stays monospace: code, keys, the bracket nav, the ticker
   (its text is drawn by .ticker-copy's pseudo-elements, so it inherits this). */
pre, code, kbd, nav, .ticker-copy { font-family: var(--mono); }
html[data-theme="dark"]  { color-scheme: dark;  background: #1c1a17; color: #e8e4dc; }
html[data-theme="light"] { color-scheme: light; background: #f7f5f2; color: #1f1d1a; }
/* The theme toggle is a button drawn as a text link — same size, same color. */
button.link       { background: none; border: none; padding: 0; font: inherit;
                    color: LinkText; text-decoration: underline; cursor: pointer; }
table             { border-collapse: collapse; }
th, td            { padding: 6px 14px; }
th                { text-align: left;
                    background: light-dark(#eae6df, #2a2721); }
section, article  { margin: 56px 0; }
pre               { overflow-x: auto; }
summary           { cursor: pointer; }
dd                { margin-bottom: 14px; }
details           { margin-bottom: 20px; }
details details   { margin-bottom: 0; }

/* Cells that hold a date or a step code must not wrap — a broken "2026-11-05"
   or "audience-auth" reads as two values, not one. */
td time, td > code { white-space: nowrap; }
progress          { width: 110px; vertical-align: middle; }
h3                { margin-top: 40px; }

/* Markdown bodies: tables have no border attribute, so give them the same
   hairline the hand-built tables get from border="1" — currentColor, so it
   follows whatever theme the reader's agent is in. */
.post-body table th, .post-body table td { border: 1px solid; }
.post-body pre      { padding: 12px 14px; }
img                 { max-width: 100%; height: auto; }
.mobile-label       { display: none; }
fieldset            { min-inline-size: 0; }

/* The status ticker: the old <marquee>, rebuilt as a sliding track so it can
   stop for readers who ask for less motion. The text is written once in
   data-ticker; the two pseudo-elements draw the two identical copies the
   loop needs, and the track slides exactly one copy's width (-50%). Each
   copy is at least 64ch so even a short ticker scrolls instead of gapping. */
.ticker             { overflow: hidden; }
.ticker-track       { display: inline-block; white-space: nowrap;
                      animation: ticker-slide 50s linear infinite; }
.ticker-copy        { display: inline-block; }
.ticker-copy::before,
.ticker-copy::after { content: attr(data-ticker); display: inline-block;
                      min-width: 64ch; }
@keyframes ticker-slide { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .ticker         { overflow-x: auto; }
  .ticker-track   { animation: none; }
}

/* Phones and small tablets: tables scroll sideways instead of shrinking their
   cells into wraps; the masthead's two cells stack on the narrowest screens. */
@media (max-width: 860px) {
  body             { padding: 0 14px; }
  section, article { margin: 40px 0; }
  table            { display: block; overflow-x: auto; }
  th, td           { padding: 6px 10px; }
  th, td           { vertical-align: top; }
  /* Keep comparison columns readable; wide tables scroll inside the page.
     A pinned prose column used to cover neighbouring cells while scrolling. */
  .post-body th, .post-body td { min-width: 8ch; }
}
/* Descriptive homepage rows need the phone's full width. Keep the real column
   headers available to assistive technology and repeat visible labels per row.
   No script or second copy of the data is needed. */
@media (max-width: 680px) {
  .mobile-records, .mobile-records tbody, .mobile-records tr,
  .mobile-records td { display: block; width: auto; }
  .mobile-records { border: 0; overflow: visible; }
  .mobile-records thead { position: absolute; width: 1px; height: 1px;
                         padding: 0; overflow: hidden; clip-path: inset(50%); }
  .mobile-records tr { margin-bottom: 14px; border: 1px solid; }
  .mobile-records td { border: 0; text-align: left; overflow-wrap: anywhere; }
  .mobile-records .mobile-label { display: inline; font-weight: bold; }
}
@media (max-width: 560px) {
  header table, header tbody, header tr, header td { display: block; }
  header td        { position: static; }
  h1               { font-size: 1.6em; }
  /* Multi-word step codes wrap on phones; dates still never break. */
  td > code        { white-space: normal; }
}
