/*
 * The landing page's stylesheet, and the only one it loads.
 *
 * The palette is the playground's, which is GitHub's, so the two pages read as
 * one site. Every pair here clears WCAG AA in both themes — computed by
 * `tests/contrast.test.ts` over every token in every theme, rather than
 * measured by hand once. The hand measurement had drifted: three light-theme
 * colours were below 4.5:1 on `--panel-2`, one of them `--accent`, which is
 * what the theme toggle paints itself when it is on.
 *
 * Dark is the default and light is the media query, matching the playground.
 * `[data-theme]` on the root wins over both, which is what the toggle sets.
 */

/*
 * `--border` separates things; `--field` is the edge of a control.
 *
 * They are two tokens because WCAG 2.2 asks two different things of them.
 * A rule between table cells is decoration and 1.4.11 does not reach it. The
 * outline of a text input is the only thing that says a text input is there,
 * and 1.4.11 requires 3:1 against what is behind it — `--border` is 1.45:1 in
 * the light theme, so the documentation search read as a faint rectangle on
 * forty-five pages. `--field` clears 3:1 on all three surfaces a control sits
 * on, in both themes; `tests/contrast.test.ts` computes that rather than
 * trusting this sentence.
 */
:root {
  --bg: #0d1117;
  --panel: #161b22;
  --panel-2: #1c2128;
  --border: #30363d;
  --field: #6e7681;
  --text: #e6edf3;
  --muted: #8b949e;
  --accent: #58a6ff;
  --ok: #3fb950;
  --error: #f85149;
  --kw: #ff7b72;
  --str: #a5d6ff;
  --num: #79c0ff;
  --com: #8b949e;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, Helvetica,
    Arial, sans-serif;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #ffffff;
    --panel: #f6f8fa;
    --panel-2: #eaeef2;
    --border: #d0d7de;
    --field: #7d8590;
    --text: #1f2328;
    --muted: #59636e;
    --accent: #0860ca;
    --ok: #116329;
    --error: #cf222e;
    --kw: #cf222e;
    --str: #0a3069;
    --num: #0550ae;
    --com: #59636e;
  }
}

:root[data-theme="light"] {
  --bg: #ffffff;
  --panel: #f6f8fa;
  --panel-2: #eaeef2;
  --border: #d0d7de;
  --field: #7d8590;
  --text: #1f2328;
  --muted: #59636e;
  --accent: #0860ca;
  --ok: #116329;
  --error: #cf222e;
  --kw: #cf222e;
  --str: #0a3069;
  --num: #0550ae;
  --com: #59636e;
}

:root[data-theme="dark"] {
  --bg: #0d1117;
  --panel: #161b22;
  --panel-2: #1c2128;
  --border: #30363d;
  --field: #6e7681;
  --text: #e6edf3;
  --muted: #8b949e;
  --accent: #58a6ff;
  --ok: #3fb950;
  --error: #f85149;
  --kw: #ff7b72;
  --str: #a5d6ff;
  --num: #79c0ff;
  --com: #8b949e;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* The page must never scroll sideways. On `body` alone this does nothing when
   the overflow comes from a flex row inside the header: the scrollbar appears
   on the root element, which `body` cannot suppress. Measured on 2026-08-07 at
   34px over on a 360px screen. */
html,
body {
  overflow-x: hidden;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.65 var(--sans);
}

a {
  color: var(--accent);
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 10;
  padding: 0.5rem 0.75rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
}

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

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem clamp(1rem, 5vw, 4rem);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.wordmark {
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  color: var(--text);
  text-decoration: none;
}

.top nav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

/* WCAG 2.5.8: a target is at least 24px. The audit found the playground's
   header links at 20. */
.top nav a,
.top nav button {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  font-size: 0.95rem;
}

/*
 * On a narrow screen the navigation gets a row of its own.
 *
 * `flex-wrap` alone keeps it beside the wordmark until it does not fit, and
 * "does not fit" arrives as a horizontal scrollbar rather than as a wrap when
 * one of the items cannot break. Adding a fifth link tipped the header over at
 * 360px; giving the navigation the full width makes the behaviour the same at
 * every size below the breakpoint instead of depending on where the items land.
 */
@media (max-width: 40rem) {
  .top {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
  }

  .top nav {
    width: 100%;
    flex-wrap: wrap;
    gap: 0.7rem;
    row-gap: 0.5rem;
  }
}

.ghost {
  background: none;
  border: 1px solid var(--field);
  border-radius: 6px;
  color: var(--text);
  padding: 0.2rem 0.6rem;
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
}

.ghost:hover {
  background: var(--panel-2);
}

/* A toggle that is on looks on. `aria-pressed` tells a screen reader which
   theme is active; this is the same fact for everybody else, and without it
   the control is exactly as mute as the "Theme" label it replaced. */
.ghost[aria-pressed="true"] {
  background: var(--panel-2);
  border-color: var(--accent);
  color: var(--accent);
}

/* ------------------------------------------------------------------ hero */

main {
  max-width: 68rem;
  margin: 0 auto;
  padding: 0 clamp(1rem, 5vw, 4rem);
}

.hero {
  padding: clamp(2.5rem, 8vw, 5rem) 0 clamp(2rem, 5vw, 3rem);
}

h1 {
  font-size: clamp(1.9rem, 5vw, 3rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0 0 1rem;
  max-width: 24ch;
}

.lede {
  font-size: clamp(1.05rem, 2vw, 1.2rem);
  color: var(--text);
  max-width: 62ch;
  margin: 0 0 1.75rem;
}

.cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.75rem;
}

.button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1.15rem;
  border: 1px solid var(--field);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}

.button:hover {
  background: var(--panel-2);
}

.button--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.button--primary:hover {
  filter: brightness(1.08);
  background: var(--accent);
}

.caveat {
  border-left: 3px solid var(--border);
  padding-left: 0.9rem;
  color: var(--muted);
  max-width: 62ch;
  margin: 0;
}

.caveat strong {
  color: var(--text);
}

/* ----------------------------------------------------------------- bands */

.band {
  padding: clamp(2.5rem, 6vw, 4rem) 0;
  border-top: 1px solid var(--border);
}

.band--alt {
  /* A tint rather than a block, so the page reads as one column of content
     and the bands are rhythm rather than boxes. */
  background:
    linear-gradient(var(--panel), var(--panel)) padding-box,
    none;
  margin: 0 calc(clamp(1rem, 5vw, 4rem) * -1);
  padding-left: clamp(1rem, 5vw, 4rem);
  padding-right: clamp(1rem, 5vw, 4rem);
}

h2 {
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  letter-spacing: -0.015em;
  margin: 0 0 0.5rem;
}

.section-lede {
  color: var(--muted);
  max-width: 62ch;
  margin: 0 0 1.75rem;
}

.band p {
  max-width: 68ch;
}

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

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 0 0 1.5rem;
}

/* A squeezed split is unreadable well before it is narrow. Stack early. */
@media (max-width: 56rem) {
  .split {
    grid-template-columns: 1fr;
  }
}

/*
 * A split holding generated COBOL does not get a column. It gets the page.
 *
 * F13, measured: at 1280px each column is 470px and the rounding sample is
 * 624px, so a quarter of the widest line sat behind an inner scrollbar — and
 * the lines that were cut were `WHEN FUNCTION ABS (BANK-RND-1-EXCESS) > 0.005`
 * and the `ADD` under it, which are the banker's-rounding arithmetic the
 * section titled "The COBOL it produces" exists to show. An 80-column language
 * in a 59-character box.
 *
 * Stacked rather than scrolled, because the reader who matters here is the
 * mainframe engineer deciding whether the output is acceptable, and the first
 * thing they do is read the whole line. Full width is 960px inside this
 * container, which fits a 72-column line with room to spare. `overflow-x` on
 * `pre` stays for the phone, where nothing fits.
 */
.split--code {
  grid-template-columns: 1fr;
}

figure {
  margin: 0;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg);
}

figcaption {
  padding: 0.45rem 0.9rem;
  background: var(--panel-2);
  border-bottom: 1px solid var(--border);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

pre {
  margin: 0;
  padding: 0.9rem;
  /* Code is the one thing allowed to scroll sideways, and only inside its own
     box. */
  overflow-x: auto;
  font: 13px/1.55 var(--mono);
  tab-size: 4;
}

code {
  font-family: var(--mono);
}

/* Diagnostics are prose, not code with significant columns. Wrapping them
   beats 880px of sideways scrolling on the most important block of the page. */
.diagnostics {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.diagnostics code {
  color: var(--error);
}

.c-kw {
  color: var(--kw);
}
.c-str {
  color: var(--str);
}
.c-num {
  color: var(--num);
}
.c-com {
  color: var(--com);
  font-style: italic;
}

/* A link that ends a section is a standalone target, not one inside a
   sentence, so WCAG 2.5.8's inline exception does not cover it. Padding rather
   than a min-height, which does nothing to an inline box. */
.more {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
}

.more a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

p code {
  background: var(--panel-2);
  border-radius: 4px;
  padding: 0.1em 0.35em;
  font-size: 0.9em;
}

/* ---------------------------------------------------------------- limits */

.limits {
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem;
  display: grid;
  gap: 0.9rem;
  max-width: 68ch;
}

.limits li {
  border-left: 3px solid var(--border);
  padding-left: 0.9rem;
  color: var(--muted);
}

.limits strong {
  color: var(--text);
}

/* ---------------------------------------------------------------- footer */

.foot {
  border-top: 1px solid var(--border);
  margin-top: 3rem;
  padding: 2rem clamp(1rem, 5vw, 4rem);
  text-align: center;
  font-size: 0.9rem;
}

.foot p {
  margin: 0.35rem 0;
}

.foot a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

.muted {
  color: var(--muted);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
