/* ==========================================================
   components.css — All interface components
   Header, sidebar/drawer, table of contents, page header,
   badges, TL;DR, callouts, code blocks, check-yourself,
   related, pager, footer, home page, topic overview,
   glossary, search palette and results, term tooltips.

   Uses only the custom properties from tokens.css.
   Design rules: 1px hairlines, no shadows, no gradients,
   square corners (--radius), separation by white space.
   A topic's accent color arrives as --accent.

   CUSTOMIZE HERE:
   - Colors, fonts, spacing: tokens.css, not here.
   - Callout labels: set in the HTML of each page.
   ========================================================== */

/* ==========================================================
   Icons and small controls
   ========================================================== */

.icon {
  width: 1.25rem;
  height: 1.25rem;
}

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--color-ink);
  transition: background-color var(--duration) var(--ease);
}

.icon-button:hover {
  background: var(--color-surface);
}

.badge,
.tag:not(.token) {
  display: inline-flex;
  align-items: center;
  padding: 0.05rem 0.5rem;
  border: var(--line) solid var(--color-line-soft);
  border-radius: var(--radius);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

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

/* Certification and topic tags carry the topic accent. Prism also marks
   HTML tags in code as .tag (with .token), so those are excluded. */
.tag:not(.token) {
  border-color: var(--accent);
  color: var(--accent);
}

.chip {
  padding: 0.3rem 0.8rem;
  border: var(--line) solid var(--color-line-soft);
  border-radius: var(--radius);
  background: transparent;
  font-size: var(--text-sm);
  transition:
    border-color var(--duration) var(--ease),
    background-color var(--duration) var(--ease);
}

.chip:hover {
  border-color: var(--color-ink);
}

.chip[aria-pressed="true"] {
  border-color: var(--color-ink);
  background: var(--color-ink);
  color: var(--color-bg);
}

.field {
  width: 100%;
  padding: 0.6rem 0.8rem;
  border: var(--line) solid var(--color-line-soft);
  border-radius: var(--radius);
  background: var(--color-bg);
  transition: border-color var(--duration) var(--ease);
}

.field:hover,
.field:focus {
  border-color: var(--color-ink);
}

.field::placeholder {
  color: var(--color-faint);
}

/* ==========================================================
   Header
   ========================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--color-bg);
  border-bottom: var(--line) solid var(--color-line-soft);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: var(--header-height);
}

.brand {
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
  min-width: 0;
  margin-right: auto;
  font-family: var(--font-heading);
  font-variation-settings:
    "SOFT" var(--heading-soft),
    "WONK" var(--heading-wonk);
  font-size: 1.25rem;
  line-height: 1;
  white-space: nowrap;
}

.brand a {
  text-decoration: none;
}

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

.brand__topic {
  overflow: hidden;
  text-overflow: ellipsis;
  /* overflow: hidden clips at the line box; with line-height 1 that cut off
     descenders such as g. Room below the baseline, without moving it: */
  padding-bottom: 0.2em;
  margin-bottom: -0.2em;
}

.site-nav {
  display: none;
  gap: var(--space-md);
  font-size: var(--text-sm);
}

.site-nav a {
  color: var(--color-muted);
  text-decoration: none;
}

.site-nav a:hover {
  color: var(--color-ink);
}

@media (min-width: 48rem) {
  .site-nav {
    display: flex;
  }
}

.search-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  height: 2.5rem;
  padding: 0 var(--space-2xs);
  border: var(--line) solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--color-muted);
  font-size: var(--text-sm);
  transition:
    border-color var(--duration) var(--ease),
    color var(--duration) var(--ease);
}

.search-trigger:hover {
  color: var(--color-ink);
}

.search-trigger__label,
.search-trigger__kbd {
  display: none;
}

@media (min-width: 40rem) {
  .search-trigger {
    min-width: 12rem;
    padding: 0 var(--space-xs);
    border-color: var(--color-line-soft);
  }

  .search-trigger:hover {
    border-color: var(--color-ink);
  }

  .search-trigger__label {
    display: inline;
    margin-right: auto;
  }

  .search-trigger__kbd {
    display: inline-block;
  }
}

/* Theme toggle: moon in light mode, sun in dark mode */
.theme-toggle__sun {
  display: none;
}

:root[data-theme="dark"] .theme-toggle__sun {
  display: block;
}

:root[data-theme="dark"] .theme-toggle__moon {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__sun {
    display: block;
  }

  :root:not([data-theme="light"]) .theme-toggle__moon {
    display: none;
  }
}

/* The menu button only exists below the tablet breakpoint */
@media (min-width: 56rem) {
  .site-header__menu {
    display: none;
  }
}

/* Region switch: a native <select> (keyboard and screen readers for free),
   quiet like the search trigger, with a drawn chevron. */
.region-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  color: var(--color-muted);
  transition: color var(--duration) var(--ease);
}

.region-switch:hover {
  color: var(--color-ink);
}

.region-switch__select {
  height: 2.5rem;
  padding: 0 1.5rem 0 var(--space-2xs);
  border: var(--line) solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  appearance: none;
  transition: border-color var(--duration) var(--ease);
}

.region-switch__select:hover {
  border-color: var(--color-line-soft);
}

.region-switch__select option {
  background: var(--color-bg);
  color: var(--color-ink);
}

.region-switch__chevron {
  position: absolute;
  right: var(--space-3xs);
  width: 1rem;
  height: 1rem;
  pointer-events: none;
}

/* Phones: one more control in the header, so a little less room around it */
@media (max-width: 39.99rem) {
  .site-header__inner {
    gap: var(--space-2xs);
  }

  .region-switch__select {
    padding: 0 1.25rem 0 var(--space-3xs);
    font-size: var(--text-xs);
  }

  .region-switch__chevron {
    right: 0.125rem;
  }
}

/* ==========================================================
   Sidebar (topic navigation) and drawer
   ========================================================== */

.sidebar {
  font-size: var(--text-sm);
}

.sidebar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-sm);
}

.sidebar__topic {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-heading);
  font-variation-settings:
    "SOFT" var(--heading-soft),
    "WONK" var(--heading-wonk);
  font-size: 1.2rem;
  text-decoration: none;
}

.sidebar__topic .icon {
  color: var(--accent);
}

.sidebar__topic[aria-current="page"] {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
  text-underline-offset: 0.25em;
}

.sidebar__list {
  list-style: none;
  padding: 0;
}

.sidebar__list a {
  display: flex;
  gap: var(--space-xs);
  padding: 0.3rem 0 0.3rem var(--space-xs);
  border-left: var(--line) solid var(--color-line-soft);
  color: var(--color-muted);
  line-height: 1.4;
  text-decoration: none;
  transition:
    color var(--duration) var(--ease),
    border-color var(--duration) var(--ease);
}

.sidebar__list a:hover {
  color: var(--color-ink);
  border-left-color: var(--color-ink);
}

.sidebar__list a[aria-current="page"] {
  border-left: var(--rule-accent) solid var(--accent);
  padding-left: calc(var(--space-xs) - var(--rule-accent) + var(--line));
  color: var(--color-ink);
  font-weight: 600;
}

.sidebar__num {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.75;
  color: var(--color-muted);
  font-weight: 400;
}

.sidebar__close {
  display: none;
}

/* The copy of "On this page" inside the sidebar: small screens only */
.sidebar__toc {
  margin-top: var(--space-lg);
}

@media (min-width: 72rem) {
  .sidebar__toc {
    display: none;
  }
}

/* Desktop: sidebar sticks below the header */
@media (min-width: 56rem) {
  .sidebar__inner {
    position: sticky;
    top: calc(var(--header-height) + var(--space-lg));
    max-height: calc(100vh - var(--header-height) - var(--space-xl));
    overflow-y: auto;
    padding-right: var(--space-2xs);
  }
}

/* Small screens: sidebar becomes an off-canvas drawer */
@media (max-width: 55.99rem) {
  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 40;
    width: min(20rem, 85vw);
    padding: var(--space-md);
    overflow-y: auto;
    background: var(--color-bg);
    border-right: var(--line) solid var(--color-line);
    visibility: hidden;
    transform: translateX(-100%);
    transition:
      transform var(--duration) var(--ease),
      visibility 0s linear var(--duration);
  }

  .drawer-open .sidebar {
    visibility: visible;
    transform: none;
    transition: transform var(--duration) var(--ease);
  }

  .sidebar__close {
    display: inline-flex;
  }
}

.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: var(--color-overlay);
}

@media (min-width: 56rem) {
  .drawer-backdrop {
    display: none;
  }
}

/* ==========================================================
   Table of contents ("On this page")
   ========================================================== */

.toc-column {
  display: none;
  font-size: var(--text-sm);
}

@media (min-width: 72rem) {
  .toc-column {
    display: block;
  }

  .toc-column__inner {
    position: sticky;
    top: calc(var(--header-height) + var(--space-lg));
    max-height: calc(100vh - var(--header-height) - var(--space-xl));
    overflow-y: auto;
  }
}

.toc__title {
  margin-bottom: var(--space-2xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.toc__list {
  list-style: none;
  padding: 0;
}

.toc__item a {
  display: block;
  padding: 0.2rem 0 0.2rem var(--space-xs);
  border-left: var(--line) solid var(--color-line-soft);
  color: var(--color-muted);
  line-height: 1.4;
  text-decoration: none;
  transition:
    color var(--duration) var(--ease),
    border-color var(--duration) var(--ease);
}

.toc__item--h3 a {
  padding-left: var(--space-md);
  font-size: var(--text-xs);
}

.toc__item a:hover {
  color: var(--color-ink);
}

.toc__item a[aria-current="true"] {
  border-left: var(--rule-accent) solid var(--accent);
  padding-left: calc(var(--space-xs) - var(--rule-accent) + var(--line));
  color: var(--color-ink);
}

.toc__item--h3 a[aria-current="true"] {
  padding-left: calc(var(--space-md) - var(--rule-accent) + var(--line));
}

/* ==========================================================
   Breadcrumb and page header
   ========================================================== */

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-2xs);
  list-style: none;
  padding: 0;
  margin-bottom: var(--space-md);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.breadcrumb li + li::before {
  content: "›";
  margin-right: var(--space-2xs);
  color: var(--color-faint);
}

.breadcrumb a {
  color: inherit;
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--color-ink);
  text-decoration: underline;
}

.breadcrumb [aria-current] {
  color: var(--color-ink);
}

.page-header {
  margin-bottom: var(--space-lg);
}

.page-header h1 {
  max-width: 20ch;
}

.lead {
  margin-top: var(--space-sm);
  font-size: var(--text-lead);
  line-height: 1.5;
  color: var(--color-muted);
}

.page-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: var(--space-md);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.page-meta:empty {
  display: none;
}

.page-meta__date,
.page-meta__time {
  margin-right: var(--space-2xs);
}

/* ==========================================================
   Headings with anchor links
   ========================================================== */

.content h2,
.content h3 {
  position: relative;
}

.heading-anchor {
  margin-left: 0.35em;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--color-faint);
  text-decoration: none;
  opacity: 0;
  transition: opacity var(--duration) var(--ease);
}

.content h2:hover .heading-anchor,
.content h3:hover .heading-anchor,
.heading-anchor:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  .heading-anchor {
    opacity: 0.6;
  }
}

/* ==========================================================
   TL;DR
   ========================================================== */

.tldr {
  padding: var(--space-md);
  border: var(--line) solid var(--color-line);
  border-radius: var(--radius);
}

.tldr__label {
  margin-bottom: var(--space-2xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.tldr ul {
  padding-left: 1.2em;
}

/* ==========================================================
   Callouts: note, tip, warning, exam-tip, common-mistake
   Told apart by label and line style, not by color —
   except exam-tip, which uses the topic accent.
   ========================================================== */

.callout {
  padding: var(--space-xs) 0 var(--space-xs) var(--space-md);
  border-left: var(--line) solid var(--color-line);
}

.callout > * + * {
  margin-top: var(--space-2xs);
}

.callout__label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.callout--note {
  border-left-color: var(--color-line-soft);
}

.callout--note .callout__label {
  color: var(--color-muted);
}

.callout--warning {
  padding-right: var(--space-md);
  border: var(--line) solid var(--color-line);
}

.callout--common-mistake {
  border-left: 2px dashed var(--color-line);
}

.callout--exam-tip {
  border-left: var(--rule-accent) solid var(--accent);
}

.callout--exam-tip .callout__label {
  color: var(--accent);
}

/* ==========================================================
   Regional blocks (region switch in the header)
   <div class="regional" data-regional> with one <div data-region="eu|us|uk">
   per region. Without JavaScript all variants stack; with it, layout.js
   shows the reader's region first and puts the others in a closed
   <details class="regional__others">. Each variant carries a small
   label, drawn here so it also shows without JavaScript and in print.
   ========================================================== */

.regional {
  padding-left: var(--space-md);
  border-left: var(--line) solid var(--color-line-soft);
}

.regional > * + * {
  margin-top: var(--space-md);
}

.regional > [data-region] > * + *,
.regional__others > [data-region] > * + * {
  margin-top: var(--space-sm);
}

.regional > [data-region]::before,
.regional__others > [data-region]::before {
  display: table;
  margin-bottom: var(--space-2xs);
  padding: 0.05rem 0.5rem;
  border: var(--line) solid var(--color-line-soft);
  border-radius: var(--radius);
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.02em;
}

/* The second content value (with alternative text for screen readers)
   replaces the first where supported; older browsers keep the first. */
.regional [data-region="eu"]::before {
  content: "NL/EU";
  content: "NL/EU" / "Region: EU and the Netherlands";
}

.regional [data-region="us"]::before {
  content: "US";
  content: "US" / "Region: United States";
}

.regional [data-region="uk"]::before {
  content: "UK";
  content: "UK" / "Region: United Kingdom";
}

.regional__others > summary {
  display: flex;
  gap: var(--space-xs);
  width: fit-content;
  color: var(--color-muted);
  font-size: var(--text-sm);
  cursor: pointer;
  list-style: none;
  transition: color var(--duration) var(--ease);
}

.regional__others > summary:hover {
  color: var(--color-ink);
}

.regional__others > summary::-webkit-details-marker {
  display: none;
}

.regional__others > summary::before {
  content: "+";
  content: "+" / "";
  flex: 0 0 1em;
  font-family: var(--font-mono);
}

.regional__others[open] > summary::before {
  content: "−";
  content: "−" / "";
}

.regional__others > [data-region] {
  margin-top: var(--space-md);
}

/* ==========================================================
   Code blocks, output and syntax highlighting
   ========================================================== */

.content pre {
  max-width: 100%;
  padding: var(--space-sm) var(--space-md);
  overflow-x: auto;
  background: var(--code-bg);
  border-radius: var(--radius);
  color: var(--code-ink);
  line-height: 1.6;
  tab-size: 4;
}

.content pre code {
  font-size: inherit;
}

.code-block {
  position: relative;
}

.copy-button {
  position: absolute;
  top: var(--space-2xs);
  right: var(--space-2xs);
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.2rem 0.5rem;
  border: var(--line) solid var(--color-line-soft);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-muted);
  font-size: var(--text-xs);
  opacity: 0;
  transition:
    opacity var(--duration) var(--ease),
    color var(--duration) var(--ease);
}

.copy-button .icon {
  width: 0.9rem;
  height: 0.9rem;
}

.code-block:hover .copy-button,
.copy-button:focus-visible,
.copy-button.is-done {
  opacity: 1;
}

.copy-button:hover {
  color: var(--color-ink);
  border-color: var(--color-ink);
}

@media (hover: none) {
  .copy-button {
    opacity: 1;
  }
}

/* An example = a code block followed by its expected output */
.example > .output,
.example > .code-block + .output {
  margin-top: 0;
}

.content pre.output {
  background: transparent;
  border: var(--line) solid var(--color-line-soft);
  color: var(--color-ink);
}

/* Directly under its code block, the output shares that block's edge */
.example > .code-block + pre.output {
  border-top: 0;
}

/* Label above the block: "Output", or <pre class="output" data-label="…"> */
.content pre.output::before {
  content: "Output";
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content pre.output[data-label]::before {
  content: attr(data-label);
}

.content pre.output samp {
  font-size: inherit;
}

/* Language label on code that is not Python, and on pseudocode */
.content pre:has(> code.language-c)::before,
.content pre:has(> code.language-javascript)::before,
.content pre:has(> code.language-json)::before,
.content pre:has(> code.language-yaml)::before,
.content pre:has(> code.language-powershell)::before,
.content pre:has(> code.language-batch)::before,
.content pre.pseudocode::before {
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content pre:has(> code.language-c)::before {
  content: "C";
}

.content pre:has(> code.language-javascript)::before {
  content: "JavaScript";
}

.content pre:has(> code.language-json)::before {
  content: "JSON";
}

.content pre:has(> code.language-yaml)::before {
  content: "YAML";
}

.content pre:has(> code.language-powershell)::before {
  content: "PowerShell";
}

.content pre:has(> code.language-batch)::before {
  content: "Command Prompt";
}

.content pre:has(> code.language-hcl)::before,
.content pre:has(> code.language-promql)::before,
.content pre:has(> code.language-spreadsheet)::before,
.content pre:has(> code.language-docker)::before,
.content pre:has(> code.language-sql)::before {
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content pre:has(> code.language-hcl)::before {
  content: "Terraform (HCL)";
}

.content pre:has(> code.language-promql)::before {
  content: "PromQL";
}

.content pre:has(> code.language-spreadsheet)::before {
  content: "Spreadsheet";
}

.content pre:has(> code.language-markup)::before,
.content pre:has(> code.language-css)::before,
.content pre:has(> code.language-php)::before,
.content pre:has(> code.language-markdown)::before,
.content pre:has(> code.language-csharp)::before,
.content pre:has(> code.language-java)::before,
.content pre:has(> code.language-typescript)::before,
.content pre:has(> code.language-rust)::before,
.content pre:has(> code.language-toml)::before {
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content pre:has(> code.language-markup)::before {
  content: "HTML";
}

.content pre:has(> code.language-css)::before {
  content: "CSS";
}

.content pre:has(> code.language-php)::before {
  content: "PHP";
}

.content pre:has(> code.language-markdown)::before {
  content: "Markdown";
}

.content pre:has(> code.language-csharp)::before {
  content: "C#";
}

.content pre:has(> code.language-java)::before {
  content: "Java";
}

.content pre:has(> code.language-typescript)::before {
  content: "TypeScript";
}

.content pre:has(> code.language-rust)::before {
  content: "Rust";
}

.content pre:has(> code.language-toml)::before {
  content: "TOML";
}

/* Live result of an HTML/CSS example: <div class="example" data-preview>.
   page.js renders the example's HTML and CSS into a sandboxed iframe
   (no scripts, no forms, no access to this page) below the code.
   The frame shows the browser's own defaults (white canvas, black
   text), as a page without styles really looks. */
.example > .code-block + .code-block {
  margin-top: var(--space-2xs);
}

.preview {
  border: var(--line) solid var(--color-line-soft);
  border-top: 0;
  padding: var(--space-xs) var(--space-sm) var(--space-sm);
}

.preview__label {
  margin: 0 0 var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.preview__frame {
  display: block;
  width: 100%;
  border: var(--line) solid var(--color-line-soft);
}

/* Playable Three.js game: <div class="example example--game" data-game>.
   page.js puts a stage with Play / Reset above the code and moves the
   code blocks into a closed <details>. The frame is created only on
   Play (sandbox="allow-scripts", opaque origin). The game paints its
   own canvas; the stage is only a hairline box until then. */
.game {
  border: var(--line) solid var(--color-line-soft);
  padding: var(--space-xs) var(--space-sm) var(--space-sm);
}

.game__label {
  margin: 0 0 var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.game__stage {
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--line) solid var(--color-line-soft);
}

.game__message {
  margin: 0;
  padding: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.game__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.game__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin-top: var(--space-xs);
}

.game__button {
  padding: 0.2rem 0.9rem;
  border: var(--line) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-bg);
  font-size: var(--text-sm);
}

.game__button:hover {
  background: var(--color-surface);
}

.game__button:disabled {
  color: var(--color-muted);
  border-color: var(--color-line-soft);
}

.game__note {
  flex: 1 1 20rem;
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.game__code {
  margin-top: var(--space-sm);
}

.game__code > summary {
  display: flex;
  gap: var(--space-xs);
  width: fit-content;
  color: var(--color-muted);
  font-size: var(--text-sm);
  cursor: pointer;
  list-style: none;
  transition: color var(--duration) var(--ease);
}

.game__code > summary:hover {
  color: var(--color-ink);
}

.game__code > summary::-webkit-details-marker {
  display: none;
}

.game__code > summary::before {
  content: "+";
  content: "+" / "";
  flex: 0 0 1em;
  font-family: var(--font-mono);
}

.game__code[open] > summary::before {
  content: "−";
  content: "−" / "";
}

.game__code > summary + .code-block {
  margin-top: var(--space-sm);
}

.game__code > .code-block + .code-block {
  margin-top: var(--space-2xs);
}

.content pre:has(> code.language-docker)::before {
  content: "Dockerfile";
}

.content pre:has(> code.language-sql)::before {
  content: "SQL";
}

/* A runnable shell example (inside .example); terminal commands in
   pre.shell stay unlabeled, their output block carries the label */
.content .example pre:has(> code.language-bash)::before {
  content: "Bash";
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* Device configuration and CLI sessions (Cisco IOS and similar):
   <pre class="config" data-label="Cisco IOS · R1"><code>…</code></pre>
   Kept as plain text on purpose; a later version may make these
   interactive, keyed on the class and data-label. */
.content pre.config {
  border-left: var(--rule-accent) solid var(--accent);
}

.content pre.config::before {
  content: "Configuration";
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content pre.config[data-label]::before {
  content: attr(data-label);
}

/* Pseudocode: not a real language, so no background — a thin rule instead */
.content pre.pseudocode {
  background: transparent;
  border-left: var(--line) solid var(--color-line);
  border-radius: 0;
}

.content pre.pseudocode::before {
  content: "Pseudocode";
}

/* Prompts for an AI model: plain prose, so lines wrap.
   <pre class="prompt" data-label="Prompt · vague"><code>…</code></pre> */
.content pre.prompt {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  border-left: var(--rule-accent) solid var(--accent);
}

.content pre.prompt::before {
  content: "Prompt";
  display: block;
  margin-bottom: var(--space-3xs);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content pre.prompt[data-label]::before {
  content: attr(data-label);
}

/* Model answers vary from run to run: shown wrapped, never as checked output */
.content pre.output.response {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* "Try it yourself": prompts to paste into an AI assistant and compare.
   <div class="try-it"><p class="try-it__label">Try it yourself</p> … </div> */
.try-it {
  padding: var(--space-sm) var(--space-md);
  border: var(--line) solid var(--color-line);
}

.try-it > * + * {
  margin-top: var(--space-xs);
}

.try-it__label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.try-it .copy-button {
  opacity: 1;
}

/* ==========================================================
   Diagrams: <figure class="diagram"><svg>…</svg><figcaption>
   Inline SVG drawn with currentColor, so it follows light and
   dark mode. Classes inside the SVG:
     .fill-soft   light surface fill (boxes that need a fill)
     .accent      stroke/fill in the topic accent
     .muted       secondary lines and labels
   ========================================================== */

.diagram {
  max-width: var(--measure);
  margin-left: 0;
  margin-right: 0;
}

.diagram svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 28rem;
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 13px;
  overflow: visible;
}

.diagram svg text {
  fill: currentColor;
  stroke: none;
}

.diagram svg .mono {
  font-family: var(--font-mono);
}

.diagram svg .fill-soft {
  fill: var(--color-surface);
}

.diagram svg .accent {
  stroke: var(--accent);
}

.diagram svg text.accent {
  fill: var(--accent);
  stroke: none;
}

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

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

.diagram figcaption {
  margin-top: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* Quotations */
.content blockquote {
  padding-left: var(--space-md);
  border-left: var(--line) solid var(--color-line);
  font-family: var(--font-heading);
  font-variation-settings:
    "SOFT" var(--heading-soft),
    "WONK" var(--heading-wonk);
  font-size: 1.125rem;
  line-height: 1.6;
}

/* Terminal commands (language-bash): prompt-like first character */
.content pre.shell {
  border-left: var(--rule-accent) solid var(--color-line-soft);
}

/* Prism token colors, calm and mostly monochrome */
.token.comment,
.token.prolog {
  color: var(--code-comment);
  font-style: italic;
}

.token.keyword,
.token.boolean,
.token.important {
  color: var(--code-keyword);
  font-weight: 600;
}

.token.string,
.token.triple-quoted-string,
.token.char {
  color: var(--code-string);
}

.token.string-interpolation .token.interpolation {
  color: var(--code-ink);
}

.token.number {
  color: var(--code-number);
}

.token.function {
  color: var(--code-function);
}

.token.builtin,
.token.class-name,
.token.decorator {
  color: var(--code-builtin);
}

.token.operator,
.token.punctuation {
  color: var(--code-punctuation);
}

/* HTML and CSS (prism-markup, prism-css): the same calm palette */
.token.tag,
.token.selector,
.token.doctype {
  color: var(--code-keyword);
}

.token.attr-name,
.token.property {
  color: var(--code-function);
}

.token.attr-value,
.token.url {
  color: var(--code-string);
}

.token.atrule,
.token.entity {
  color: var(--code-builtin);
}

/* ==========================================================
   Glossary terms in running text + tooltip
   ========================================================== */

.term-ref {
  font-style: normal;
  text-decoration: underline dotted;
  text-decoration-thickness: var(--line);
  text-underline-offset: 0.25em;
  text-decoration-color: var(--color-muted);
  cursor: help;
}

.term-ref:hover,
.term-ref:focus-visible {
  text-decoration-color: var(--color-ink);
}

.term-tip {
  position: fixed;
  z-index: 60;
  max-width: min(22rem, calc(100vw - 1rem));
  padding: var(--space-2xs) var(--space-xs);
  background: var(--color-ink);
  color: var(--color-bg);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  line-height: 1.5;
  pointer-events: none;
}

.term-tip__name {
  font-weight: 600;
}

/* ==========================================================
   Check yourself
   ========================================================== */

.check-yourself details {
  border-top: var(--line) solid var(--color-line-soft);
  padding: var(--space-xs) 0;
}

.check-yourself details:last-child {
  border-bottom: var(--line) solid var(--color-line-soft);
}

.check-yourself summary {
  display: flex;
  gap: var(--space-xs);
  cursor: pointer;
  font-weight: 500;
  list-style: none;
}

.check-yourself summary::-webkit-details-marker {
  display: none;
}

.check-yourself summary::before {
  content: "+";
  flex: 0 0 1em;
  font-family: var(--font-mono);
  color: var(--color-muted);
}

.check-yourself details[open] summary::before {
  content: "−";
}

.check-yourself .answer {
  margin-top: var(--space-2xs);
  padding-left: calc(1em + var(--space-xs));
  color: var(--color-ink);
}

.check-yourself .answer > * + * {
  margin-top: var(--space-2xs);
}

/* ==========================================================
   Tables in content
   Hairlines between rows only, no vertical lines, no fills.
   Wrap wide tables in <div class="table-wrap"> so they scroll
   sideways on small screens instead of the whole page.
   ========================================================== */

.table-wrap {
  max-width: var(--measure);
  overflow-x: auto;
}

.content table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  line-height: 1.5;
}

.content caption {
  padding-bottom: var(--space-2xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-align: left;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content th,
.content td {
  padding: var(--space-2xs) var(--space-sm) var(--space-2xs) 0;
  border-bottom: var(--line) solid var(--color-line-soft);
  text-align: left;
  vertical-align: top;
}

.content th {
  font-weight: 600;
}

.content thead th {
  border-bottom-color: var(--color-line);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.content td code,
.content th code {
  white-space: nowrap;
}

/* ==========================================================
   Related terms and pages
   ========================================================== */

.related__label {
  margin-top: var(--space-md);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.term-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-sm);
  list-style: none;
  padding: 0 !important;
}

.term-list li + li {
  margin-top: 0;
}

.related-pages {
  list-style: none;
  padding: 0 !important;
}

.related-pages li {
  display: flex;
  flex-direction: column;
}

.related-pages__summary {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* ==========================================================
   Previous / next
   ========================================================== */

.pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
  max-width: var(--measure);
  margin-top: var(--space-xl);
  padding-top: var(--space-md);
  border-top: var(--line) solid var(--color-line-soft);
}

.pager__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  text-decoration: none;
}

.pager__link--next {
  grid-column: 2;
  align-items: flex-end;
  text-align: right;
}

.pager__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.pager__label .icon {
  width: 1rem;
  height: 1rem;
}

.pager__title {
  font-family: var(--font-heading);
  font-variation-settings:
    "SOFT" var(--heading-soft),
    "WONK" var(--heading-wonk);
  font-size: 1.2rem;
  line-height: 1.25;
}

.pager__link:hover .pager__title {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
  text-underline-offset: 0.2em;
}

/* ==========================================================
   Footer
   ========================================================== */

.site-footer {
  margin-top: var(--space-xl);
  padding: var(--space-lg) 0;
  border-top: var(--line) solid var(--color-line-soft);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-sm);
}

.site-footer__links {
  display: flex;
  gap: var(--space-md);
}

/* ==========================================================
   Section headings on overview pages (home, topic, glossary)
   ========================================================== */

.section {
  margin-top: var(--space-2xl);
}

.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2xs) var(--space-md);
  margin-bottom: var(--space-md);
}

.section__note {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* ==========================================================
   Home page
   ========================================================== */

.hero {
  padding: var(--space-xl) 0 var(--space-lg);
  max-width: 48rem;
}

.hero h1 {
  font-size: var(--text-hero);
  font-weight: 300;
  font-variation-settings:
    "SOFT" var(--heading-soft),
    "WONK" var(--heading-wonk),
    "opsz" 144;
  letter-spacing: -0.02em;
}

.hero__tagline {
  margin-top: var(--space-sm);
  max-width: 36rem;
  font-size: var(--text-lead);
  line-height: 1.5;
  color: var(--color-muted);
}

.hero__search {
  position: relative;
  margin-top: var(--space-lg);
  max-width: 36rem;
}

.hero__search .icon {
  position: absolute;
  top: 50%;
  left: var(--space-sm);
  transform: translateY(-50%);
  color: var(--color-muted);
  pointer-events: none;
}

.hero__search .field {
  padding: 0.9rem 5rem 0.9rem 3rem;
  border-color: var(--color-line);
  font-size: 1.0625rem;
}

.hero__search kbd {
  position: absolute;
  top: 50%;
  right: var(--space-sm);
  transform: translateY(-50%);
  pointer-events: none;
}

.hero__hint {
  margin-top: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* Topic groups: a row of jump links, then per group a heading and its
   cards. Separation by white space only. */
.group-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs) var(--space-md);
  list-style: none;
  padding: 0;
  font-size: var(--text-sm);
}

.topic-group {
  margin-top: var(--space-xl);
}

/* Topic cards: whitespace and a thin accent rule, no boxes */
.topic-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: var(--space-lg) var(--space-md);
  list-style: none;
  padding: 0;
}

.topic-card__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--space-sm) var(--space-sm) var(--space-sm) 0;
  border-top: var(--line) solid var(--color-line);
  text-decoration: none;
  transition: background-color var(--duration) var(--ease);
}

a.topic-card__link {
  border-top: var(--rule-accent) solid var(--accent);
}

a.topic-card__link:hover {
  background: var(--color-surface);
}

a.topic-card__link:hover .topic-card__title {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
  text-underline-offset: 0.2em;
}

.topic-card__icon {
  margin: var(--space-sm) 0 var(--space-sm);
  color: var(--accent);
}

.topic-card__icon .icon {
  width: 1.75rem;
  height: 1.75rem;
}

.topic-card__title {
  font-size: 1.4rem;
}

.topic-card__tagline {
  margin-top: var(--space-2xs);
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--color-muted);
}

.topic-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: auto;
  padding-top: var(--space-sm);
  font-size: var(--text-sm);
}

.topic-card.is-soon .topic-card__link {
  border-top-color: var(--color-line-soft);
}

.topic-card.is-soon .topic-card__icon,
.topic-card.is-soon .topic-card__title {
  color: var(--color-muted);
}

.topic-card__status {
  color: var(--color-muted);
  font-style: italic;
}

.topic-card.is-soon .tag {
  border-color: var(--color-line-soft);
  color: var(--color-muted);
}

/* Recently added */
.recent {
  list-style: none;
  padding: 0;
  max-width: 48rem;
}

.recent__item {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3xs) var(--space-md);
  padding: var(--space-xs) 0;
  border-top: var(--line) solid var(--color-line-soft);
}

.recent__item a {
  font-weight: 500;
  text-decoration: none;
}

.recent__item a:hover {
  text-decoration: underline;
}

.recent__meta {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.recent__meta::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: var(--space-2xs);
  background: var(--accent);
}

/* ==========================================================
   Topic overview
   ========================================================== */

.topic-hero {
  padding-bottom: var(--space-md);
}

.topic-hero__icon {
  margin-bottom: var(--space-sm);
  color: var(--accent);
}

.topic-hero__icon .icon {
  width: 2.5rem;
  height: 2.5rem;
}

.topic-hero__stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-md);
  margin-top: var(--space-md);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.path {
  list-style: none;
  padding: 0 !important;
  max-width: none !important;
}

.path__item + .path__item {
  margin-top: 0 !important;
}

.path__link {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: var(--space-3xs) var(--space-sm);
  padding: var(--space-sm) var(--space-2xs) var(--space-sm) 0;
  border-top: var(--line) solid var(--color-line-soft);
  text-decoration: none;
  transition: background-color var(--duration) var(--ease);
}

.path__link:hover {
  background: var(--color-surface);
}

.path__num {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.9;
  color: var(--accent);
}

.path__body {
  display: flex;
  flex-direction: column;
}

.path__title {
  font-family: var(--font-heading);
  font-variation-settings:
    "SOFT" var(--heading-soft),
    "WONK" var(--heading-wonk);
  font-size: 1.2rem;
  line-height: 1.4;
}

.path__link:hover .path__title {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
  text-underline-offset: 0.2em;
}

.path__summary {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.path__meta {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

/* Field Notes: the date of a note in place of its level. */
.path__meta time {
  font-size: var(--text-sm);
  color: var(--color-muted);
  white-space: nowrap;
}

/* Wide screens: level and certification tags in their own column of a
   fixed width, stacked, so the summary column is equally wide in every
   row no matter how many tags a page has. */
@media (min-width: 64rem) {
  .path__link {
    grid-template-columns: 2.5rem minmax(0, 1fr) var(--path-meta-width);
  }

  .path__meta {
    grid-column: 3;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: flex-end;
    align-self: start;
    gap: var(--space-3xs);
    padding-top: 0.3rem;
  }
}

.mini-glossary {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: var(--space-md) var(--space-lg);
  max-width: none !important;
}

.mini-glossary dt a {
  font-weight: 600;
  text-decoration: none;
}

.mini-glossary dt a:hover {
  text-decoration: underline;
}

.mini-glossary dd {
  margin-top: var(--space-3xs);
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--color-muted);
}

/* ==========================================================
   Glossary page
   ========================================================== */

.glossary-tools {
  display: grid;
  gap: var(--space-sm);
  max-width: 48rem;
}

/* Group filter: a native <select> (keyboard and screen readers for free)
   with a drawn chevron, as in the region switch. A fixed width, so the
   options added by script do not move anything. */
.glossary-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-sm);
}

.glossary-group__label {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.glossary-group__control {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: min(100%, 17rem);
}

.glossary-group__select {
  padding-right: 2.25rem;
  color: inherit;
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  appearance: none;
}

.glossary-group__select option {
  background: var(--color-bg);
  color: var(--color-ink);
}

.glossary-group__chevron {
  position: absolute;
  right: var(--space-2xs);
  width: 1rem;
  height: 1rem;
  color: var(--color-muted);
  pointer-events: none;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.glossary-status {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.letter-bar {
  position: sticky;
  top: var(--header-height);
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin-top: var(--space-lg);
  padding: var(--space-2xs) 0;
  background: var(--color-bg);
  border-bottom: var(--line) solid var(--color-line-soft);
}

.letter-bar a {
  min-width: 2rem;
  padding: 0.25rem 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-align: center;
  text-decoration: none;
}

.letter-bar a:hover {
  background: var(--color-surface);
}

.letter-bar a.is-empty {
  color: var(--color-line-soft);
  pointer-events: none;
}

.glossary-list {
  scroll-margin-top: calc(var(--header-height) + 4rem);
}

.glossary-letter {
  margin-top: var(--space-xl);
  scroll-margin-top: calc(var(--header-height) + 4rem);
}

.glossary-letter__heading {
  margin-bottom: var(--space-sm);
  font-size: var(--text-h2);
}

.term {
  max-width: var(--measure);
  padding: var(--space-md) var(--space-sm) var(--space-md) 0;
  border-top: var(--line) solid var(--color-line-soft);
  scroll-margin-top: calc(var(--header-height) + 4rem);
}

.term > * + * {
  margin-top: var(--space-2xs);
}

.term__name {
  display: inline;
  margin-right: var(--space-2xs);
  font-family: var(--font-body);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: 0;
}

.term .tag {
  vertical-align: 0.15em;
}

.term__related {
  font-size: var(--text-sm);
}

.term__label {
  margin-right: var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.term__more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--text-sm);
}

.term__more .icon {
  width: 1rem;
  height: 1rem;
}

.term.is-target {
  padding-left: var(--space-sm);
  background: var(--color-surface);
}

/* ==========================================================
   Search palette
   ========================================================== */

.palette-open {
  overflow: hidden;
}

.palette {
  width: min(40rem, calc(100vw - 2rem));
  max-width: none;
  max-height: min(36rem, calc(100vh - 4rem));
  margin: 8vh auto auto;
  padding: 0;
  border: var(--line) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-ink);
}

.palette::backdrop {
  background: var(--color-overlay);
}

.palette[open] {
  display: flex;
}

.palette__box {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 0;
}

.palette__field {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 0 var(--space-sm);
  border-bottom: var(--line) solid var(--color-line-soft);
}

.palette__field > .icon {
  color: var(--color-muted);
}

.palette__input {
  flex: 1;
  min-width: 0;
  padding: var(--space-sm) 0;
  border: 0;
  background: transparent;
  font-size: 1.125rem;
  outline: none;
}

.palette__input::-webkit-search-cancel-button {
  display: none;
}

.palette__input::placeholder {
  color: var(--color-faint);
}

.palette__close {
  padding: 0;
  border: 0;
  background: transparent;
}

.palette__results {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-2xs) 0;
}

.palette__status {
  padding: var(--space-2xs) var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.palette__status:empty {
  display: none;
}

.palette__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-md);
  padding: var(--space-2xs) var(--space-sm);
  border-top: var(--line) solid var(--color-line-soft);
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.palette__footer kbd + kbd {
  margin-left: 2px;
}

.palette__footer kbd {
  margin-right: 2px;
}

.palette__all {
  margin-left: auto;
}

@media (max-width: 40rem) {
  .palette {
    margin-top: var(--space-sm);
    max-height: calc(100vh - 2rem);
  }

  .palette__footer span {
    display: none;
  }
}

/* ==========================================================
   Search results (palette and results page)
   ========================================================== */

.result-group + .result-group {
  margin-top: var(--space-2xs);
}

.result-group__label {
  padding: var(--space-2xs) var(--space-sm) var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.result-group__count {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

.result {
  display: flex;
  gap: var(--space-xs);
  padding: var(--space-2xs) var(--space-sm);
  border-left: var(--rule-accent) solid transparent;
  text-decoration: none;
}

.result:hover,
.result[aria-selected="true"] {
  background: var(--color-surface);
  border-left-color: var(--accent);
}

.result__icon {
  flex: 0 0 1.25rem;
  padding-top: 0.15rem;
  color: var(--accent);
}

.result--section .result__icon,
.result--glossary .result__icon {
  color: var(--color-muted);
}

.result__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.result__title {
  font-weight: 500;
  line-height: 1.4;
}

.result__meta {
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.result__summary,
.result__definition {
  margin-top: var(--space-3xs);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-muted);
}

.result__definition {
  color: var(--color-ink);
}

/* Results page */
.search-page {
  max-width: 48rem;
}

.search-page__form {
  display: flex;
  gap: var(--space-2xs);
  margin-top: var(--space-md);
}

.search-page__button {
  padding: 0 var(--space-md);
  border: var(--line) solid var(--color-ink);
  border-radius: var(--radius);
  background: var(--color-ink);
  color: var(--color-bg);
}

.search-page__summary {
  margin: var(--space-md) 0;
  color: var(--color-muted);
}

.search-page .result {
  padding-left: var(--space-xs);
}

.search-page .result-group {
  margin-top: var(--space-lg);
}

.search-page .result-group__label {
  padding-left: 0;
}

/* ==========================================================
   Regex tester (regex/regex-tester.html, assets/js/regex-tester.js)
   The test text is a transparent textarea over a backdrop that
   holds the same text with <mark>s; both share font, padding
   and wrapping so the marks line up with the letters.
   ========================================================== */

.rt {
  margin-top: var(--space-md);
  padding: var(--space-md);
  border: var(--line) solid var(--color-line);
}

.rt > * + * {
  margin-top: var(--space-md);
}

.rt__label {
  display: block;
  margin-bottom: var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.rt__pattern {
  display: flex;
  align-items: stretch;
  border: var(--line) solid var(--color-ink);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--text-code);
}

.rt__pattern:focus-within {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: 2px;
}

.rt__slash {
  display: flex;
  align-items: center;
  padding: 0 var(--space-2xs);
  color: var(--color-muted);
}

.rt__pattern input {
  flex: 1;
  min-width: 0;
  padding: var(--space-2xs) 0;
  border: 0;
  background: transparent;
  font: inherit;
}

.rt__pattern input:focus-visible {
  outline: none;
}

.rt__flags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  /* No margin shorthand: the top margin comes from .rt > * + * */
  margin-right: 0;
  margin-bottom: 0;
  margin-left: 0;
  padding: 0;
  border: 0;
}

.rt__flags legend {
  float: left;
  width: 100%;
  padding: 0;
}

.rt__flag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--text-sm);
}

.rt__flag code {
  font-weight: 600;
}

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

.rt__text {
  position: relative;
  border: var(--line) solid var(--color-ink);
  border-radius: var(--radius);
  background: var(--color-bg);
}

.rt__text:focus-within {
  outline: var(--focus-width) solid var(--color-focus);
  outline-offset: 2px;
}

.rt__backdrop,
.rt__text textarea {
  margin: 0;
  padding: var(--space-xs) var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-code);
  line-height: var(--leading-body);
  letter-spacing: normal;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  tab-size: 4;
}

.rt__backdrop {
  position: absolute;
  inset: 0;
  overflow: hidden;
  color: transparent;
  pointer-events: none;
}

.rt__text textarea {
  position: relative;
  display: block;
  width: 100%;
  min-height: 8rem;
  border: 0;
  background: transparent;
  color: var(--color-ink);
  resize: none;
  overflow: hidden;
}

.rt__text textarea:focus-visible {
  outline: none;
}

.rt-mark {
  color: transparent;
  background: var(--color-mark);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.rt-mark--alt {
  box-shadow: inset 0 -2px 0 var(--color-ink);
}

.rt__replace {
  display: grid;
  gap: var(--space-2xs);
}

.rt__replace input[type="text"] {
  padding: var(--space-2xs) var(--space-sm);
  border: var(--line) solid var(--color-ink);
  border-radius: var(--radius);
  background: var(--color-bg);
  font-family: var(--font-mono);
  font-size: var(--text-code);
}

.rt__replace input[type="text"]:disabled {
  border-color: var(--color-line-soft);
  color: var(--color-muted);
}

.rt__status {
  padding-left: var(--space-sm);
  border-left: var(--line) solid var(--color-line);
}

.rt__status.is-problem {
  border-left: var(--rule-accent) solid var(--accent);
}

.rt__literal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-sm);
}

.rt__literal code {
  overflow-wrap: anywhere;
}

.rt__button {
  padding: 0.2rem 0.6rem;
  border: var(--line) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-bg);
  font-size: var(--text-sm);
}

.rt__button:hover {
  border-color: var(--color-ink);
}

/* .rt in front: .content ul and .content ol would otherwise indent the lists */
.rt .rt__matches {
  margin: 0;
  padding: 0;
  list-style: none;
}

.rt-match {
  padding: var(--space-2xs) 0;
  border-top: var(--line) solid var(--color-line-soft);
}

.rt-match__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin: 0;
}

.rt-match__head code {
  overflow-wrap: anywhere;
}

.rt-match__number,
.rt-match__where {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.rt-match__groups {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-3xs) var(--space-sm);
  margin: var(--space-3xs) 0 0 var(--space-md);
  font-size: var(--text-sm);
}

.rt-match__groups dt {
  color: var(--color-muted);
}

.rt-match__groups dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.rt .rt__examples {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* .content li + li adds a top margin to every item but the first,
   which pushed the example buttons out of line. */
.rt__examples li + li,
.rt__matches li + li {
  margin-top: 0;
}

.rt-example {
  padding: 0.2rem 0.6rem;
  border: var(--line) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-bg);
  font-size: var(--text-sm);
}

.rt-example:hover {
  border-color: var(--accent);
}

.rt__note {
  margin-top: var(--space-xs);
}

.rt-offscreen {
  position: fixed;
  top: 0;
  left: -9999px;
}

.rt__result pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ==========================================================
   Network and binary tools (assets/js/net-tools.js)
   <form class="nt" data-net-tool="…"> in a "Try it" section on
   networking and math pages. The status line is the live region
   (a one-sentence summary); the result below it is not.
   ========================================================== */

.nt {
  padding: var(--space-md);
  border: var(--line) solid var(--color-line);
}

.nt > * + *,
.nt__result > * + *,
.nt__live > * + *,
.nt__notice > * + * {
  margin-top: var(--space-sm);
}

/* The noscript note is not shown when scripts run: no gap for it */
.nt > noscript + * {
  margin-top: 0;
}

.nt__label {
  display: block;
  margin-bottom: var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.nt__input {
  display: block;
  width: 100%;
  max-width: 28rem;
  padding: var(--space-2xs) var(--space-sm);
  border: var(--line) solid var(--color-ink);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-mono);
  font-size: var(--text-code);
}

.nt__input--area {
  line-height: var(--leading-body);
  resize: vertical;
}

/* Not by color alone: an invalid field gets a thick left rule */
.nt__input[aria-invalid="true"] {
  border-left: var(--rule-accent) solid var(--accent);
}

.nt__help {
  margin-top: var(--space-3xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.nt__choices,
.nt__needs {
  /* No margin shorthand: the top margin comes from .nt > * + * */
  margin-right: 0;
  margin-bottom: 0;
  margin-left: 0;
  padding: 0;
  border: 0;
}

.nt__choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
}

.nt__choices legend {
  float: left;
  width: 100%;
  padding: 0;
}

.nt__choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
}

.nt__needs > * + *,
[data-nt-rows] > * + * {
  margin-top: var(--space-2xs);
}

.nt__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
}

.nt__row .nt__input {
  flex: 1 1 10rem;
  width: auto;
}

.nt__row .nt__input + .visually-hidden + .nt__input {
  flex: 0 1 7rem;
}

.nt__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.nt__button {
  padding: 0.2rem 0.6rem;
  border: var(--line) solid var(--color-line);
  border-radius: var(--radius);
  background: var(--color-bg);
  font-size: var(--text-sm);
}

.nt__button:hover {
  border-color: var(--color-ink);
}

.nt__button--primary {
  border-color: var(--color-ink);
  background: var(--color-ink);
  color: var(--color-bg);
}

.nt__button--primary:hover {
  background: var(--color-bg);
  color: var(--color-ink);
}

.nt__status {
  padding-left: var(--space-sm);
  border-left: var(--line) solid var(--color-line);
}

.nt__status.is-problem {
  border-left: var(--rule-accent) solid var(--accent);
}

.nt__status:empty,
.nt__result:empty {
  display: none;
}

.nt__answer {
  font-weight: 600;
}

.nt__subhead {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.nt__facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-3xs) var(--space-md);
  margin: 0;
  font-size: var(--text-sm);
}

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

.nt__facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

@media (max-width: 30rem) {
  .nt__facts {
    grid-template-columns: 1fr;
  }

  .nt__facts dd + dt {
    margin-top: var(--space-2xs);
  }
}

.nt__note,
.nt__source,
.nt__noscript {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.nt__note--warning {
  padding: var(--space-2xs) var(--space-sm);
  border: var(--line) solid var(--color-ink);
  color: var(--color-ink);
}

.nt__table td {
  font-variant-numeric: tabular-nums;
}

.nt__table--grid th,
.nt__table--grid td {
  padding-right: var(--space-2xs);
  font-family: var(--font-mono);
  text-align: center;
}

/* Bits: network bits in the ink color and semibold, host bits muted.
   The weight is the cue that does not rely on color. */
.nt-bits {
  font-family: var(--font-mono);
  white-space: nowrap;
}

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

.nt-bit--net {
  color: var(--color-ink);
  font-weight: 600;
}

/* Tool output tables with bits (calculator, binary, bitwise AND): smaller
   text and tighter cells, so 32 bits fit the tool without a scrollbar. */
.content table.nt__table--compact {
  font-size: 0.71875rem; /* 11.5px, chosen by eye; smaller than --text-xs */
}

.content .nt__table--compact th,
.content .nt__table--compact td {
  padding-right: var(--space-2xs);
}

.content .nt__table--compact thead th {
  font-size: inherit;
}

/* Port lookup: one table per protocol. Fixed column widths, so the
   columns line up from table to table instead of following the content. */
.content table.nt__table--ports {
  table-layout: fixed;
}

.nt__table--ports th:nth-child(1) {
  width: 30%;
}

.nt__table--ports th:nth-child(2) {
  width: 50%;
}

.nt__table--ports td code {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* A block drawn to scale: parts side by side, free space dashed */
.nt-bar {
  display: flex;
  height: 1.75rem;
  border: var(--line) solid var(--color-ink);
}

.nt-bar__part {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 2px;
  overflow: hidden;
  border-right: var(--line) solid var(--color-ink);
  background: var(--color-surface);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

.nt-bar__part:last-child {
  border-right: 0;
}

.nt-bar__part--free {
  background: var(--color-bg);
  outline: var(--line) dashed var(--color-line);
  outline-offset: -4px;
}

/* .nt in front: .content ul would otherwise set its own spacing */
.nt .nt__list {
  margin: 0;
  font-size: var(--text-sm);
}

.nt__notice {
  padding: var(--space-sm) var(--space-md);
  border: var(--line) solid var(--color-ink);
}

/* ==========================================================
   Math formulas, rendered by KaTeX (assets/vendor/katex)
   <span class="math">…</span> inline · <div class="math math--display">
   ========================================================== */

.content .math--display {
  max-width: 100%;
  margin-top: var(--space-sm);
  overflow-x: auto;
  overflow-y: hidden;
  padding: var(--space-3xs) 0;
}

.content .katex {
  font-size: 1.1em;
}

/* ==========================================================
   Illustrations (assets/images/<topic>/)
   <figure class="illustration illustration--side">
     <img src="…" alt="…" width="…" height="…" loading="lazy">
     <figcaption>…</figcaption>
   </figure>
   --side floats to the right of the paragraphs that follow it on
   wider screens; on narrow screens it sits above them.
   ========================================================== */

.content .illustration {
  margin: var(--space-lg) 0;
}

/* The paragraph after a full-width picture keeps the same distance */
.content .illustration:not(.illustration--side) + * {
  margin-top: var(--space-lg);
}

.content .illustration img {
  display: block;
  width: 100%;
  height: auto;
}

.content .illustration figcaption {
  margin-top: var(--space-2xs);
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.content .illustration--side {
  max-width: 20rem;
}

@media (min-width: 40rem) {
  .content .illustration--side {
    float: right;
    width: 45%;
    max-width: 20rem;
    margin: var(--space-3xs) 0 var(--space-sm) var(--space-md);
  }

  /* The text next to it starts level with the picture */
  .content .illustration--side + p {
    margin-top: var(--space-xs);
  }
}

/* A new section never wraps around a picture from the previous one */
.content h2,
.content h3 {
  clear: both;
}
