@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
}

:root {
  --bg: #FAFAF8;
  --fg: #17181A;
  --cell: 8px;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* #5C6166 measures 5.99:1 on --bg, clearing the 4.5:1 floor it is used
     at (captions, footer text) -- see scripts/contrast-check.sh. */
  --muted: #5C6166;
  --rule: rgba(23, 24, 26, 0.15);

  /* State colors -- the Nagios exit-code vocabulary (OK/WARNING/CRITICAL/
     UNKNOWN/PENDING), never the board's wood tones. Rule: a state is never
     carried by color alone -- always the color AND the word, set in the
     mono face. The transcript, the diagram and the status table all sit on
     the page ground, so the tokens are per-theme: this set clears 4.5:1 on
     paper, the dark overrides clear 4.5:1 on graphite -- see
     scripts/contrast-check.sh. */
  --jq-state-ok: #14764F;
  --jq-state-warning: #8A5A00;
  --jq-state-critical: #C8102C;
  --jq-state-unknown: #6D3FD6;
  --jq-state-pending: #5A6675;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #101214;
    --fg: #E8EAED;
    /* #9AA0A6 measures 7.11:1 on --bg -- see scripts/contrast-check.sh. */
    --muted: #9AA0A6;
    --rule: rgba(232, 234, 237, 0.15);
    --jq-state-ok: #259563;
    --jq-state-warning: #B57515;
    --jq-state-critical: #EF3E58;
    --jq-state-unknown: #916AEE;
    --jq-state-pending: #75849B;
  }
}

* {
  box-sizing: border-box;
}

html {
  background: var(--bg);
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.55;
  /* An RFC page is 72 columns of monospace; 72ch plus the 3ch body indent,
     the 3ch a figure frame spends on its own padding, and a little air. ch
     here tracks the mono face the whole page is set in, so the widest pre
     (the status table and the transcript, 72 chars) exactly fits. */
  max-width: calc(79ch + 2rem);
  margin: 0 auto;
  padding: 2.5rem 1rem 4rem;
}

a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

a:hover {
  background: var(--fg);
  color: var(--bg);
  text-decoration: none;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 2px;
}

code {
  font-family: inherit;
}

/* Document header: RFC letterhead -- metadata left, mark and date right,
   then the centered title block. */
.meta {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 2rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--rule);
}

.meta p {
  margin: 0;
  line-height: 1.7;
}

.meta-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

.meta-right .rook {
  margin-bottom: 0.75rem;
}

h1 {
  font-size: 1rem;
  font-weight: 500;
  text-align: center;
  letter-spacing: 0.01em;
  margin: 3rem 0 0.75rem;
}

.subtitle,
.tagline {
  text-align: center;
  margin: 0;
  color: var(--muted);
}

.tagline {
  margin-top: 1.5rem;
  color: var(--fg);
}

h2 {
  font-size: inherit;
  font-weight: 500;
  margin: 3rem 0 1rem;
}

h3 {
  font-size: inherit;
  font-weight: 500;
  margin: 2rem 0 1rem 0;
}

section {
  margin: 0;
}

/* RFC body text is indented three columns under its heading. */
main p,
main pre,
main ul {
  margin-left: 3ch;
}

main p {
  max-width: 72ch;
  margin-top: 0;
  margin-bottom: 1rem;
}

main pre {
  font-family: inherit;
  font-size: inherit;
  line-height: 1.55;
  margin-top: 1.25rem;
  margin-bottom: 0.5rem;
  overflow-x: auto;
}

/* The contents are a numbered list, so they are one. The section numbers
   come from counters() rather than being typed into the markup a second
   time, and the entries wrap on a narrow screen instead of scrolling. */
ol.toc,
ol.toc ol {
  list-style: none;
  counter-reset: toc;
  padding: 0;
  margin: 0 0 0 3ch;
}

ol.toc li {
  counter-increment: toc;
}

ol.toc li::before {
  content: counters(toc, ".") ".";
  display: inline-block;
  width: 4ch;
  color: var(--muted);
}

ol.toc ol li::before {
  width: 6ch;
}

ol.toc a {
  text-decoration: none;
}

ol.toc a:hover {
  background: var(--fg);
  color: var(--bg);
}

/* The status table is a table. It used to be ASCII at a fixed 72 columns
   that nothing narrower could reflow; these are the same rules the +---+
   drew, drawn by the markup, one under every row. */
table.status {
  border-collapse: collapse;
  border-top: 1px solid var(--rule);
  margin: 1.25rem 0 1rem 3ch;
}

table.status th,
table.status td {
  text-align: left;
  font-weight: 400;
  vertical-align: top;
  padding: 0.35rem 2ch 0.35rem 0;
  border-bottom: 1px solid var(--rule);
  overflow-wrap: anywhere;
}

table.status th {
  color: var(--muted);
}

/* The state column shrinks to its widest state word so the capability
   column gets the rest; without it the browser splits the two-word states
   across lines. */
table.status th:last-child,
table.status td:last-child {
  width: 1%;
  white-space: nowrap;
}

/* The roadmap's hyphen was a typed character in a <pre>; it is a marker. */
ul.roadmap {
  list-style: none;
  padding-left: 3ch;
}

ul.roadmap li::before {
  content: "- ";
  color: var(--muted);
}

/* A figure is the one thing on the page that is not running text, so it is
   the one thing that gets a frame. The frame belongs to the figure, drawn
   once: two stacked boxes each drawing their own left border left a visible
   seam wherever the layout landed on a half pixel. Nothing is tinted -- the
   state colors are calibrated against the page ground itself, and a panel
   behind them would invalidate that. */
main figure {
  border: 1px solid var(--rule);
  margin: 1.25rem 0 2rem 3ch;
}

main figure pre {
  margin: 0;
  padding: 0.75rem 1.5ch;
}

/* The caption is the figure's label, not a second sentence: it sits a step
   below body size and starts at the frame's own left edge. Centered at body
   size it measured wider than the drawing above it and read as the heavier
   of the two. */
figcaption {
  border-top: 1px solid var(--rule);
  padding: 0.4rem 1.5ch;
  font-size: 0.8125rem;
  color: var(--muted);
}

/* The pipeline drawing is the same asset the docs serve, inlined because the
   landing has no build step. Its fills and strokes are class hooks, never
   baked hex, so one drawing serves both themes off the tokens above. Sizes
   are in user units: the 760-wide viewBox scales down to the measure, so
   they are set above the body size to land near it. */
.diagram {
  padding: 0.75rem 1.5ch;
  overflow-x: auto;
}

/* Below the floor the labels shrink past legibility, so the drawing scrolls
   inside its own frame the way the transcript does rather than getting
   smaller. */
.diagram svg {
  display: block;
  width: 100%;
  min-width: 460px;
  height: auto;
}

.diagram svg text {
  font-family: var(--font-mono);
  fill: var(--fg);
  text-anchor: middle;
  font-size: 17px;
}

.diagram svg .caption,
.diagram svg .annotation,
.diagram svg .foreign {
  fill: var(--muted);
  font-size: 14px;
}

.diagram svg .box,
.diagram svg .infra {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1;
}

/* Zero radius is the page's, not the drawing's: the asset carries rx for the
   docs and it is overridden here rather than forked. Only the rects -- on an
   ellipse rx is the radius itself, and zeroing it erases the shape. */
.diagram svg rect {
  rx: 0;
}

.diagram svg .box.owner {
  stroke: var(--muted);
}

.diagram svg .box.owner.ghost {
  stroke-dasharray: 4 3;
  opacity: 0.5;
}

.diagram svg .connector {
  fill: none;
  stroke: var(--muted);
}

.diagram svg .connector.dashed {
  stroke-dasharray: 4 3;
}

.diagram svg .arrowhead {
  fill: var(--muted);
}

.state.ok {
  color: var(--jq-state-ok);
}

.state.critical {
  color: var(--jq-state-critical);
}

.state.warning {
  color: var(--jq-state-warning);
}

.state.unknown {
  color: var(--jq-state-unknown);
}

.state.pending {
  color: var(--jq-state-pending);
}

/* The transcript's longest line is 72 characters, which is exactly the page
   measure -- anything narrower and it used to scroll sideways inside its own
   frame. Wrapping is the lesser evil: a horizontal scrollbar hides the end of
   the sentence behind a gesture nobody makes. */
pre.terminal {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* The replay: lines are visible by default (the static page and the
   finished state are the same thing); while a replay runs the terminal
   carries .playing and lines appear as the player reveals them. */
pre.terminal.playing .line {
  opacity: 0;
}

pre.terminal.playing .line.show {
  opacity: 1;
}

.cursor {
  display: inline-block;
  width: 0.55em;
  height: 1em;
  margin-left: 1px;
  background: currentColor;
  vertical-align: text-bottom;
  animation: cursor-blink 1s steps(1) infinite;
}

@keyframes cursor-blink {
  50% {
    opacity: 0;
  }
}

.replay-again {
  font: inherit;
  color: var(--muted);
  background: none;
  border: none;
  padding: 0;
  margin-left: 1ch;
  cursor: pointer;
}

.replay-again:hover {
  background: var(--fg);
  color: var(--bg);
}

.rook {
  display: grid;
  grid-template-columns: repeat(7, var(--cell));
  grid-template-rows: repeat(7, var(--cell));
  gap: 1px;
  flex: none;
}

.c {
  width: var(--cell);
  height: var(--cell);
  background: transparent;
  border-radius: 0;
}

.c.on {
  background: var(--fg);
}

footer {
  margin-top: 4rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2rem;
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.rook-sm {
  --cell: 6px;
}

.footer-word {
  font-weight: 500;
  margin: 0;
}

.ipa {
  color: var(--muted);
  margin: 0;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 3rem;
}

.footer-group h2 {
  color: var(--muted);
  margin: 0 0 0.5rem;
}

.footer-group ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-group li {
  margin: 0.25rem 0;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  color: var(--muted);
}

.footer-bottom p {
  margin: 0;
}

/* 404.html shares this stylesheet and the letterhead structure; its .links
   strip is the one element of its own. */
.links {
  margin: 2rem 0;
  text-align: center;
}

@media (max-width: 560px) {
  body {
    font-size: 0.8125rem;
  }

  .meta {
    flex-direction: column-reverse;
    gap: 1.25rem;
  }

  .meta-right {
    align-items: flex-start;
    text-align: left;
  }

  h1 {
    margin-top: 2rem;
  }

  /* A phone cannot afford the state column its widest word: held to one
     line it pushes the table past the viewport and the whole page scrolls
     sideways. Let it wrap there instead. */
  table.status th:last-child,
  table.status td:last-child {
    width: auto;
    white-space: normal;
  }
}
