/* ==========================================================================
   3270.io documentation theme

   Ports the 3270.io landing-page design system onto Material for MkDocs so
   the docs, the marketing site, the 3270Connect operations console and the
   3270Web terminal all read as one surface: the same accent ramp, the same
   four palettes, the same mono-eyebrow / glass-panel language.

   Keep this file byte-identical between the 3270Connect and 3270Web repos —
   it is the shared vocabulary. Per-site differences belong in extra.css.

   Contents
   1.  Design tokens — four palettes
   2.  Material variable bridge
   3.  Base & ambient backdrop
   4.  Header, tabs & search
   5.  Sidebars: navigation & table of contents
   6.  Typography
   7.  Code
   8.  Admonitions, details & content tabs
   9.  Tables, images, cards & keys
   10. Footer
   11. Home-page primitives (hero, KPI tiles, terminal, panels)
   12. Motion preferences
   ========================================================================== */

/* ==========================================================================
   1. Design tokens — four palettes

   Phosphor green is the default. Amber CRT, ice/steel and daylight mirror the
   segmented GRN / AMB / ICE / DAY control on 3270.io and in the console.
   ========================================================================== */

:root,
html[data-theme='phosphor'] {
  --bg: #03110d;
  --bg-deep: #010806;

  --aurora-1: rgba(78, 255, 176, 0.18);
  --aurora-2: rgba(90, 210, 255, 0.12);
  --aurora-3: rgba(185, 140, 255, 0.10);

  --surface: rgba(9, 40, 30, 0.62);
  --surface-2: rgba(6, 30, 23, 0.72);
  --surface-3: rgba(4, 20, 16, 0.86);
  --surface-solid: #06201a;

  --line: rgba(78, 255, 176, 0.16);
  --line-strong: rgba(78, 255, 176, 0.34);

  --text: #e6fff5;
  --text-2: #9fe6c8;
  --text-3: #5f9e86;

  --accent: #4effb3;
  --accent-2: #7cf9d0;
  --accent-ink: #02130a;
  --accent-soft: rgba(78, 255, 176, 0.14);

  --ok: #4effb3;
  --info: #5ad2ff;
  --warn: #f7c36b;
  --danger: #ff6f82;
  --violet: #b98cff;

  --scanline: rgba(255, 255, 255, 0.028);

  color-scheme: dark;
}

html[data-theme='amber'] {
  --bg: #150c02;
  --bg-deep: #0a0601;

  --aurora-1: rgba(255, 183, 77, 0.20);
  --aurora-2: rgba(255, 122, 89, 0.12);
  --aurora-3: rgba(255, 231, 143, 0.08);

  --surface: rgba(52, 32, 6, 0.58);
  --surface-2: rgba(38, 23, 4, 0.72);
  --surface-3: rgba(26, 15, 2, 0.86);
  --surface-solid: #1e1204;

  --line: rgba(255, 183, 77, 0.18);
  --line-strong: rgba(255, 183, 77, 0.38);

  --text: #fff3dc;
  --text-2: #e9c48a;
  --text-3: #a3814c;

  --accent: #ffb84d;
  --accent-2: #ffd489;
  --accent-ink: #1a0f01;
  --accent-soft: rgba(255, 184, 77, 0.16);

  --ok: #8fe388;
  --info: #7cc8ff;
  --warn: #ffd166;
  --danger: #ff7a6b;
  --violet: #d6a4ff;

  --scanline: rgba(255, 255, 255, 0.028);

  color-scheme: dark;
}

html[data-theme='ice'] {
  --bg: #050b16;
  --bg-deep: #02050c;

  --aurora-1: rgba(90, 210, 255, 0.20);
  --aurora-2: rgba(120, 140, 255, 0.14);
  --aurora-3: rgba(80, 255, 220, 0.08);

  --surface: rgba(14, 32, 58, 0.58);
  --surface-2: rgba(10, 24, 44, 0.74);
  --surface-3: rgba(6, 16, 32, 0.88);
  --surface-solid: #0a1830;

  --line: rgba(120, 200, 255, 0.16);
  --line-strong: rgba(120, 200, 255, 0.36);

  --text: #eaf5ff;
  --text-2: #a7c9e8;
  --text-3: #6b8bab;

  --accent: #5ad2ff;
  --accent-2: #9be6ff;
  --accent-ink: #021019;
  --accent-soft: rgba(90, 210, 255, 0.15);

  --ok: #4ee9b0;
  --info: #5ad2ff;
  --warn: #ffcc70;
  --danger: #ff7a90;
  --violet: #a99bff;

  --scanline: rgba(255, 255, 255, 0.028);

  color-scheme: dark;
}

html[data-theme='daylight'] {
  --bg: #eef2f0;
  --bg-deep: #dde5e1;

  --aurora-1: rgba(0, 160, 105, 0.12);
  --aurora-2: rgba(0, 130, 190, 0.08);
  --aurora-3: rgba(140, 100, 220, 0.06);

  --surface: rgba(255, 255, 255, 0.84);
  --surface-2: rgba(255, 255, 255, 0.94);
  --surface-3: rgba(246, 249, 247, 0.98);
  --surface-solid: #ffffff;

  --line: rgba(12, 60, 45, 0.14);
  --line-strong: rgba(12, 60, 45, 0.26);

  --text: #082019;
  --text-2: #3d5c51;
  --text-3: #6d8579;

  --accent: #00875a;
  --accent-2: #00a76f;
  --accent-ink: #ffffff;
  --accent-soft: rgba(0, 135, 90, 0.12);

  --ok: #12805a;
  --info: #0b6fa4;
  --warn: #a16207;
  --danger: #c0392b;
  --violet: #6d4bbd;

  --scanline: rgba(8, 32, 25, 0.020);

  color-scheme: light;
}

/* --- Shape, depth, type & motion — palette-independent ------------------- */
:root {
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 12px 32px -12px rgba(0, 0, 0, 0.75);
  --shadow-3: 0 32px 80px -24px rgba(0, 0, 0, 0.85);

  --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', 'Cascadia Code', Consolas, monospace;
  --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-1: 140ms;
  --dur-2: 260ms;
  --dur-3: 520ms;
}

html[data-theme='daylight'] {
  --shadow-2: 0 12px 32px -14px rgba(8, 32, 25, 0.35);
  --shadow-3: 0 32px 80px -28px rgba(8, 32, 25, 0.35);
}

/* ==========================================================================
   2. Material variable bridge

   Every Material component reads --md-* custom properties. Mapping them onto
   the tokens above re-skins the whole theme without touching its internals,
   and keeps all four palettes coherent in one place.

   Material stamps the palette onto <body>, not <html>. A rule on body wins
   over anything inherited from html, so its scheme block would quietly beat
   these values — most visibly in daylight, where slate's dark surfaces leaked
   through onto the nav and code punctuation. Two defences:

     • mkdocs.yml asks for scheme `3270` and primary/accent `custom`, none of
       which Material ships a variable block for, so nothing competes;
     • the bridge is declared on `html[data-theme] body` too (0,1,2), which
       outranks `body[data-md-color-scheme=…]` (0,1,1) even if that changes.
   ========================================================================== */

:root,
html[data-theme],
html[data-theme] body {
  --md-text-font-family: var(--font-sans);
  --md-code-font-family: var(--font-mono);

  --md-default-fg-color: var(--text);
  --md-default-fg-color--light: var(--text-2);
  --md-default-fg-color--lighter: var(--text-3);
  --md-default-fg-color--lightest: var(--line);
  --md-default-bg-color: var(--bg);
  --md-default-bg-color--light: var(--surface);
  --md-default-bg-color--lighter: var(--surface-2);
  --md-default-bg-color--lightest: var(--surface-3);

  --md-primary-fg-color: var(--accent);
  --md-primary-fg-color--light: var(--accent-2);
  --md-primary-fg-color--dark: var(--accent);
  --md-primary-bg-color: var(--accent-ink);
  --md-primary-bg-color--light: var(--accent-ink);

  --md-accent-fg-color: var(--accent-2);
  --md-accent-fg-color--transparent: var(--accent-soft);
  --md-accent-bg-color: var(--accent-ink);
  --md-accent-bg-color--light: var(--accent-ink);

  --md-typeset-color: var(--text-2);
  --md-typeset-a-color: var(--accent);
  --md-typeset-mark-color: var(--accent-soft);
  --md-typeset-del-color: rgba(255, 111, 130, 0.22);
  --md-typeset-ins-color: rgba(78, 255, 176, 0.22);
  --md-typeset-kbd-color: var(--surface-2);
  --md-typeset-kbd-accent-color: var(--line);
  --md-typeset-kbd-border-color: var(--line-strong);
  --md-typeset-table-color: var(--line);

  --md-code-fg-color: var(--text-2);
  --md-code-bg-color: var(--surface-3);
  --md-code-hl-color: var(--accent-soft);
  --md-code-hl-number-color: var(--warn);
  --md-code-hl-special-color: var(--violet);
  --md-code-hl-function-color: var(--violet);
  --md-code-hl-constant-color: var(--info);
  --md-code-hl-keyword-color: var(--info);
  --md-code-hl-string-color: var(--accent);
  --md-code-hl-name-color: var(--text);
  --md-code-hl-operator-color: var(--text-3);
  --md-code-hl-punctuation-color: var(--text-3);
  --md-code-hl-comment-color: var(--text-3);
  --md-code-hl-generic-color: var(--text-2);
  --md-code-hl-variable-color: var(--text-2);

  --md-admonition-fg-color: var(--text-2);
  --md-admonition-bg-color: var(--surface-2);

  --md-footer-fg-color: var(--text);
  --md-footer-fg-color--light: var(--text-3);
  --md-footer-fg-color--lighter: var(--text-3);
  --md-footer-bg-color: transparent;
  --md-footer-bg-color--dark: transparent;

  --md-shadow-z1: var(--shadow-1);
  --md-shadow-z2: var(--shadow-2);
  --md-shadow-z3: var(--shadow-3);
}

/* ==========================================================================
   3. Base & ambient backdrop

   The landing page layers an aurora wash, a drifting engineering grid and
   CRT scanlines behind everything. Same recipe here, painted onto body's
   pseudo-elements: html carries the base colour so the negative-z-index
   layers stay visible above the canvas.
   ========================================================================== */

html {
  background-color: var(--bg-deep);
  scroll-padding-top: 4.5rem;
}

body {
  background-color: transparent;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Aurora wash + scanlines */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, var(--scanline) 2px 4px),
    radial-gradient(120% 90% at 12% -10%, var(--aurora-1), transparent 58%),
    radial-gradient(110% 80% at 88% 0%, var(--aurora-2), transparent 55%),
    radial-gradient(120% 120% at 50% 120%, var(--aurora-3), transparent 60%),
    var(--bg);
}

/* Drifting engineering grid, masked to the upper page so long docs stay calm */
body::after {
  content: '';
  position: fixed;
  inset: -20%;
  z-index: -1;
  pointer-events: none;
  opacity: 0.35;
  background:
    linear-gradient(to right, var(--line) 1px, transparent 1px) 0 0 / 64px 64px,
    linear-gradient(to bottom, var(--line) 1px, transparent 1px) 0 0 / 64px 64px;
  mask-image: radial-gradient(80% 60% at 50% 18%, #000 0%, transparent 78%);
  -webkit-mask-image: radial-gradient(80% 60% at 50% 18%, #000 0%, transparent 78%);
  animation: grid-drift 90s linear infinite;
}

@keyframes grid-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-64px, -64px, 0); }
}

/* Material paints an opaque background on the main container in some
   layouts; keep it transparent so the backdrop reads through. */
.md-main,
.md-main__inner,
.md-content,
.md-container,
.md-grid { background: transparent; }

/* Scrollbars — thin, accent on hover, same as the console. */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
*::-webkit-scrollbar-thumb:hover { background: var(--accent); background-clip: content-box; }

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

::selection { background: var(--accent); color: var(--accent-ink); }

/* ==========================================================================
   4. Header, tabs & search
   ========================================================================== */

.md-header {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  color: var(--text);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  box-shadow: none;
}

.md-header--shadow { box-shadow: 0 10px 30px -22px rgba(0, 0, 0, 0.9); }

.md-header__title {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.md-header__topic:first-child { font-weight: 600; }

.md-header__button { color: var(--text-2); }
.md-header__button:hover { color: var(--accent); opacity: 1; }

/* --- Product mark --------------------------------------------------------
   overrides/partials/logo.html inlines the SVG so it can read `currentColor`
   and `--accent` and re-tint with the palette. Two things must be corrected
   for that to work inside Material's chrome:

     • Material sets `fill: currentcolor` on logo SVGs. That wins over the
       `fill="none"` presentation attribute on the root, and the bezel — which
       is stroked, not filled — would flood solid. Reset it here and let each
       shape opt in to its own fill.
     • The mark is drawn on a 32×32 grid; give it a square box rather than
       `width: auto`, which has no intrinsic size to resolve against. */

.md-header__button.md-logo svg,
.md-nav__button.md-logo svg {
  fill: none;
}

.md-header__button.md-logo :is(img, svg),
.md-nav__button.md-logo :is(img, svg) {
  width: 1.75rem;
  height: 1.75rem;
}

/* Daylight deliberately carries no per-palette tweaks to the mark. It used to
   lift the receding planes and dim the specular sweep, which backfired: the
   glyph is knocked *out* of the front face, so raising the plane directly
   behind it filled that hole back in with a dull mid-green and the mark lost
   its edge. 3270.io ships the drawing unmodified, which is why the same mark
   reads sharper there. Don't reintroduce the overrides. */

/* The product mark above the home page hero. index.md carries an empty
   placeholder and overrides/main.html splices the header's SVG partial into
   it — see the comment there for why it cannot be written inline. The partial
   sizes itself for the header, so the hero size is set here. */
.hero-mark {
  margin: 0;
  line-height: 0;
}

/* Mark and provenance chip on one row — the lockup used at the top of
   3270.io. It wraps on narrow viewports, where the chip drops under the mark
   rather than squeezing the hero. The children's own margins are cleared so
   the lockup owns the spacing below it. */
.md-typeset .hero-lockup {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin: 0 0 1.4rem;
}

.md-typeset .hero-lockup > * {
  margin: 0;
}

/* The framing in "Images" below is for screenshots. A mark on a transparent
   ground must not pick up a border, a tile and a shadow, so this rule
   outranks the same framing in extra.css. */
.md-typeset .hero-mark :is(img, svg),
.hero-mark :is(img, svg) {
  width: 72px;
  height: 72px;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

/* The site name beside the mark is wrapped in a home link by 3270-theme.js.
   It should read as the title it replaced, not as body-copy link. */
.md-header__title .t3270-home-link {
  color: inherit;
  text-decoration: none;
}

.md-header__title .t3270-home-link:hover {
  color: var(--accent);
}

.md-header__title .t3270-home-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* --- Product tabs -------------------------------------------------------- */

.md-tabs {
  background: transparent;
  border-bottom: 1px solid var(--line);
  color: var(--text-2);
}

.md-tabs__link {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 1;
  color: var(--text-3);
  margin-top: 0.7rem;
  transition: color var(--dur-1) var(--ease);
}

.md-tabs__link:is(:hover, :focus) { color: var(--text); }

.md-tabs__item--active .md-tabs__link,
.md-tabs__link--active { color: var(--accent); }

/* --- Product tabs: reaching the ones past the edge -------------------------
   A nav of twenty-odd pages is wider than a tab strip at any desktop width,
   and the strip scrolls without saying so: `overflow-x: auto` paired with
   `scrollbar-width: none` leaves the overflowing tabs reachable by touch and
   by a trackpad's horizontal axis, and by nothing a mouse can do. There is no
   scrollbar to drag, no arrows, and a wheel reports only a vertical delta.

   3270-theme.js supplies what was missing — a stepper at each end, the wheel
   mapped onto the strip, and the current page scrolled into view on arrival —
   and marks the strip with `data-t3270-overflow` naming the ends that still
   have tabs behind them. Everything below hangs off that attribute, which is
   absent whenever the whole nav fits, so a short nav is left exactly as
   Material drew it. Wrapping the tabs onto more rows is the other way out of
   this and is worse: at these lengths it costs several rows of header before
   any documentation is reached. */

.md-tabs > .md-grid {
  display: flex;
}

.md-tabs__list {
  flex: 1 1 auto;
  min-width: 0;
  /* Browsers differ in how far they scroll a focused link into view: some
     centre it, others do the bare minimum and leave it flush against the edge
     — which is exactly where the fade below is thickest, so a focused tab
     would arrive half faded out. Reserve the fade's width so even the bare
     minimum lands clear of it. */
  scroll-padding-inline: 1.5rem;
}

/* Fade the strip where it continues rather than cutting a word in half. A
   mask, not a gradient overlay: the header is translucent over the ambient
   backdrop, so there is no solid colour to fade to. */
.md-tabs[data-t3270-overflow] .md-tabs__list {
  --t3270-fade-start: 0px;
  --t3270-fade-end: 0px;
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0, #000 var(--t3270-fade-start),
    #000 calc(100% - var(--t3270-fade-end)), transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0, #000 var(--t3270-fade-start),
    #000 calc(100% - var(--t3270-fade-end)), transparent 100%
  );
}

.md-tabs[data-t3270-overflow='start'] .md-tabs__list,
.md-tabs[data-t3270-overflow='both'] .md-tabs__list { --t3270-fade-start: 1.25rem; }

.md-tabs[data-t3270-overflow='end'] .md-tabs__list,
.md-tabs[data-t3270-overflow='both'] .md-tabs__list { --t3270-fade-end: 1.25rem; }

/* Both steppers appear together and then stay put: one that came and went
   with the scroll position would resize the strip under the pointer mid-step.
   The end with nothing left to reach dims instead of disappearing. */
.t3270-tabscroll {
  display: none;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 2.4rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-3);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease);
}

.md-tabs[data-t3270-overflow] .t3270-tabscroll { display: flex; }

.t3270-tabscroll svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: currentColor;
}

.t3270-tabscroll:hover { color: var(--accent); }

.t3270-tabscroll[disabled] {
  opacity: 0.3;
  cursor: default;
  color: var(--text-3);
}

/* --- Search -------------------------------------------------------------- */

.md-search__form {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}

.md-search__form:hover { background: var(--surface); border-color: var(--line-strong); }

[data-md-toggle='search']:checked ~ .md-header .md-search__form {
  background: var(--surface-solid);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-2);
}

.md-search__input { color: var(--text); font-size: 0.78rem; }
.md-search__input::placeholder { color: var(--text-3); }
.md-search__icon { color: var(--text-3); }

.md-search__output {
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-3);
}

.md-search-result__meta {
  background: var(--surface-2);
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.md-search-result__list { background: var(--surface-solid); }
.md-search-result__item { border-top: 1px solid var(--line); }
.md-search-result__article { color: var(--text-2); }
.md-search-result__title { color: var(--text); font-weight: 600; }

.md-search-result__link:is(:hover, :focus) { background: var(--accent-soft); }

.md-search-result mark { color: var(--accent); background: transparent; }

/* --- Palette switch — GRN / AMB / ICE / DAY -------------------------------
   Injected into the header by javascripts/3270-theme.js. Mirrors the
   segmented control on 3270.io and in the operations console. */

.t3270-palette {
  display: inline-flex;
  align-items: center;
  padding: 3px;
  margin-inline: 0.3rem;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-2);
}

.t3270-palette button {
  padding: 4px 9px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}

.t3270-palette button:hover { color: var(--text-2); }

.t3270-palette button[aria-pressed='true'] {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}

/* The control costs ~150px, which the phone header does not have to spare.
   Below the tablet breakpoint the header instance steps aside and the drawer
   instance takes over, so the palette stays reachable at every width. */
.t3270-palette--drawer {
  display: none;
  margin: 0.6rem 0.8rem;
}

@media screen and (max-width: 59.9375em) {
  .t3270-palette--header { display: none; }
  .t3270-palette--drawer { display: inline-flex; }
}

/* ==========================================================================
   5. Sidebars: navigation & table of contents
   ========================================================================== */

.md-sidebar { color: var(--text-2); }

.md-nav {
  font-size: 0.72rem;
  color: var(--text-2);
}

.md-nav__title {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3);
}

.md-nav__link {
  border-radius: var(--r-sm);
  padding: 0.32rem 0.5rem;
  margin-inline-start: -0.5rem;
  color: var(--text-2);
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}

.md-nav__link:is(:hover, :focus) { color: var(--text); background: var(--surface-2); }

.md-nav__item .md-nav__link--active,
.md-nav__item .md-nav__link--active:is(:hover, :focus) {
  color: var(--accent);
  background: var(--accent-soft);
  font-weight: 600;
}

/* Section labels (navigation.sections) read as eyebrows */
.md-nav__item--section > .md-nav__link {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
}

.md-nav--secondary .md-nav__title { box-shadow: none; }

/* Integrated TOC (toc.integrate) sits inside the primary sidebar: give it a
   hairline so it separates from the page nav above it. */
.md-nav--integrated > .md-nav__list > .md-nav__item--active .md-nav--secondary {
  border-left: 1px solid var(--line);
  margin-inline-start: 0.4rem;
  padding-inline-start: 0.4rem;
}

/* Scroll-spy marker on the standalone TOC */
.md-nav--secondary .md-nav__link--passed { color: var(--text-3); }

.md-sidebar__scrollwrap { scrollbar-color: var(--line-strong) transparent; }

/* ==========================================================================
   6. Typography
   ========================================================================== */

.md-typeset {
  font-size: 0.78rem;
  line-height: 1.72;
  color: var(--text-2);
}

.md-typeset h1 {
  font-size: clamp(1.9rem, 4.5vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -0.035em;
  font-weight: 640;
  color: var(--text);
  text-wrap: balance;
  margin-bottom: 1.2rem;
}

.md-typeset h2 {
  font-size: clamp(1.35rem, 3vw, 1.65rem);
  line-height: 1.15;
  letter-spacing: -0.026em;
  font-weight: 620;
  color: var(--text);
  margin-top: 2.4rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
  text-wrap: balance;
}

.md-typeset h3 {
  font-size: 1.1rem;
  letter-spacing: -0.015em;
  font-weight: 600;
  color: var(--text);
  margin-top: 1.8rem;
}

.md-typeset h4,
.md-typeset h5,
.md-typeset h6 {
  color: var(--text);
  font-weight: 600;
  letter-spacing: -0.005em;
}

.md-typeset h5 { text-transform: none; }

/* Anchor permalinks stay quiet until you are on the heading */
.md-typeset .headerlink { color: var(--line-strong); transition: color var(--dur-1) var(--ease); }
.md-typeset :is(h1, h2, h3, h4, h5, h6):hover .headerlink { color: var(--accent); }

.md-typeset a {
  color: var(--accent);
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.18em;
  transition: color var(--dur-1) var(--ease);
}
.md-typeset a:is(:hover, :focus) { color: var(--accent-2); text-decoration-color: var(--accent); }

.md-typeset strong, .md-typeset b { color: var(--text); font-weight: 600; }

.md-typeset hr {
  border-bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong), transparent);
  margin: 2.2rem 0;
}

.md-typeset blockquote {
  border-left: 2px solid var(--line-strong);
  color: var(--text-3);
  background: var(--surface-2);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 0.6rem 1rem;
}

.md-typeset ul li::marker { color: var(--accent); }
.md-typeset ol li::marker { color: var(--text-3); font-family: var(--font-mono); }

/* Task lists. A ticked box means shipped, so the tick is green in every
   palette instead of following the accent (amber and ice would otherwise
   render a shipped item in orange or blue). Unticked items get a hollow
   ring rather than a dimmed tick, so the two states differ by shape and
   not only by colour — which matters most in the phosphor palette, where
   everything is already green. */
.md-typeset .task-list-control .task-list-indicator::before {
  background-color: var(--text-3);
  opacity: 0.55;
  -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20m0 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16"/></svg>');
  mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20m0 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16"/></svg>');
}
.md-typeset .task-list-control [type='checkbox']:checked + .task-list-indicator::before {
  background-color: var(--ok);
  opacity: 1;
  -webkit-mask-image: var(--md-tasklist-icon--checked);
  mask-image: var(--md-tasklist-icon--checked);
}
/* Fallback for the native control if the custom indicator is unavailable. */
.md-typeset .task-list-item [type='checkbox'] { accent-color: var(--ok); }

/* Footnotes */
.md-typeset .footnote { color: var(--text-3); font-size: 0.72rem; }
.md-typeset .footnote-backref { color: var(--accent); }

/* Scroll-to-top pill */
.md-top {
  background: var(--surface-solid);
  border: 1px solid var(--line-strong);
  color: var(--text-2);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-2);
}
.md-top:is(:hover, :focus) { background: var(--accent); color: var(--accent-ink); }

/* ==========================================================================
   7. Code
   ========================================================================== */

.md-typeset code {
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: var(--r-xs);
  padding: 0.12em 0.4em;
  font-size: 0.86em;
  box-shadow: inset 0 0 0 1px var(--line);
}

/* Inside links and headings, inline code should not shout over the text */
.md-typeset a code { color: var(--accent-2); }
.md-typeset :is(h1, h2, h3, h4) code { background: var(--surface-2); color: var(--text); }

.md-typeset pre > code {
  background: transparent;
  color: var(--text-2);
  box-shadow: none;
  padding: 0.8rem 1rem;
}

.md-typeset .highlight,
.md-typeset pre {
  border-radius: var(--r-md);
}

.md-typeset .highlight {
  border: 1px solid var(--line);
  background: var(--surface-3);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.md-typeset .highlight > pre { margin: 0; }
.md-typeset .highlight code { font-size: 0.74rem; line-height: 1.75; }

/* Filename ribbon on annotated blocks */
.md-typeset .highlight span.filename {
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.md-clipboard { color: var(--text-3); }
.md-clipboard:is(:hover, :focus) { color: var(--accent); }

/* Line numbers */
.md-typeset .highlighttable .linenos { background: var(--surface-2); }
.md-typeset .linenodiv pre { color: var(--text-3); }

/* Highlighted lines */
.md-typeset .highlight .hll { background: var(--accent-soft); }

/* ==========================================================================
   8. Admonitions, details & content tabs
   ========================================================================== */

.md-typeset :is(.admonition, details) {
  border: 1px solid var(--line);
  border-left-width: 2px;
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow: var(--shadow-2);
  font-size: 0.74rem;
}

.md-typeset :is(.admonition-title, summary) {
  background: transparent;
  border: 0;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.md-typeset :is(.admonition-title, summary)::before { background-color: var(--accent); }

.md-typeset :is(.admonition, details) { border-left-color: var(--accent); }

/* Per-type accents, tied to the palette's semantic ramp */
.md-typeset :is(.note, .abstract, .info, .todo, .tip, .hint) { border-left-color: var(--info); }
.md-typeset :is(.note, .abstract, .info, .todo, .tip, .hint) > :is(.admonition-title, summary)::before { background-color: var(--info); }

.md-typeset :is(.success, .check, .done, .example) { border-left-color: var(--ok); }
.md-typeset :is(.success, .check, .done, .example) > :is(.admonition-title, summary)::before { background-color: var(--ok); }

.md-typeset :is(.warning, .caution, .attention) { border-left-color: var(--warn); }
.md-typeset :is(.warning, .caution, .attention) > :is(.admonition-title, summary)::before { background-color: var(--warn); }

.md-typeset :is(.failure, .fail, .missing, .danger, .error, .bug) { border-left-color: var(--danger); }
.md-typeset :is(.failure, .fail, .missing, .danger, .error, .bug) > :is(.admonition-title, summary)::before { background-color: var(--danger); }

.md-typeset :is(.quote, .cite) { border-left-color: var(--violet); }
.md-typeset :is(.quote, .cite) > :is(.admonition-title, summary)::before { background-color: var(--violet); }

/* --- Content tabs -------------------------------------------------------- */

.md-typeset .tabbed-set > input:checked + label {
  color: var(--accent);
  border-color: var(--accent);
}

.md-typeset .tabbed-labels > label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
  transition: color var(--dur-1) var(--ease);
}

.md-typeset .tabbed-labels > label:hover { color: var(--text); }

.md-typeset .tabbed-labels { box-shadow: 0 -1px var(--line) inset; }

/* ==========================================================================
   9. Tables, images, cards & keys
   ========================================================================== */

.md-typeset table:not([class]) {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow: var(--shadow-2);
  font-size: 0.72rem;
  overflow: hidden;
}

.md-typeset table:not([class]) th {
  background: var(--surface-3);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  border-bottom: 1px solid var(--line);
}

.md-typeset table:not([class]) td { border-top: 1px solid var(--line); vertical-align: top; }
.md-typeset table:not([class]) tr:hover { background: var(--accent-soft); }
.md-typeset table:not([class]) tbody tr:first-child td { border-top: 0; }

/* --- Images -------------------------------------------------------------- */

.md-typeset img:not(.emojione):not(.twemoji):not(.gemoji):not(.plain) {
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-2);
  background: var(--surface-3);
}

/* --- Card grids (grid cards) --------------------------------------------- */

.md-typeset .grid.cards > :is(ul, ol) > li,
.md-typeset .grid > .card {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-2);
  padding: 1rem 1.1rem;
  transition: transform var(--dur-2) var(--ease),
              border-color var(--dur-2) var(--ease),
              box-shadow var(--dur-2) var(--ease);
}

.md-typeset .grid.cards > :is(ul, ol) > li:is(:hover, :focus-within),
.md-typeset .grid > .card:is(:hover, :focus-within) {
  transform: translateY(-3px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-3), 0 0 40px -18px var(--accent);
}

/* Card titles carry the icon; give them the display voice, not body copy. */
.md-typeset .grid.cards > :is(ul, ol) > li > p:first-child {
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.md-typeset .grid.cards > :is(ul, ol) > li > p:first-child > :is(.twemoji, .emojione) svg {
  fill: var(--accent);
  height: 1.4rem;
  width: 1.4rem;
}

.md-typeset .grid.cards > :is(ul, ol) > li > hr {
  margin: 0.6rem 0 0.8rem;
  background: var(--line);
}

/* --- Keyboard keys ------------------------------------------------------- */

.md-typeset kbd {
  background: var(--surface-2);
  color: var(--text);
  border-radius: var(--r-xs);
  box-shadow:
    0 0 0 1px var(--line-strong),
    0 2px 0 var(--line);
  font-family: var(--font-mono);
  font-size: 0.72em;
}

/* --- Marks, buttons ------------------------------------------------------ */

.md-typeset mark { background: var(--accent-soft); color: var(--accent); }

.md-typeset .md-button {
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.55em 1.1em;
  transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-2) var(--ease),
              border-color var(--dur-1) var(--ease);
}

.md-typeset .md-button:is(:hover, :focus) {
  transform: translateY(-1px);
  border-color: var(--line-strong);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 6px 22px -10px var(--accent);
}

.md-typeset .md-button--primary {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  color: var(--accent-ink);
  border-color: transparent;
  box-shadow: 0 8px 26px -12px var(--accent);
}

.md-typeset .md-button--primary:is(:hover, :focus) {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  color: var(--accent-ink);
  border-color: transparent;
  box-shadow: 0 14px 34px -12px var(--accent);
}

/* --- Edit / view source actions ------------------------------------------ */

.md-content__button { color: var(--text-3); }
.md-content__button:hover { color: var(--accent); }

/* ==========================================================================
   10. Footer
   ========================================================================== */

.md-footer { background: transparent; }

.md-footer-meta { background: transparent; border-top: 1px solid var(--line); }

.md-footer__inner { margin-bottom: 1rem; }

.md-footer__link {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  padding: 0.8rem 1rem;
  margin: 0.4rem;
  opacity: 1;
  transition: border-color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.md-footer__link:is(:hover, :focus) {
  border-color: var(--line-strong);
  transform: translateY(-2px);
}

.md-footer__direction {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
  opacity: 1;
}

.md-footer__title { color: var(--text); background: transparent; }

.md-copyright { color: var(--text-3); font-size: 0.66rem; }
.md-copyright__highlight { color: var(--text-3); }

.md-social__link { color: var(--text-3); transition: color var(--dur-1) var(--ease); }
.md-social__link:hover { color: var(--accent); }

/* ==========================================================================
   11. Home-page primitives

   The hero, KPI strip and terminal window from 3270.io, available to any page
   through md_in_html. The home pages use them; other pages can too.
   ========================================================================== */

/* --- Eyebrows, chips, status dots ---------------------------------------- */

.md-typeset .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 0.8rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-3);
}

.md-typeset .chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.md-typeset .chip.accent {
  border-color: var(--line-strong);
  background: var(--accent-soft);
  color: var(--accent);
}

.md-typeset .dot {
  position: relative;
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-3);
  flex: none;
}

.md-typeset .dot.live { background: var(--ok); box-shadow: 0 0 10px var(--ok); }

.md-typeset .dot.live::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid var(--ok);
  animation: t3270-halo 1.8s var(--ease-out) infinite;
}

@keyframes t3270-halo {
  0%   { transform: scale(0.7); opacity: 0.9; }
  100% { transform: scale(2.1); opacity: 0; }
}

/* --- Hero ---------------------------------------------------------------- */

.md-typeset .hero { margin: 0 0 2.6rem; }

/* The docs shell gives the hero roughly half the width the landing page has,
   so the display size is dialled back to keep the headline to two lines. */
.md-typeset .hero h1 {
  font-size: clamp(1.8rem, 3.6vw, 2.4rem);
  margin: 0 0 1rem;
}

.md-typeset .hero .grad {
  background: linear-gradient(100deg, var(--accent-2), var(--accent) 60%, var(--accent-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.md-typeset .hero .lede {
  font-size: 0.92rem;
  line-height: 1.7;
  color: var(--text-2);
  max-width: 40rem;
  text-wrap: pretty;
}

.md-typeset .hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.4rem;
}

.md-typeset .hero-actions .md-button { margin: 0; }

/* --- KPI strip ----------------------------------------------------------- */

.md-typeset .kpi-strip {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem;
  margin: 1.8rem 0;
}

@media screen and (min-width: 45em) {
  .md-typeset .kpi-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.md-typeset .kpi {
  position: relative;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  overflow: hidden;
}

.md-typeset .kpi::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
  opacity: 0.55;
}

.md-typeset .kpi .k {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3);
}

.md-typeset .kpi .v {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
}

.md-typeset .kpi .n {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.68rem;
  line-height: 1.4;
  color: var(--text-3);
}

/* --- Terminal window ----------------------------------------------------- */

.md-typeset .term {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-3);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  margin: 1.4rem 0;
}

.md-typeset .term-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}

.md-typeset .term-head .right { margin-left: auto; }

.md-typeset .term-body {
  margin: 0;
  padding: 0.9rem 1rem;
  background: transparent;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.8;
  color: var(--text-2);
  overflow-x: auto;
}

.md-typeset .term-body .sig { color: var(--accent); }
.md-typeset .term-body .tag { color: var(--ok); }
.md-typeset .term-body .tag.info { color: var(--info); }
.md-typeset .term-body .tag.warn { color: var(--warn); }
.md-typeset .term-body .cmt { color: var(--text-3); }

/* Blinking caret, same shape as the console's */
.md-typeset .caret {
  display: inline-block;
  width: 0.5em;
  height: 0.92em;
  margin-left: 0.14em;
  vertical-align: -0.1em;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
  animation: t3270-caret 1.1s steps(1) infinite;
}

@keyframes t3270-caret { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }

/* --- Glass panel & screenshot frame -------------------------------------- */

.md-typeset .panel {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-2);
  padding: 1.1rem 1.2rem;
  margin: 1.4rem 0;
  overflow: hidden;
}

/* Hairline sheen along the top edge — the console's signature */
.md-typeset .panel::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong) 25%, var(--line-strong) 75%, transparent);
  pointer-events: none;
}

/* --- Split layout for hero / secondary column ---------------------------- */

.md-typeset .split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.4rem;
  align-items: center;
}

@media screen and (min-width: 60em) {
  .md-typeset .split { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; }
}

.md-typeset .split > * { min-width: 0; }

/* ==========================================================================
   12. Motion preferences
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  body::after { animation: none; }
  .md-typeset .caret,
  .md-typeset .dot.live::after { animation: none; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
