/* IBM Plex, self-hosted (SIL Open Font License 1.1, public/fonts/OFL.txt).
   Generated by scripts/fetch-fonts.js; do not edit by hand. */
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-latin-ext-400.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-latin-400.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-latin-ext-500.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-latin-500.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-condensed-latin-ext-500.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-condensed-latin-500.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-condensed-latin-ext-600.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-condensed-latin-600.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-condensed-latin-ext-700.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/ibm-plex-sans-condensed-latin-700.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* synthetos.com: "Datasheet" design.
   Cool drafting white, ink rules and pencil blue; pages read like a well-made
   data sheet. Colour tokens are defined here (light) and overridden by
   src/themes/dark.css under [data-theme="dark"]. Fonts (IBM Plex) are
   self-hosted: src/fonts.css (scripts/fetch-fonts.js) goes first in the build. */
:root {
  --paper: #f6f8f9;
  --sheet: #ffffff;
  --ink: #15222c;
  --muted: #4f5f6a;
  --rule: #c7d2d9;
  --grid: #e3e9ed;
  --field: #8d9ca6;
  --blue: #1d5aa6;
  --blue-dk: #154680;
  --blue-wash: #e8f0f9;
  --on-blue: #ffffff;
  --ok: #1e7a45;
  --todo: #fff6d6;
  --foot-bg: #15222c;
  --foot-fg: #c9d4db;
  --foot-rule: #34434e;
  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --cond: "IBM Plex Sans Condensed", "Arial Narrow", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --max: 1180px;
  --prose: 72ch;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--paper);
  color: var(--ink);
  font: 400 1.0625rem/1.6 var(--sans);
  overflow-x: clip;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--blue); text-underline-offset: 3px; }
a:hover { color: var(--blue-dk); }
:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 20px; }

.skip-link { position: absolute; left: -9999px; }
.skip-link:focus {
  left: 16px; top: 16px; z-index: 20;
  background: var(--ink); color: var(--sheet); padding: 8px 14px;
}

/* ---------------------------------------------------------------- Type */
h1, h2, h3 {
  font-family: var(--cond);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em;
}
h1 { font-size: clamp(2rem, 4.4vw, 3.3rem); font-weight: 700; max-width: 26ch; }
h2 { font-size: clamp(1.45rem, 2.4vw, 1.9rem); margin-top: 2.2em; }
h3 { font-size: 1.25rem; margin-top: 1.6em; }
p { margin: 0 0 1em; }
main p, main ul, main ol { max-width: var(--prose); }
ul, ol { padding-left: 1.3em; margin: 0 0 1.2em; }
li { margin: 0.3em 0; }
li::marker { color: var(--muted); }
code {
  font-family: var(--mono);
  font-size: 0.9em;
  background: var(--grid);
  padding: 1px 6px;
  border-radius: 2px;
}
.lede { font-size: 1.2rem; color: var(--muted); margin-bottom: 1.4em; }
.byline { color: var(--muted); font: 400 0.92rem/1.5 var(--mono); }

/* Section headings inside pages are ruled like a data sheet. */
main > h2, main > section > h2, main > article > h2, .contact-grid > div > h2 {
  padding-bottom: 10px;
  border-bottom: 2px solid var(--ink);
  max-width: none;
}

/* ---------------------------------------------------------------- Header */
.site-header {
  background: var(--sheet);
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  z-index: 10;
}
.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 64px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  font: 700 1.3rem/1 var(--cond);
  text-decoration: none;
  flex: none;
}
.brand:hover { color: var(--ink); }
.brand-mark {
  width: 22px; height: 22px;
  border: 2px solid currentColor;
  border-radius: 50%;
  position: relative;
}
.brand-mark::before, .brand-mark::after { content: ""; position: absolute; background: currentColor; }
.brand-mark::before { left: -6px; right: -6px; top: 8px; height: 2px; }
.brand-mark::after { top: -6px; bottom: -6px; left: 8px; width: 2px; }

.site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
}
.site-nav a {
  display: block;
  padding: 8px 10px;
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.site-nav a:hover { color: var(--blue); }
.site-nav a[aria-current="page"] { border-bottom-color: var(--blue); }
.site-nav a.cta {
  margin-left: 8px;
  background: var(--blue);
  color: var(--on-blue);
  border: 2px solid var(--blue);
  border-radius: 2px;
  padding: 7px 16px;
  font-weight: 600;
}
.site-nav a.cta:hover { background: var(--blue-dk); border-color: var(--blue-dk); }

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-left: 6px;
  padding: 0;
  border: 1.5px solid var(--rule);
  border-radius: 2px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.theme-toggle:hover { border-color: var(--blue); color: var(--blue); }
.theme-toggle .icon-sun, .theme-toggle .icon-moon { display: none; }
[data-theme="light"] .theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }

/* Account control in the header slot (forumbot THEMING.md "Account control
   and the account slot"; filled by forumbot on forum pages and by the
   template's script elsewhere). Signed out: a Sign in link sized like the
   theme toggle. Signed in: the avatar opens a small menu that drops below
   the header (the slot sits outside the scrolling nav, so nothing clips it). */
.site-account { position: relative; display: flex; align-items: center; margin-left: 8px; flex: none; min-height: 36px; }
.site-account:empty { display: none; }
.forum-account { display: flex; align-items: center; min-height: 36px; }
.site-account .forum-signin, .forum-account-toggle {
  display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 12px;
  border: 1.5px solid var(--rule); border-radius: 2px; background: transparent;
  color: var(--ink); font: 600 0.95rem/1 var(--sans); text-decoration: none; white-space: nowrap; cursor: pointer;
}
.site-account .forum-signin::before {
  content: ""; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/svg%3E") center / contain no-repeat;
}
.site-account .forum-signin:hover, .forum-account-toggle:hover, .forum-account-menu[open] > .forum-account-toggle {
  border-color: var(--blue); color: var(--blue); background: transparent;
}
.forum-account-menu { position: relative; }
.forum-account-toggle { padding: 0 10px 0 5px; list-style: none; }
.forum-account-toggle::-webkit-details-marker { display: none; }
.forum-account-toggle::after {
  content: ""; width: 6px; height: 6px; margin: -3px 2px 0 0;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
.forum-account-menu[open] > .forum-account-toggle::after { transform: rotate(225deg); margin-top: 3px; }
.forum-account-avatar { width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--rule); }
.forum-account-login { max-width: 14ch; overflow: hidden; text-overflow: ellipsis; }
.forum-account-links {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; min-width: 230px;
  list-style: none; margin: 0; padding: 6px 0; max-width: none;
  background: var(--sheet); border: 1.5px solid var(--ink); box-shadow: 4px 4px 0 var(--grid);
}
.forum-account-links li { margin: 0; }
.forum-account-links li + li:has(.forum-signout) { border-top: 1px solid var(--rule); margin-top: 6px; padding-top: 6px; }
.forum-signout { margin: 0; }
.forum-account-links a, .forum-signout-button {
  display: flex; align-items: center; width: 100%; min-height: 40px; padding: 0 14px;
  background: none; border: 0; border-radius: 0; color: var(--ink);
  font: 500 0.95rem/1.2 var(--sans); text-align: left; text-decoration: none; cursor: pointer;
}
.forum-account-links a:hover, .forum-signout-button:hover { background: var(--blue-wash); color: var(--blue); }
.forum-account-links a:focus-visible, .forum-signout-button:focus-visible { outline-offset: -3px; }
@media (max-width: 1080px) {
  .forum-account-login { max-width: 10ch; }
}
@media (max-width: 420px) {
  .forum-account-login { display: none; }
}

/* ---------------------------------------------------------------- Main */
main.wrap { padding-top: 32px; padding-bottom: 80px; }

.breadcrumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0;
  margin: 0 0 20px;
  max-width: none;
  font: 400 0.88rem/1.4 var(--mono);
  color: var(--muted);
}
.breadcrumbs li { margin: 0; }
.breadcrumbs li + li::before { content: "/"; margin-right: 6px; color: var(--rule); }

/* ---------------------------------------------------------------- Buttons */
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 24px; max-width: none; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 20px;
  border: 2px solid var(--blue);
  border-radius: 2px;
  background: transparent;
  color: var(--blue);
  font: 600 1rem/1.2 var(--sans);
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}
.btn:hover { background: var(--blue-wash); color: var(--blue-dk); }
.btn-primary, button.btn { background: var(--blue); color: var(--on-blue); }
.btn-primary:hover, button.btn:hover { background: var(--blue-dk); border-color: var(--blue-dk); color: var(--on-blue); }
.btn-secondary { background: transparent; color: var(--blue); }
.btn[disabled] { opacity: 0.6; cursor: progress; }

/* ---------------------------------------------------------------- Home hero */
.home-hero {
  margin: -32px calc(50% - 50vw) 0;
  padding: 64px 0 56px;
  background-color: var(--sheet);
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 24px 24px;
  border-bottom: 1px solid var(--rule);
}
.hero-grid {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 20px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 48px;
  align-items: center;
}
.hero-copy h1 { font-size: clamp(2.1rem, 4.2vw, 3.4rem); }
.hero-copy .lede { color: var(--ink); opacity: 0.86; }
.hero-copy > * { background: var(--sheet); }
.hero-copy .actions { background: none; margin: 28px 0 0; }

.plot { margin: 0; background: var(--sheet); border: 1px solid var(--rule); padding: 16px 16px 12px; }
.plot svg { width: 100%; height: auto; overflow: visible; display: block; }
.plot-grid path { stroke: var(--grid); stroke-width: 1; fill: none; }
.plot .axis { stroke: var(--ink); stroke-width: 1.5; fill: none; }
.plot .axis-tip { fill: var(--ink); }
.plot .trap { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 6 6; fill: none; }
.plot .scurve {
  stroke: var(--blue); stroke-width: 4; fill: none; stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: 0;
  animation: draw 1.8s 0.3s cubic-bezier(0.45, 0, 0.2, 1) both;
}
@keyframes draw { from { stroke-dashoffset: 1; } }
.plot text { font: 400 15px var(--mono); fill: var(--muted); }
.plot .t-axis { fill: var(--ink); font-style: italic; }
.plot .callout path { stroke: var(--muted); fill: none; }
.plot .callout circle { fill: var(--muted); }
.plot .callout-s path { stroke: var(--blue); }
.plot .callout-s circle, .plot .callout-s text { fill: var(--blue); }
.plot figcaption { border-top: 1px solid var(--rule); margin-top: 8px; padding-top: 8px; }

/* ---------------------------------------------------------------- Cards: drawing sheets with a title block */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin: 28px 0;
}
.card {
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  display: flex;
  flex-direction: column;
}
.card > img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; border-bottom: 1px solid var(--rule); background: #fff; }
.card-body { padding: 22px 22px 0; display: flex; flex-direction: column; flex: 1; }
.card :is(h2, h3) { margin: 0 0 10px; font-size: 1.4rem; padding: 0; border: 0; }
.card :is(h2, h3) a { color: var(--ink); text-decoration: none; }
.card :is(h2, h3) a:hover { color: var(--blue); text-decoration: underline; }
.card p { color: var(--muted); font-size: 1rem; }
.card ul { list-style: none; padding: 0; margin: 4px 0 18px; font-size: 0.95rem; }
.card ul li { border-top: 1px solid var(--grid); padding: 6px 0; margin: 0; }
.card .price {
  margin: auto -22px 0;
  padding: 14px 22px 0;
  border-top: 1.5px solid var(--ink);
  font: 500 1.35rem/1.2 var(--mono);
  color: var(--ink);
}
.card .actions { margin: 12px 0 22px; }
.card a.more { font-weight: 600; }

/* ---------------------------------------------------------------- Why grid */
.why-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-left: 1px solid var(--rule);
  margin: 28px 0;
}
.why-grid > div { padding: 4px 22px 8px; border-right: 1px solid var(--rule); }
.why-grid h3 { margin-top: 0; font-size: 1.2rem; }
.why-grid p { color: var(--muted); font-size: 1rem; }

/* ---------------------------------------------------------------- Product page */
.product-top {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 32px;
  align-items: start;
  margin: 8px 0 32px;
}
.project-hero {
  margin: 0 0 24px;
  background: var(--sheet);
  border: 1px solid var(--rule);
  padding: 8px;
}
.product-top .project-hero { margin: 0; }
.project-hero img { background: #fff; }

.buybox {
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  padding: 0;
  margin: 0 0 24px;
}
.buybox > * { padding-left: 22px; padding-right: 22px; }
.buybox .price {
  font: 500 2rem/1.1 var(--mono);
  margin: 0;
  padding-top: 20px;
  padding-bottom: 6px;
}
.buybox .stock { color: var(--ok); font-weight: 600; margin: 0 0 16px; }
.buybox .actions { margin: 0; padding-bottom: 20px; }
.buybox .actions .btn { flex: 1; }
.buybox .note {
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-size: 0.95rem;
  margin: 0;
  padding-top: 14px;
  padding-bottom: 16px;
}

/* Spec and comparison tables */
.table-scroll { overflow-x: auto; margin: 0 0 28px; padding: 1px; }
.spec-table {
  width: 100%;
  border-collapse: collapse;
  border: 1.5px solid var(--ink);
  background: var(--sheet);
  font-size: 1rem;
}
.spec-table th, .spec-table td {
  text-align: left;
  vertical-align: top;
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
}
.spec-table thead th {
  background: var(--ink);
  color: var(--sheet);
  font: 600 0.98rem/1.3 var(--cond);
  border-bottom: 0;
}
.spec-table tbody th { font-weight: 600; min-width: 9em; width: 26%; }
.spec-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--grid) 35%, transparent); }

/* FAQ */
details.faq {
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
  padding: 0;
  margin: 0 0 10px;
  max-width: var(--prose);
}
details.faq summary {
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  padding: 14px 44px 14px 18px;
  position: relative;
}
details.faq summary::-webkit-details-marker { display: none; }
details.faq summary::after {
  content: "+";
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  font: 500 1.3rem/1 var(--mono);
  color: var(--blue);
}
details.faq[open] summary::after { content: "\2212"; }
details.faq[open] { border-left-color: var(--blue); }
details.faq > :not(summary) { margin: 0 18px 14px; }

/* Tags (g2core page) */
.tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 20px; }
.tag {
  border: 1px solid var(--rule);
  background: var(--sheet);
  padding: 2px 10px;
  font: 400 0.85rem/1.6 var(--mono);
  color: var(--muted);
}

/* Video thumbnail links (no third-party iframe until the visitor clicks) */
.video {
  display: block;
  position: relative;
  max-width: 560px;
  border: 1px solid var(--rule);
  background: var(--sheet);
  padding: 8px;
  margin: 0 0 10px;
  text-decoration: none;
}
.video img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.video::after {
  content: "Watch on YouTube";
  position: absolute;
  left: 22px;
  bottom: 22px;
  background: var(--ink);
  color: var(--sheet);
  padding: 8px 14px;
  font-weight: 600;
}
.video:hover::after { background: var(--blue); color: var(--on-blue); }

figure { margin: 0 0 28px; }
figure img { border: 1px solid var(--rule); background: var(--sheet); padding: 6px; }
figcaption { color: var(--muted); font: 400 0.85rem/1.45 var(--mono); margin-top: 8px; }

/* Call-to-action band */
.contact-block {
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  padding: 24px 26px;
  margin: 40px 0 16px;
}
.contact-block h2 { margin-top: 0; padding: 0; border: 0; }
.contact-block p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- Contact form */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 48px;
  align-items: start;
}
.contact-grid > div > h2:first-child { margin-top: 0.4em; }
.form {
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  position: relative;
}
.form h2 { margin: 0; padding: 0; border: 0; font-size: 1.4rem; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-weight: 600; }
input, select, textarea {
  font: inherit;
  color: var(--ink);
  background: var(--sheet);
  border: 1.5px solid var(--field);
  border-radius: 2px;
  padding: 10px 12px;
  width: 100%;
}
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--blue); outline-offset: 0; }
.turnstile-slot { min-height: 65px; }
.form .btn { align-self: flex-start; }
.form-status { border-left: 4px solid var(--blue); background: var(--blue-wash); padding: 12px 14px; margin: 0; }
.form-status[data-state="error"] { border-left-color: #b3261e; background: color-mix(in srgb, #b3261e 10%, var(--sheet)); }
.form-status[data-state="ok"] { border-left-color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, var(--sheet)); }
.fallback { border-left: 3px solid var(--blue); padding-left: 14px; }

/* ---------------------------------------------------------------- Footer */
.site-footer {
  background: var(--foot-bg);
  color: var(--foot-fg);
  padding: 56px 0 24px;
  font-size: 0.97rem;
}
.site-footer a { color: #fff; }
.site-footer .cols {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 32px;
}
.foot-brand { font: 700 1.3rem/1.2 var(--cond); color: #fff; margin: 0 0 8px; }
.site-footer h2 { font-size: 1rem; color: #fff; margin: 0 0 10px; }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 4px; }
.site-footer li { margin: 0; }
.site-footer .cols p { max-width: 42ch; }
.fineprint {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin: 40px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--foot-rule);
  font: 400 0.85rem/1.4 var(--mono);
}

/* ---------------------------------------------------------------- Responsive */
@media (max-width: 1080px) {
  .site-header .wrap { flex-wrap: wrap; gap: 0 12px; padding-top: 8px; }
  .site-nav { order: 3; width: 100%; margin: 0 -10px; overflow-x: auto; scrollbar-width: none; }
  .site-nav .theme-toggle { margin-left: auto; flex: none; }
  .site-header { position: static; }
  .header-shop { order: 2; margin-left: 0; }
  /* The account control sits on the top row, before the Shop button. */
  .site-account { order: 1; margin-left: auto; }
  /* The header Shop button replaces the nav one when the nav wraps. */
  .site-nav .cta { display: none; }
}
@media (min-width: 1081px) { .header-shop { display: none; } }
@media (max-width: 960px) {
  .hero-grid, .product-top, .contact-grid { grid-template-columns: minmax(0, 1fr); }
  .why-grid { grid-template-columns: 1fr 1fr; }
  .why-grid > div { border-bottom: 1px solid var(--rule); padding-top: 16px; }
  .site-footer .cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .wrap { padding: 0 16px; }
  .hero-grid { padding: 0 16px; }
  .home-hero { padding: 36px 0 40px; margin-top: -24px; }
  main.wrap { padding-top: 24px; }
  .plot { padding: 10px; }
  .plot text { font-size: 19px; }
  .why-grid, .site-footer .cols { grid-template-columns: 1fr; }
  .spec-table, .spec-table tbody, .spec-table tr, .spec-table th, .spec-table td { font-size: 0.95rem; }
  .table-scroll .spec-table:not(:has(thead)) tr { display: grid; padding: 10px 14px; border-bottom: 1px solid var(--rule); }
  .table-scroll .spec-table:not(:has(thead)) :is(th, td) { padding: 0; border: 0; width: auto; }
  .form { padding: 20px; }
  .card-body { padding: 18px 18px 0; }
  .card .price { margin: auto -18px 0; padding: 14px 18px 0; }
}
@media (prefers-reduced-motion: reduce) {
  .plot .scurve { animation: none; }
}

/* Stock line next to a card price */
.card .price .stock { font: 600 0.9rem/1 var(--sans); color: var(--ok); margin-left: 8px; }

/* ---------------------------------------------------------------- Forum archive */
.archive-banner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  border: 1.5px solid var(--ink);
  background: var(--sheet);
  margin: 0 0 28px;
}
.archive-note { padding: 16px 20px; border-left: 4px solid var(--blue); }
.archive-note p { margin: 0 0 6px; font-size: 0.97rem; max-width: 70ch; }
.archive-note p:last-child { margin: 0; }
.archive-note p.archive-ask { margin-top: 12px; }
.archive-buy {
  padding: 16px 20px;
  border-left: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  min-width: 220px;
}
.archive-buy p { margin: 0; }
.archive-buy-name { font-weight: 600; }
.archive-buy-price { font: 500 1.25rem/1.2 var(--mono); }
.archive-buy-price .stock { font: 600 0.85rem/1 var(--sans); color: var(--ok); margin-left: 6px; }
.archive-buy .btn { min-height: 40px; align-self: flex-start; }

.h1-page { font-weight: 500; color: var(--muted); font-size: 0.55em; white-space: nowrap; }
.topic-meta, .topic-foot { color: var(--muted); font-size: 0.97rem; }
.topic-meta .badge { margin-left: 4px; }

/* Topic lists (archive and live): the title reads as the row's link, the
   badges sit apart from it, and a row lights up under the pointer. */
.topic-table td { vertical-align: top; }
.topic-table .num { text-align: right; width: 6em; font-family: var(--mono); }
.topic-table .nowrap { white-space: nowrap; width: 9em; font-family: var(--mono); font-size: 0.92rem; }
.topic-table td:first-child > a:first-child { font-weight: 600; text-decoration: none; }
.topic-table td:first-child > a:first-child:hover { text-decoration: underline; }
.topic-table td:first-child > .badge { margin-left: 8px; vertical-align: 2px; }
.topic-table tbody tr:hover { background: color-mix(in srgb, var(--blue-wash) 60%, var(--sheet)); }
.topic-table .m-label { display: none; }
.row-meta { display: block; color: var(--muted); font-size: 0.9rem; margin-top: 2px; }

.pager { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 20px; font-family: var(--mono); font-size: 0.95rem; }
.pager a, .pager span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 10px;
  border: 1.5px solid var(--rule); background: var(--sheet); text-decoration: none;
}
.pager a:hover { border-color: var(--blue); }
.pager [aria-current] { background: var(--ink); color: var(--sheet); border-color: var(--ink); }
.pager .pager-gap { border-color: transparent; background: none; min-width: 20px; }

/* ---- Threads: the opening post, then a "Replies" rule, then one group per
   top-level reply. forumbot wraps each top-level reply and its replies in
   div.post-thread > article.post + div.post-replies, so nested replies get a
   real indent and connector rail, and groups alternate a faint tint so one
   conversation reads as one block. The rule is the list's ::after moved up
   to sit right after the opening post. Archive topics stay a flat list. */
.posts { display: grid; gap: 14px; margin: 0 0 24px; }
.post { background: var(--post-bg, var(--sheet)); border: 1px solid var(--rule); scroll-margin-top: 80px; position: relative; min-width: 0; }
/* Arriving at #post-<id>: a soft ring that fades, not a selection outline. */
.post:target { animation: post-target 2.8s ease-out 1; }
@keyframes post-target {
  0%, 30% { outline: 3px solid color-mix(in srgb, var(--blue) 45%, transparent); outline-offset: 3px; background-color: color-mix(in srgb, var(--blue-wash) 85%, var(--sheet)); }
  100% { outline: 3px solid transparent; outline-offset: 3px; }
}
.post-thread { display: grid; gap: 10px; min-width: 0; }
.post-thread:nth-of-type(even) { --post-bg: color-mix(in srgb, var(--grid) 55%, var(--sheet)); }
.post-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px;
  padding: 10px 18px; border-bottom: 1px solid var(--grid);
}
.post-author { font-weight: 600; }
.badge { display: inline-block; font: 600 0.78rem/1.6 var(--sans); padding: 0 8px; border: 1px solid var(--blue); color: var(--blue); white-space: nowrap; }
.post-head time { font: 400 0.88rem/1.4 var(--mono); color: var(--muted); }
.post-link {
  order: 3; margin-left: auto; font: 400 0.85rem/1.4 var(--mono); color: var(--muted); text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; min-width: 32px; min-height: 32px; margin-block: -6px;
}
.post-link:hover { color: var(--blue); }
.post-body { padding: 14px 18px 4px; overflow-wrap: anywhere; }
.post-body p, .post-body ul, .post-body ol { max-width: 76ch; }
.post-body blockquote { margin: 0 0 1em; padding: 4px 0 4px 16px; border-left: 3px solid var(--rule); color: var(--muted); }
.post-body pre {
  margin: 0 0 1em;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
  overflow-x: auto;
  font: 400 0.88rem/1.5 var(--mono);
  white-space: pre;
  overflow-wrap: normal;
}
.post-body pre code { background: none; padding: 0; font-size: inherit; }
.post-body img { max-width: 100%; height: auto; border: 1px solid var(--rule); margin: 4px 0; }
.post-body h3, .post-body h4 { font-size: 1.1rem; margin: 1em 0 0.4em; }
.post-body table { border-collapse: collapse; margin: 0 0 1em; display: block; overflow-x: auto; }
.post-body th, .post-body td { border: 1px solid var(--rule); padding: 6px 10px; }
.post-body input[type="checkbox"] { width: auto; margin: 0 6px 0 0; }

/* The opening post: the heaviest sheet, with a title-block header. */
.post-lead { order: -2; border: 1.5px solid var(--ink); }
.post-lead > .post-head { background: color-mix(in srgb, var(--grid) 70%, var(--sheet)); border-bottom: 1.5px solid var(--ink); }
.post-lead > .post-head::before {
  content: "Opening post"; order: -1;
  font: 600 0.72rem/1.6 var(--mono); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--sheet); background: var(--ink); padding: 0 7px;
}
.post-lead > .post-body { padding-top: 16px; font-size: 1.04rem; }
.posts:has(> .post:not(.post-lead), > .post-thread)::after {
  content: "Replies"; order: -1;
  display: flex; align-items: center; gap: 12px; margin: 14px 0 0;
  font: 600 0.8rem/1 var(--mono); text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted);
  border-bottom: 2px solid var(--ink); padding-bottom: 8px;
}
/* Legacy staff posts from the archive export. */
.post-staff { border-left: 4px solid var(--blue); }
/* The accepted answer. */
.post-answer { border: 2px solid var(--ok); }
.post-answer > .post-head { background: color-mix(in srgb, var(--ok) 10%, var(--sheet)); border-bottom-color: color-mix(in srgb, var(--ok) 35%, var(--sheet)); }
.post-answer .badge { border-color: var(--ok); background: var(--ok); color: var(--sheet); }
.post-answer .badge::before { content: "\2713\00a0"; }
/* Nested replies: one step in, a touch smaller, each hung off a rail that
   drops from the reply they belong to. The rail is drawn per reply (an elbow
   into the card, and a run on to the next one) so it stops at the last reply.
   --rail is --field: visible against the paper in both themes. */
.post-replies { display: grid; gap: 10px; margin-left: 40px; min-width: 0; --rail: var(--field); }
.post-reply { font-size: 0.96rem; }
.post-replies > .post-reply::before {
  content: ""; position: absolute; left: -24px; top: -11px; height: calc(11px + 22px); width: 16px;
  border-left: 2px solid var(--rail); border-bottom: 2px solid var(--rail); border-bottom-left-radius: 6px;
}
.post-replies > .post-reply:not(:last-child)::after {
  content: ""; position: absolute; left: -24px; top: 20px; bottom: -11px; border-left: 2px solid var(--rail);
}
/* Pages cached before the groups existed: replies follow their reply as siblings. */
.posts > .post-reply { margin-left: 40px; box-shadow: -14px 0 0 -12px var(--rail, var(--field)); }
.post-reply > .post-head { padding: 7px 14px; }
.post-reply > .post-body { padding: 10px 14px 2px; }
/* "↳ replying to @login": the first line of a nested reply. */
.post-context { margin: 0; padding: 8px 14px 0; max-width: none; font: 400 0.82rem/1.4 var(--mono); color: var(--muted); }
.post-context a { color: var(--blue); text-decoration: none; font-weight: 600; }
.post-context a:hover { text-decoration: underline; }
.post-context + .post-head { padding-top: 4px; }
/* The inline composer, while it replies inside a group, sits with the replies. */
.post-thread > .composer { margin-left: 40px; }

/* The viewer's own posts (set in the browser from /me, never served): a
   blue-washed sheet, an accent bar and a "You" chip after the name. */
.post-own { --post-bg: color-mix(in srgb, var(--blue-wash) 70%, var(--sheet)); box-shadow: inset 4px 0 0 var(--blue); }
.post-own:not(.post-answer):not(.post-lead) { border-color: color-mix(in srgb, var(--blue) 45%, var(--rule)); }
.post-own:not(.post-answer):not(.post-lead) > .post-head { border-bottom-color: color-mix(in srgb, var(--blue) 25%, var(--sheet)); }
.post-own .post-author::after {
  content: "You"; display: inline-block; margin-left: 8px; vertical-align: 1px;
  font: 600 0.68rem/1.6 var(--mono); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--on-blue); background: var(--blue); padding: 0 6px;
}

/* Thread page extras. */
/* Each post ends in one quiet action row: Reply, then the viewer's Edit and
   Delete (added in the browser with .post-own; a moderator gets Delete on
   every post). All three are the same text-and-icon action, under a hairline
   divider, their text aligned with the post body. Delete stays quiet until
   hovered or focused, then turns the error red (--danger, as form-status). */
:root { --danger: #b3261e; --on-danger: #ffffff; }
[data-theme="dark"] { --danger: #ff8a80; --on-danger: #0d161d; }
.post-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px;
  padding: 4px 10px; border-top: 1px solid var(--grid);
}
.post-reply > .post-actions { padding: 2px 6px; }
.post-actions:empty { display: none; }
.post-reply-link, .post-edit, .post-delete {
  display: inline-flex; align-items: center; gap: 6px; min-height: 38px; padding: 0 8px; margin: 0;
  background: none; border: 0; border-radius: 2px; cursor: pointer;
  font: 500 0.9rem/1 var(--sans); color: var(--muted); text-decoration: none;
  transition: background-color 0.12s, color 0.12s;
}
.post-reply-link::before, .post-edit::before, .post-delete::before {
  content: ""; flex: none; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat;
}
.post-reply-link { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 14L4 9l5-5'/%3E%3Cpath d='M4 9h10a6 6 0 0 1 6 6v5'/%3E%3C/svg%3E"); }
.post-edit { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h4L19 9l-4-4L4 16z'/%3E%3Cpath d='M13.5 6.5l4 4'/%3E%3C/svg%3E"); }
.post-delete { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7h16M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3'/%3E%3C/svg%3E"); }
.post-reply-link:hover, .post-edit:hover { color: var(--blue); background: var(--blue-wash); }
.post-reply-link:focus-visible, .post-edit:focus-visible { color: var(--blue); outline-offset: -1px; }
.post-delete:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.post-delete:focus-visible { color: var(--danger); outline-color: var(--danger); outline-offset: -1px; }
.post-edit[disabled] { opacity: 0.6; cursor: progress; }
/* While its editor is open a post shows only the editor: no body (forumbot
   hides it), no action row. */
.post:has(> .post-editor) > .post-actions { display: none; }
/* "edited" after the time, from GitHub's lastEditedAt or a just-saved edit. */
.post-edited {
  font: 400 0.78rem/1.4 var(--mono); color: var(--muted); letter-spacing: 0.02em;
  border-bottom: 1px dotted color-mix(in srgb, var(--muted) 60%, transparent);
}
.post-edited[title] { cursor: help; }
/* Why the editor could not open (not your post, gone): under the body. */
.post-action-status {
  margin: 0 18px 12px; max-width: none; padding: 8px 12px;
  border-left: 4px solid var(--danger); background: color-mix(in srgb, var(--danger) 10%, var(--sheet));
  color: var(--danger); font-size: 0.92rem; font-weight: 500;
}
.post-reply > .post-action-status { margin: 0 14px 10px; }
/* The editor, in place of the post body: no extra frame, just the composer's
   framed instrument inside the post's padding, under a small "Editing" head.
   The body field's own label ("Edit your post") stays as its accessible name
   but is hidden visually; the head says the same. */
.composer-edit {
  display: flex; flex-direction: column; gap: var(--gap); margin: 0; padding: 14px 18px 16px; border: 0; background: transparent; --gap: 12px;
}
.post-reply > .composer-edit { padding: 10px 14px 14px; }
.composer-edit::before {
  content: "Editing your post"; display: flex; align-items: center; gap: 8px;
  font: 600 0.75rem/1.2 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; color: var(--blue);
}
.post-lead > .composer-edit::before { content: "Editing your question"; }
.composer-edit > label[for^="fb-reply-body"] {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; margin: 0;
}
.composer-title { font: 600 1.1rem/1.3 var(--sans); padding: 10px 12px; margin-top: -4px; }
.composer-edit .composer-actions { padding-top: 2px; }

/* Delete confirmation: a modal sheet, centred, with a red title rule. Fits a
   phone (16 px gutters, scrolls inside when the reason field is open). */
.post-delete-dialog {
  width: min(34rem, calc(100vw - 32px)); max-width: none; max-height: calc(100dvh - 32px); overflow: auto;
  margin: auto; padding: 20px 24px 22px;
  background: var(--sheet); color: var(--ink);
  border: 1.5px solid var(--ink); border-top: 5px solid var(--danger); border-radius: 2px;
  box-shadow: 6px 6px 0 color-mix(in srgb, var(--ink) 22%, transparent);
}
.post-delete-dialog::backdrop {
  background: rgba(13, 22, 29, 0.55);
  background-image: linear-gradient(rgba(125, 176, 245, 0.08) 1px, transparent 1px), linear-gradient(90deg, rgba(125, 176, 245, 0.08) 1px, transparent 1px);
  background-size: 24px 24px;
}
.post-delete-heading { margin: 0 0 8px; font-size: 1.45rem; max-width: none; }
.post-delete-text { margin: 0 0 16px; color: var(--muted); max-width: none; }
.post-delete-dialog label { display: block; margin: 0 0 6px; font-weight: 600; font-size: 0.95rem; }
.post-delete-reason { display: block; min-height: calc(2 * 1.6em + 22px); resize: vertical; margin: 0 0 12px; }
.post-delete-status { margin: 0 0 14px; padding: 10px 12px; border-left-color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, var(--sheet)); color: var(--danger); font-size: 0.92rem; font-weight: 500; }
.post-delete-status:empty { margin: 0; padding: 0; border: 0; }
.post-delete-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px 12px; padding-top: 16px; border-top: 1px solid var(--rule); }
.post-delete-actions .btn { min-width: 112px; min-height: 44px; }
.post-delete-dialog button.btn-secondary { background: transparent; color: var(--blue); }
.post-delete-dialog button.btn-secondary:hover { background: var(--blue-wash); color: var(--blue-dk); border-color: var(--blue); }
.post-delete-confirm.btn { background: var(--danger); border-color: var(--danger); color: var(--on-danger); }
.post-delete-confirm.btn:hover { background: color-mix(in srgb, var(--danger) 82%, var(--ink)); border-color: color-mix(in srgb, var(--danger) 82%, var(--ink)); color: var(--on-danger); }
.post-delete-confirm:focus-visible { outline-color: var(--danger); }
@media (max-width: 480px) {
  .post-delete-dialog { padding: 18px 16px 16px; }
  .post-delete-heading { font-size: 1.3rem; }
  .post-delete-actions { flex-direction: column-reverse; }
  .post-delete-actions .btn { width: 100%; }
}

/* Read-your-writes: a post or row the viewer just made. A soft bar and a
   chip, not an outline (an outline reads as an error or a selection). */
.post.fb-just-posted { box-shadow: inset 4px 0 0 var(--ok); animation: fb-just-posted 2.4s ease-out 1; }
.post.fb-just-posted > .post-head::after {
  content: "Just posted"; order: 2;
  font: 600 0.72rem/1.6 var(--mono); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ok); border: 1px solid currentColor; padding: 0 7px;
}
tr.fb-just-posted { box-shadow: inset 4px 0 0 var(--ok); animation: fb-just-posted 2.4s ease-out 1; }
@keyframes fb-just-posted { from { background-color: color-mix(in srgb, var(--ok) 16%, var(--sheet)); } }
.fb-new-replies {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 15;
  background: var(--ink); color: var(--sheet); padding: 10px 18px; border-radius: 2px;
  box-shadow: 4px 4px 0 var(--blue); font-size: 0.95rem;
}
.fb-new-replies a, .fb-new-replies button { color: inherit; font-weight: 600; }

/* ---- Live forum pages (forumbot, rendered into /_forumbot/shell). Every
   forumbot page puts form.forum-search right after the breadcrumbs, so
   main:has(> .forum-search) scopes the forum layout without a shell class. */
.forum-ask { margin: 0 0 24px; }
.forum-ask .btn { background: var(--blue); color: var(--on-blue); }
.forum-ask .btn:hover { background: var(--blue-dk); border-color: var(--blue-dk); color: var(--on-blue); }

/* /forum/ front page (static, src/forum.js): ask + search, category cards
   with board chips, latest activity, earlier discussions by board. */
.forum-home-head { margin: 0 0 8px; }
.forum-home-head h1 { font-size: clamp(2rem, 3.6vw, 2.8rem); margin-bottom: 0.3em; }
.forum-home-head .lede { margin-bottom: 20px; }
.forum-home-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.forum-home-actions > .btn { min-height: 44px; }
.forum-home-actions .forum-search { flex: 1 1 320px; max-width: 480px; margin: 0; }
.forum-categories {
  list-style: none; margin: 0 0 8px; padding: 0; max-width: none;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 14px;
}
.forum-category {
  margin: 0; display: flex; flex-direction: column;
  background: var(--sheet); border: 1px solid var(--rule); border-top: 3px solid var(--ink); padding: 16px 18px 18px;
}
.forum-category:hover { border-color: var(--field); border-top-color: var(--blue); }
.forum-category h3 { margin: 0 0 6px; font-size: 1.3rem; }
.forum-category h3 a { text-decoration: none; color: var(--ink); }
.forum-category h3 a:hover { color: var(--blue); text-decoration: underline; }
.forum-category h3 a::after { content: " \2192"; color: var(--blue); }
.forum-category p { margin: 0 0 12px; color: var(--muted); font-size: 0.95rem; }
.forum-category .board-chips-label { margin: auto 0 6px; font: 600 0.72rem/1.4 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; }
.board-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.board-chips li { margin: 0; }
.board-chip {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 10px;
  border: 1px solid var(--rule); border-radius: 2px; background: var(--paper);
  font: 500 0.85rem/1 var(--sans); color: var(--ink); text-decoration: none;
}
.board-chip:hover { border-color: var(--blue); color: var(--blue); }
.board-chip-count { font: 400 0.78rem/1 var(--mono); color: var(--muted); }
.forum-latest-list:empty { display: none; }
.forum-latest-list .table-scroll { margin-bottom: 12px; }
.forum-more { margin: 0 0 8px; font-weight: 600; }
.forum-more a::after { content: " \2192"; }
.forum-earlier > p { color: var(--muted); }
.forum-earlier h3 { font-size: 1.2rem; margin: 1.4em 0 0.6em; }
.forum-earlier h3 a { color: var(--ink); text-decoration: none; }
.forum-earlier h3 a:hover { color: var(--blue); text-decoration: underline; }
/* The same front page rendered by forumbot (unified forum): latest activity is
   server-rendered, and popular topics per board replace the static by-board tables. */
.forum-latest > .topic-table, .forum-latest > .table-scroll { margin-bottom: 12px; }
.forum-popular h3 { font-size: 1.2rem; margin: 1.4em 0 0.6em; }
.forum-popular h3 a { color: var(--ink); text-decoration: none; }
.forum-popular h3 a:hover { color: var(--blue); text-decoration: underline; }
.forum-popular-list { list-style: none; margin: 0 0 8px; padding: 0; border-top: 1px solid var(--rule); }
.forum-popular-list li { margin: 0; padding: 10px 0; border-bottom: 1px solid var(--rule); overflow-wrap: anywhere; }
.forum-popular-list li > a { font-weight: 600; text-decoration: none; }
.forum-popular-list li > a:hover { text-decoration: underline; }
.forum-popular-list .row-meta { display: block; margin-top: 2px; color: var(--muted); font: 400 0.85rem/1.4 var(--mono); }
.forum-popular > p:last-child { margin-top: 16px; font-weight: 600; }
.forum-popular > p:last-child a::after { content: " \2192"; }
@media (max-width: 760px) {
  .forum-home-actions > .btn { flex: 1 1 100%; }
  .forum-home-actions .forum-search { flex: 1 1 100%; max-width: none; }
  .board-chip { min-height: 40px; }
}

main:has(> .forum-search) h1 { font-size: clamp(1.8rem, 3.2vw, 2.5rem); max-width: 34ch; margin-bottom: 0.4em; }
main:has(> .forum-search) > .breadcrumbs ol { margin: 0; }

/* Forum nav bar: breadcrumbs on the left, search on the right, one rule
   under both. Phones stack them. */
.forum-search { position: relative; display: flex; margin: 0 0 28px; max-width: 520px; }
.forum-search::before {
  content: ""; position: absolute; left: 13px; top: 13px; width: 18px; height: 18px;
  background: var(--muted); pointer-events: none;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='M20 20l-4.4-4.4'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='M20 20l-4.4-4.4'/%3E%3C/svg%3E") center / contain no-repeat;
}
.forum-search input {
  flex: 1; min-width: 0; height: 44px; padding: 0 12px 0 38px;
  border-right: 0; border-radius: 2px 0 0 2px; font-size: 0.98rem;
}
.forum-search .btn, .search-form .btn {
  flex: none; min-height: 44px; height: 44px; padding: 0 18px; border-radius: 0 2px 2px 0; font-size: 0.95rem;
}
.forum-search .btn {
  border: 1.5px solid var(--field); background: color-mix(in srgb, var(--grid) 70%, var(--sheet)); color: var(--ink);
}
.forum-search .btn:hover { background: var(--blue); border-color: var(--blue); color: var(--on-blue); }
.forum-search input:focus-visible { position: relative; z-index: 1; }
@media (min-width: 761px) {
  main:has(> .forum-search) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 24px; }
  main:has(> .forum-search) > * { grid-column: 1 / -1; min-width: 0; }
  main:has(> .forum-search)::before {
    content: ""; grid-row: 1; grid-column: 1 / -1; align-self: end;
    border-bottom: 1px solid var(--rule); margin-bottom: 28px;
  }
  main:has(> .forum-search) > .breadcrumbs { grid-row: 1; grid-column: 1; align-self: center; margin-bottom: 28px; padding-bottom: 14px; }
  main:has(> .forum-search) > .forum-search { grid-row: 1; grid-column: 2; width: clamp(280px, 30vw, 380px); padding-bottom: 14px; margin-bottom: 28px; }
}

/* Search page (<p>/search/). */
.search-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; max-width: 640px; margin: 0 0 20px; }
.search-form label { grid-column: 1 / -1; font-weight: 600; margin-bottom: 6px; }
.search-form input { height: 44px; border-radius: 2px 0 0 2px; }
.search-filters { color: var(--muted); font-size: 0.95rem; }
.search-results { list-style: none; margin: 0 0 24px; padding: 0; max-width: none; border-top: 1px solid var(--rule); }
.search-result { margin: 0; padding: 16px 0; border-bottom: 1px solid var(--rule); }
.search-title { margin: 0 0 4px; font-size: 1.2rem; }
.search-title a { text-decoration: none; }
.search-title a:hover { text-decoration: underline; }
.search-result .topic-meta { margin: 0 0 6px; font-size: 0.9rem; }
.search-snippet { margin: 0; }
.search-snippet mark { background: color-mix(in srgb, var(--blue) 22%, transparent); color: inherit; padding: 0 2px; }
.search-continued { margin: 6px 0 0; font-size: 0.92rem; }
.badge-archive { border-color: var(--field); color: var(--muted); }
.badge-pinned { border-color: var(--ink); color: var(--ink); }

/* ---- Composer (forumbot markup contract: forumbot docs/THEMING.md,
   COMPOSER_PLAN §6.2). The reply box under a thread, the ask page
   (/forum/new/), the no-JS reply form (/forum/t/N/reply/) and the account
   page. forumbot sets only the inline grid styles that keep the reply area
   one height; the boot script toggles [hidden], so nothing here may
   override it. */
.reply-area [hidden], .composer [hidden], .similar-list[hidden] { display: none !important; }
/* One grid cell (forumbot sets display:grid inline); minmax(0, 1fr) keeps the
   toolbar from widening the cell past the column on a phone. */
.reply-area { margin: 32px 0 24px; grid-template-columns: minmax(0, 1fr); }
.reply-area > * { min-width: 0; max-width: none; }
/* Signed out (and before the boot script runs) the cell keeps the hidden
   composer's height, so the Reply link fills it as a drafting-sheet panel
   instead of leaving a blank gap. */
.reply-area-foot {
  margin: 0; display: flex; flex-wrap: wrap; align-content: center; align-items: center; justify-content: center; gap: 12px;
  padding: 28px 20px; text-align: center; color: var(--muted);
  border: 1.5px dashed var(--field);
  background-color: var(--sheet);
  background-image: linear-gradient(color-mix(in srgb, var(--grid) 60%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--grid) 60%, transparent) 1px, transparent 1px);
  background-size: 24px 24px; background-position: -1px -1px;
}
.reply-area-foot::before {
  content: "Join the discussion"; flex: 1 1 100%;
  font: 600 1.35rem/1.2 var(--cond); color: var(--ink);
}
.reply-area[data-locked] .reply-area-foot::before { content: none; }
.reply-area-foot .btn { background-color: var(--sheet); }
.reply-area-foot .btn:not(.btn-secondary) { background-color: var(--blue); }
.composer-notice {
  margin: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px;
  padding: 24px 20px; text-align: center;
  border: 1.5px solid var(--blue); background: var(--blue-wash);
}

.composer { --gap: 18px; }
.composer-reply, .composer-form {
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  padding: 22px 24px;
  display: flex; flex-direction: column; gap: var(--gap);
}
.composer-reply { --gap: 12px; padding: 16px 20px 18px; }
section.composer { max-width: 880px; }
section.composer > h1 { margin-bottom: 0.5em; }
section.composer > .error-summary, section.composer > .composer-related { margin-bottom: 16px; }
/* Signed out, nothing to post in, or text to rescue: a short notice card. */
section.composer:not(:has(form)) {
  max-width: 640px; background: var(--sheet); border: 1.5px solid var(--ink); border-top: 4px solid var(--blue);
  padding: 24px 28px 8px;
}
section.composer:not(:has(form)) > h1 { font-size: clamp(1.6rem, 2.6vw, 2rem); }
section.composer:not(:has(form)) .btn { min-width: 220px; }
.composer label { font-weight: 600; }
.composer-form .field { gap: 8px; }
.composer-form .field > label:not(.category-option), .category-picker legend { font: 600 1rem/1.3 var(--sans); color: var(--ink); }
:is(.composer-reply, .composer-edit) > label {
  font: 600 0.75rem/1.2 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin-bottom: -4px;
}
.composer-who { display: flex; align-items: center; gap: 10px; margin: 0; min-height: 32px; font-size: 0.95rem; color: var(--muted); }
.composer-avatar { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--rule); }
.composer-context, .composer-related {
  margin: 0; padding: 8px 12px; border-left: 3px solid var(--blue); background: var(--blue-wash); font-size: 0.95rem;
}
.composer-cancel, .composer-discard {
  background: none; border: 0; padding: 0 4px; margin-left: 6px; min-height: 32px;
  font: inherit; font-weight: 600; color: var(--blue); text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.composer-cancel:hover, .composer-discard:hover { color: var(--blue-dk); }

/* The editor: tabs, toolbar, textarea and preview drawn as one framed
   instrument. Without the script (no tabs, no toolbar) the textarea keeps
   its own full border. */
.composer-tabs {
  display: flex; gap: 0; padding: 0 6px;
  border: 1.5px solid var(--field); border-bottom: 1px solid var(--rule);
  background: color-mix(in srgb, var(--grid) 55%, var(--sheet));
}
.composer-tab {
  position: relative; min-height: 44px; padding: 0 16px;
  background: transparent; color: var(--muted); border: 0; border-radius: 0;
  font: 600 0.9rem/1 var(--sans); cursor: pointer;
}
.composer-tab:hover { color: var(--ink); }
.composer-tab[aria-selected="true"] { color: var(--ink); }
.composer-tab[aria-selected="true"]::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 3px; background: var(--blue);
}
.composer-tab:focus-visible { outline-offset: -3px; }
.composer-write { display: flex; flex-direction: column; gap: 0; }
.composer-form .field > .composer-tabs:not([hidden]) ~ :is(.composer-write, .composer-preview) { margin-top: -8px; }
:is(.composer-reply, .composer-edit) > .composer-tabs ~ :is(.composer-write, .composer-preview) { margin-top: calc(-1 * var(--gap)); }
.composer-tools {
  position: relative; display: flex; align-items: center; gap: 0; padding: 0 4px;
  border: 1.5px solid var(--field); border-bottom: 1px solid var(--grid);
  background: var(--sheet);
}
.composer-tabs:not([hidden]) + .composer-write > .composer-tools { border-top: 0; }
.composer-toolbar { display: flex; gap: 0; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.composer-toolbar::-webkit-scrollbar { display: none; }
/* Icon buttons: the visible name stays in the DOM (font-size 0) as the
   accessible name; the icon is a mask so it takes the theme colour. */
.composer-tool {
  position: relative; flex: none; min-width: 44px; min-height: 44px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; color: var(--muted); border: 0; border-radius: 2px;
  font: 600 0.95rem/1 var(--mono); cursor: pointer;
}
.composer-toolbar .composer-tool { font-size: 0; }
.composer-toolbar .composer-tool::before {
  content: ""; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat;
}
.composer-tool:hover { background: var(--blue-wash); color: var(--blue); }
.composer-tool:focus-visible { outline-offset: -3px; }
.composer-tool[data-md-button="code"], .composer-tool[data-md-button="unordered-list"] { margin-left: 9px; }
.composer-tool[data-md-button="code"]::after, .composer-tool[data-md-button="unordered-list"]::after {
  content: ""; position: absolute; left: -5px; top: 12px; bottom: 12px; border-left: 1px solid var(--rule);
}
.composer-tool[data-md-button="header-3"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 5v14M18 5v14M6 12h12'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="bold"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="italic"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 5h8M6 19h8M14 5l-4 14'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="quote"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 5v14M10 8h9M10 12h9M10 16h6'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="code"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 7l-5 5 5 5M16 7l5 5-5 5'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="link"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="unordered-list"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6h11M9 12h11M9 18h11'/%3E%3Cpath d='M4.5 6h.01M4.5 12h.01M4.5 18h.01' stroke-width='3.2'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="ordered-list"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 6h10M10 12h10M10 18h10M4 4.5l1.5-1v5M3.5 14.5a1.5 1.5 0 0 1 3 .3c0 .9-3 2.7-3 3.7h3'/%3E%3C/svg%3E"); }
.composer-tool[data-md-button="task-list"] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 4.5h6v6h-6zM5 7.5l1.3 1.3 2-2.3M13 7.5h8M3.5 13.5h6v6h-6zM13 16.5h8'/%3E%3C/svg%3E"); }
/* Hover/focus name tags for the icon buttons (pointer devices only). */
@media (hover: hover) {
  .composer-toolbar .composer-tool:is(:hover, :focus-visible)::after {
    position: absolute; left: 50%; top: calc(100% + 4px); transform: translateX(-50%); z-index: 6;
    padding: 4px 8px; border: 0; background: var(--ink); color: var(--sheet);
    font: 500 0.75rem/1.2 var(--sans); white-space: nowrap; pointer-events: none; bottom: auto;
  }
  .composer-tool[data-md-button="header-3"]:is(:hover, :focus-visible)::after { content: "Heading"; }
  .composer-tool[data-md-button="bold"]:is(:hover, :focus-visible)::after { content: "Bold  Ctrl+B"; white-space: pre; }
  .composer-tool[data-md-button="italic"]:is(:hover, :focus-visible)::after { content: "Italic  Ctrl+I"; white-space: pre; }
  .composer-tool[data-md-button="quote"]:is(:hover, :focus-visible)::after { content: "Quote"; }
  .composer-tool[data-md-button="code"]:is(:hover, :focus-visible)::after { content: "Code  Ctrl+E"; white-space: pre; }
  .composer-tool[data-md-button="link"]:is(:hover, :focus-visible)::after { content: "Link  Ctrl+K"; white-space: pre; }
  .composer-tool[data-md-button="unordered-list"]:is(:hover, :focus-visible)::after { content: "Bulleted list"; }
  .composer-tool[data-md-button="ordered-list"]:is(:hover, :focus-visible)::after { content: "Numbered list"; }
  .composer-tool[data-md-button="task-list"]:is(:hover, :focus-visible)::after { content: "Task list"; }
}
.composer-help-toggle { margin-left: 4px; border-left: 1px solid var(--rule); border-radius: 0; color: var(--muted); }
.composer-help-toggle[aria-expanded="true"] { color: var(--blue); background: var(--blue-wash); }
.composer-help {
  position: absolute; right: 0; top: 100%; z-index: 5;
  width: min(360px, 100%); padding: 10px 14px;
  background: var(--sheet); border: 1.5px solid var(--ink);
  box-shadow: 4px 4px 0 var(--grid); font-size: 0.9rem;
}
.composer-help-title { margin: 0 0 6px; font: 600 0.75rem/1.3 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.composer-help ul { list-style: none; margin: 0; padding: 0; }
.composer-help li + li { margin-top: 4px; }
.composer-help kbd, .composer kbd {
  font: 500 0.8rem/1 var(--mono); padding: 2px 5px; border: 1px solid var(--rule); border-bottom-width: 2px; border-radius: 2px; background: var(--paper);
}
.composer-body {
  display: block; width: 100%; min-height: calc(7 * 1.6em + 28px); max-height: 60vh;
  field-sizing: content; resize: vertical; padding: 14px 16px; line-height: 1.6;
  font-family: var(--sans); border-radius: 2px;
}
:is(.composer-reply, .composer-edit) .composer-body { min-height: calc(5 * 1.6em + 28px); }
.composer-tools:not([hidden]) + .composer-body { border-top: 0; border-radius: 0 0 2px 2px; }
.composer-body:focus-visible { outline: 0; border-color: var(--blue); box-shadow: inset 0 0 0 1px var(--blue); }
.composer-write:focus-within > .composer-tools:not([hidden]) { border-color: var(--blue); border-bottom-color: var(--grid); }
.composer-tabs:not([hidden]):has(+ .composer-write:focus-within) { border-color: var(--blue); border-bottom-color: var(--rule); }
.composer-body::placeholder { color: var(--muted); }
.composer-preview { min-height: calc(7 * 1.6em + 28px); border: 1.5px solid var(--field); border-top: 0; background: var(--sheet); }
.composer-preview.post-body { padding: 14px 16px 4px; }
.composer-preview:focus-visible { outline-offset: -3px; }
section.composer-preview { border: 0; padding: 0; min-height: 0; }
section.composer-preview > h2 { margin: 0 0 8px; font: 600 0.8rem/1.2 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
section.composer-preview > .post-body { border: 1.5px dashed var(--field); padding: 14px 16px 4px; }
/* Status lines reuse the contact form's .form-status; an empty one stays in
   the tree (it is a live region) but gives back its gap. */
.composer-status { margin: 0; font-size: 0.95rem; }
.composer-status:empty { padding: 0; border: 0; background: none; margin-top: calc(-1 * var(--gap)); }
.error-summary p { margin: 0; }
.field-error { margin: 0; color: #b3261e; font-weight: 600; font-size: 0.95rem; }
[data-theme="dark"] .field-error { color: #ff8a80; }
.composer [aria-invalid="true"] { border-color: #b3261e; }
[data-theme="dark"] .composer [aria-invalid="true"] { border-color: #ff8a80; }
.composer-turnstile:empty { display: none; }
.composer-form .cf-turnstile { min-height: 65px; }
.composer-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; justify-content: flex-end;
  padding-top: 16px; border-top: 1px solid var(--rule);
}
:is(.composer-reply, .composer-edit) .composer-actions { padding-top: 0; border-top: 0; }
.composer-actions .btn { align-self: auto; min-width: 112px; min-height: 44px; }
.composer-actions > a:not(.btn) { display: inline-flex; align-items: center; min-height: 44px; padding: 0 6px; font-weight: 600; }
/* button.btn is filled site-wide; the composer's Preview button is secondary. */
.composer button.btn-secondary { background: transparent; color: var(--blue); }
.composer button.btn-secondary:hover { background: var(--blue-wash); color: var(--blue-dk); border-color: var(--blue); }
.composer-saved { margin-right: auto; font: 400 0.82rem/1.4 var(--mono); color: var(--muted); }
.composer-saved:not(:empty)::before { content: "\2713\00a0"; color: var(--ok); }

/* Ask page: category cards and similar questions. */
.category-picker {
  border: 0; padding: 0; margin: 0; min-width: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); gap: 10px;
}
.category-picker legend { padding: 0; margin-bottom: 8px; }
.category-picker > .field-error { grid-column: 1 / -1; }
.category-option {
  position: relative;
  display: grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: 12px; row-gap: 2px; align-content: start;
  min-height: 44px; padding: 12px 14px; border: 1.5px solid var(--rule); border-radius: 2px;
  background: var(--sheet); cursor: pointer;
}
.composer .category-option { font-weight: 400; }
.category-option:hover { border-color: var(--field); background: color-mix(in srgb, var(--grid) 35%, var(--sheet)); }
.category-option:has(input:checked) { border-color: var(--blue); background: var(--blue-wash); box-shadow: inset 0 0 0 1px var(--blue); }
.category-option:has(input:focus-visible) { outline: 3px solid var(--blue); outline-offset: 2px; }
.category-option input[type="radio"] {
  appearance: none; -webkit-appearance: none; grid-row: 1 / span 3; align-self: start;
  width: 20px; height: 20px; margin: 2px 0 0; padding: 0;
  border: 1.5px solid var(--field); border-radius: 50%; background: var(--sheet); cursor: pointer;
}
.category-option input[type="radio"]:checked { border-color: var(--blue); background: var(--blue); box-shadow: inset 0 0 0 4px var(--sheet); }
.category-option input[type="radio"]:focus-visible { outline: 0; }
.category-option strong { grid-column: 2; font-weight: 600; line-height: 1.35; }
.category-description { grid-column: 2; display: block; color: var(--muted); font-size: 0.9rem; line-height: 1.4; }
.category-note {
  grid-column: 2; justify-self: start; margin-top: 6px;
  font: 600 0.72rem/1.6 var(--mono); text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ok); border: 1px solid currentColor; padding: 0 6px;
}
.category-note::before { content: "\2713\00a0"; }
.similar-list { margin-top: 6px; padding: 10px 14px; border-left: 3px solid var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--sheet)); }
.similar-title { margin: 0 0 4px; font-weight: 600; font-size: 0.95rem; }
.similar-list ul { margin: 0; padding-left: 1.2em; }
.similar-list li { margin: 2px 0; }
.similar-list .badge { margin-left: 4px; }
/* Account page (/forum/me/). */
.muted { color: var(--muted); }

@media (max-width: 760px) {
  .composer-reply, .composer-form { padding: 16px 14px; }
  .composer-reply { padding: 14px 12px 14px; }
  .composer-actions { justify-content: stretch; }
  .composer-actions .btn { flex: 1 1 100%; }
  .composer-saved { flex: 1 1 100%; margin: 0; }
  .composer-actions > a:not(.btn) { flex: 1 1 100%; justify-content: center; }
  section.composer:not(:has(form)) { padding: 20px 18px 6px; }
  section.composer:not(:has(form)) .btn { width: 100%; }
  .post-actions { padding: 4px 6px; }
  .post-action-status { margin: 0 14px 12px; }
  .composer-edit { padding: 12px 14px 14px; }
  .forum-search { max-width: none; margin-bottom: 24px; }
  main:has(> .forum-search) > .breadcrumbs ol { margin-bottom: 14px; }
  .post-replies, .post-thread > .composer, .posts > .post-reply { margin-left: 20px; }
  .post-replies > .post-reply::before { left: -14px; width: 9px; }
  .post-replies > .post-reply:not(:last-child)::after { left: -14px; }
  .post-context { padding-left: 14px; }
  .reply-area-foot .btn { flex: 1 1 100%; }
  .archive-banner { grid-template-columns: minmax(0, 1fr); }
  .archive-buy { border-left: 0; border-top: 1px solid var(--rule); flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
  .topic-table thead { display: none; }
  .topic-table, .topic-table tbody, .topic-table tr, .topic-table td { display: block; width: auto; }
  .topic-table tr { padding: 12px 14px; border-bottom: 1px solid var(--rule); }
  .topic-table td { padding: 0; border: 0; text-align: left; }
  .topic-table td.num, .topic-table td.nowrap { display: inline; font-size: 0.88rem; color: var(--muted); }
  .topic-table td.num + td { margin-left: 10px; }
  .topic-table .m-label { display: inline; font-family: var(--sans); }
  .post-head, .post-body { padding-left: 14px; padding-right: 14px; }
}
/* Touch screens: 44 px targets for the small links and chips. */
@media (pointer: coarse) {
  .board-chip, .post-reply-link, .post-edit, .post-delete, .post-link, .composer-cancel, .composer-discard, .site-account .forum-signin, .forum-account-toggle, .forum-account-links a, .forum-signout-button, .theme-toggle { min-height: 44px; }
  .forum-account-toggle { min-width: 44px; justify-content: center; }
  .post-link { min-width: 44px; margin-block: -10px; }
  .theme-toggle { width: 44px; }
}
@media (prefers-reduced-motion: reduce) {
  .composer *, .reply-area *, .fb-just-posted { transition: none !important; animation: none !important; }
  .post:target { animation: none; outline: 2px solid color-mix(in srgb, var(--blue) 40%, transparent); outline-offset: 3px; }
}

/* ---------------------------------------------------------------- Blog */
.post-list { list-style: none; margin: 0; padding: 0; }
.post-item { border-top: 1px solid var(--rule); padding: 22px 0; }
.post-item h2 { margin: 0 0 6px; font-size: 1.45rem; }
.post-item h2 a { text-decoration: none; }
.post-item p { margin: 6px 0 0; max-width: var(--prose); }
.post-draft {
  font: 600 0.75rem/1 var(--mono); text-transform: uppercase; letter-spacing: 0.06em;
  background: var(--todo); color: #5c4a00; padding: 4px 6px; margin-left: 8px; vertical-align: middle;
}

/* Comparison chart: one small panel per metric, each on its own scale. */
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 18px 28px; margin: 0; }
.metric h3 { font: 600 0.95rem/1.3 var(--sans); margin: 0 0 8px; }
.metric h3 small { color: var(--muted); font-weight: 400; }
.bar-row { display: grid; grid-template-columns: 5.5em minmax(0, 1fr); align-items: center; gap: 10px; margin: 4px 0; }
.bar-row > span:first-child { color: var(--muted); font: 400 0.85rem/1.2 var(--mono); }
.bar-track { display: flex; align-items: center; gap: 8px; }
.bar-fill { height: 18px; min-width: 4px; border-radius: 0 4px 4px 0; background: var(--blue); }
.bar-old .bar-fill { background: var(--muted); }
.bar-val { font: 600 0.9rem/1 var(--mono); color: var(--ink); white-space: nowrap; }

/* Before/after architecture diagram */
.arch { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 28px; margin: 0; }
.arch h3 { font: 600 0.8rem/1 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin: 0 0 12px; }
.arch ol { list-style: none; margin: 0; padding: 0; }
.arch li { border: 1px solid var(--rule); background: var(--sheet); padding: 10px 12px; position: relative; }
.arch li + li { margin-top: 26px; }
.arch li + li::before {
  content: ""; position: absolute; left: 50%; top: -22px; height: 18px;
  border-left: 2px solid var(--field);
}
.arch li + li::after {
  content: ""; position: absolute; left: calc(50% - 5px); top: -9px;
  border: 5px solid transparent; border-top: 6px solid var(--field); border-bottom: 0;
}
.arch li strong { display: block; font-family: var(--cond); font-size: 1.05rem; }
.arch li span { color: var(--muted); font-size: 0.9rem; }
.arch .is-new li { border-color: var(--blue); }
.arch .is-new li strong { color: var(--blue); }
.figure-panel { background: var(--sheet); border: 1px solid var(--rule); padding: 18px; margin: 0 0 28px; }
.figure-panel > figcaption { border-top: 1px solid var(--rule); margin-top: 14px; padding-top: 8px; }

/* Logic-analyzer plots (inline SVG, drawn from bench captures) */
.scope svg { width: 100%; max-width: 760px; height: auto; display: block; overflow: visible; }
.scope .g { stroke: var(--grid); stroke-width: 1; }
.scope .ax { stroke: var(--ink); stroke-width: 1.5; fill: none; }
.scope .tk { font: 400 13px var(--mono); fill: var(--muted); }
.scope .ln { fill: none; stroke-width: 2; stroke-linejoin: round; }
.scope .before { stroke: var(--muted); }
.scope .after { stroke: var(--blue); }
.scope .mk { stroke: var(--ink); stroke-width: 1.5; stroke-dasharray: 4 4; }
.scope .mk-t { fill: var(--ink); }
.legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0 0 10px; font: 400 0.85rem/1.3 var(--mono); color: var(--ink); }
.legend span::before {
  content: ""; display: inline-block; width: 16px; height: 3px; border-radius: 2px;
  background: var(--blue); vertical-align: middle; margin-right: 6px;
}
.legend .is-before::before { background: var(--muted); }

/* Headline numbers */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); gap: 12px; margin: 0 0 28px; padding: 0; list-style: none; }
.stats li { background: var(--sheet); border: 1px solid var(--rule); padding: 14px; }
.stats strong { display: block; font: 600 2rem/1.1 var(--cond); color: var(--ink); }
.stats span { color: var(--muted); font-size: 0.88rem; }
.bars-1 .bar-row { grid-template-columns: minmax(8em, 13em) minmax(0, 1fr); }
article p.note { border-left: 3px solid var(--blue); background: var(--blue-wash); padding: 10px 14px; max-width: var(--prose); }

/* Homepage: latest blog posts */
.post-cards { list-style: none; margin: 0 0 12px; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 20px; }
.post-card { background: var(--sheet); border: 1px solid var(--rule); padding: 18px 20px; }
.post-card h3 { margin: 4px 0 8px; font-size: 1.25rem; }
.post-card h3 a { text-decoration: none; }
.post-card p { margin: 0; }
.post-card .byline { margin: 0; }

/* The forum's 503 page (src/archive-forum.mjs unavailableResponse): shown when
   forumbot cannot serve an old forum page after the cutover. */
.forum-unavailable { max-width: 40rem; margin: 4rem auto; padding: 0 16px; line-height: 1.5; }
.forum-unavailable h1 { margin-bottom: 0.5rem; }

/* Dark theme: the same data sheet, drawn on a night-blue sheet.
   Scoped to [data-theme="dark"]; build.js concatenates it into styles.css. */
[data-theme="dark"] {
  --paper: #0d161d;
  --sheet: #131f28;
  --ink: #e4ebf0;
  --muted: #a1b0bb;
  --rule: #2c3d4a;
  --grid: #1b2a35;
  --field: #4f6474;
  --blue: #7db0f5;
  --blue-dk: #a6c9f8;
  --blue-wash: #1a2d42;
  --on-blue: #0d161d;
  --ok: #5fcf8e;
  --foot-bg: #080e13;
  --foot-fg: #a1b0bb;
  --foot-rule: #22313c;
  color-scheme: dark;
}
/* Product photos have white backgrounds; keep their frames light-edged. */
[data-theme="dark"] .card > img,
[data-theme="dark"] .project-hero img { border-color: var(--rule); }

/* Light theme: the default "Datasheet" palette lives in :root in styles.css.
   build.js concatenates this file into styles.css. */
[data-theme="light"] { color-scheme: light; }
