/* ============================================================================
   pages.css — the document pages (everything except the immersive home).

   One stylesheet for nine generated pages, so a spacing decision cannot be
   right on one page and wrong on the next. It shares tokens.css with the home
   page, which is why the two read as one site.

   The rules that keep it honest:
     • one type scale, declared once, used everywhere;
     • one horizontal rhythm — .wrap sets the measure, nothing else sets margins;
     • every interactive target is at least 44px tall;
     • nothing positions absolutely except the skip link and the nav panel, so
       no element can ever land on top of another at a width nobody tested.
   ========================================================================= */

/* ------------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; }

body.page {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3 { font-weight: 500; letter-spacing: -.018em; line-height: 1.1; margin: 0; }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

a { color: inherit; }
/* The keyboard ring. This read var(--focus), which was never defined in any
   stylesheet, so the declaration was invalid and `outline` fell back to none:
   no focus indicator anywhere on the document or service pages. --accent is the
   token site.css already uses, and unlike a root-resolved --focus it follows the
   override on the dark card blocks, so the ring stays visible on them too.
   :focus-visible rather than a list of three elements, because select, textarea,
   summary and [tabindex] are focusable as well. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
:focus:not(:focus-visible) { outline: 0; }

/* Anchors. The header is sticky at top:0 and the filter bar sticks below it, so
   every in-page jump used to leave its heading behind the header. --sticky-h is
   measured by the page script; 88px is the pre-script fallback. */
html { scroll-padding-top: calc(var(--sticky-h, var(--nav-h, 88px)) + 20px); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--off-white);
  padding: 12px 18px; border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; }

.wrap {
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

/* ---------------------------------------------------------------- the nav */

.pnav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.pnav-inner {
  max-width: 1180px; margin-inline: auto;
  padding: 14px var(--pad-x);
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
}
.pnav-brand {
  text-decoration: none; display: grid; align-content: center;
  line-height: 1.15; margin-right: auto; min-height: 44px;
}
.pnav-word { font-size: 17px; font-weight: 500; }
.pnav-sub { font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--fg-muted); }

.pnav-toggle {
  display: none;
  min-height: 44px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--fg); cursor: pointer;
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
}

.pnav-list { display: flex; flex-wrap: wrap; gap: 2px; }
.pnav-link {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 12px;
  font-size: 14px; text-decoration: none; color: var(--body);
  border-radius: 8px;
  transition: color var(--d-1) var(--e-std), background var(--d-1) var(--e-std);
}
.pnav-link:hover { color: var(--fg); background: var(--bg-sunk); }
.pnav-link.is-here { color: var(--fg); font-weight: 500; box-shadow: inset 0 -2px 0 var(--accent); }

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

.phero { padding-block: clamp(48px, 8vw, 104px) clamp(28px, 4vw, 48px); }

.eyebrow {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 20px;
}

.display {
  font-size: clamp(34px, 5.6vw, 68px);
  letter-spacing: -.028em; line-height: 1.02;
  max-width: 19ch;
}

.lede {
  font-size: clamp(16.5px, 1.35vw, 20px);
  color: var(--body); max-width: 62ch; margin-top: 22px;
}
.argument {
  font-size: 15.5px; color: var(--fg-muted); max-width: 62ch; margin-top: 14px;
  padding-left: 16px; border-left: 2px solid var(--accent-soft);
}

/* ------------------------------------------------------------------ stats */

.stats {
  /* min(100%, 190px), not 128px. At 600px a 128px minimum gave three columns of
     136px and "Manufacturing, retail" is one 198px token that cannot break, so
     the strip's overflow: hidden cut it mid-word on nine service pages. Fewer,
     wider columns when there is less room; break-word below as a backstop. */
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 1px; margin-top: 36px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.stat { background: var(--surface); padding: 16px 18px; }
.stat dt { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-muted); }
.stat dd {
  overflow-wrap: break-word;
  font-size: 30px; line-height: 1.05; margin-top: 8px;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}

/* ------------------------------------------------------------- jump links */

.jump { margin-top: 34px; }
.jump-label { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-muted); }
.jump ul { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.jump a {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 15px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); text-decoration: none; font-size: 14px;
  transition: border-color var(--d-1) var(--e-std);
}
.jump a:hover { border-color: var(--accent); }
.jump a span { color: var(--fg-muted); font-size: 12px; }

/* ------------------------------------------------------------- team line */

/* This replaced the per-service delivery legend on 2026-09-06. The studio does
   not grade itself line by line any more; it makes one statement about who
   builds the work, and it is the owner's own. */
.teamline {
  margin-top: 8px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-sunk);
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.55;
  color: var(--body);
  max-width: 72ch;
}

/* -------------------------------------------------------------- filterbar */

/* The header wraps to two rows once the nav no longer fits, so a hard-coded
   offset here hid the search field behind it. --nav-h is measured by the page
   script and updated on resize; 88px is only the pre-script fallback. */
.filterbar {
  position: sticky; top: var(--nav-h, 88px); z-index: 40;
  margin-top: 36px; padding-block: 14px;
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-block: 1px solid var(--line);
}
.filterrow { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.search { flex: 1 1 260px; display: block; }
.search input {
  width: 100%; min-height: 46px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--fg);
  font: inherit; font-size: 15px;
}
.search input::placeholder { color: var(--fg-muted); }

.chips { display: flex; gap: 6px; overflow-x: auto; padding: 12px 0 4px; }
.chip {
  white-space: nowrap; cursor: pointer;
  min-height: 44px; padding: 0 14px;
  border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--body); font: inherit; font-size: 13.5px;
  transition: border-color var(--d-1) var(--e-std), background var(--d-1) var(--e-std);
}
.chip span { color: var(--fg-muted); font-size: 11.5px; margin-left: 6px; }
.chip:hover { border-color: var(--fg-muted); }
.chip.is-on { background: var(--ink); border-color: var(--fg); color: var(--off-white); }
.chip.is-on span { color: color-mix(in srgb, var(--off-white) 65%, transparent); }

.count { font-size: 12px; color: var(--fg-muted); letter-spacing: .05em; padding-top: 8px; }

/* --------------------------------------------------------- the categories */

.catblocks { padding-block: clamp(32px, 5vw, 64px) 0; }

.catblock + .catblock { margin-top: clamp(44px, 6vw, 84px); }
.catblock[hidden] { display: none; }

.cathead {
  display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
  padding-bottom: 14px; border-bottom: 1px solid var(--line);
}
.catnum { font-size: 12px; color: var(--accent); letter-spacing: .1em; }
.catname { font-size: clamp(22px, 3vw, 34px); margin-right: auto; }
.catlink a { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.catcount { font-size: 11.5px; color: var(--fg-muted); letter-spacing: .06em; }

.srvlist { margin-top: 4px; }

.srv {
  display: grid;
  grid-template-columns: 44px minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 0 24px;
  padding: 20px 0;
  border-bottom: 1px solid var(--line);
}
.srv[hidden] { display: none; }
.srv-n { font-size: 12px; color: var(--fg-muted); padding-top: 4px; font-variant-numeric: tabular-nums; }
.srv-name { font-size: 19px; letter-spacing: -.012em; }
.srv-desc { font-size: 15px; color: var(--body); margin-top: 6px; max-width: 54ch; }

.srv-meta {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 20px; align-content: start; padding-top: 3px;
}
.srv-meta dt { font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-muted); }
.srv-meta dd { font-size: 14px; margin-top: 3px; }
.srv-price { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.empty {
  padding: 64px 0; text-align: center; color: var(--fg-muted);
  font-family: var(--font-mono); font-size: 14px;
}

/* --------------------------------------------------------- generic blocks */

.band {
  margin-top: clamp(48px, 7vw, 96px);
  padding: clamp(32px, 4.5vw, 56px) clamp(24px, 3.5vw, 44px);
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.wrap.band { max-width: 1180px; }

.section-title { font-size: clamp(24px, 3.4vw, 40px); max-width: 22ch; }
.section-title + .lede { margin-top: 16px; }

.hint { font-size: 12px; color: var(--fg-muted); margin-top: 20px; letter-spacing: .04em; }

/* the audit page */

.refusals {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px; margin-top: 28px;
}
.refusal {
  background: var(--surface); border: 1px solid var(--line);
  border-top: 2px solid var(--accent); border-radius: var(--radius);
  padding: 22px;
}
.refusal-n { font-size: 11px; color: var(--accent); letter-spacing: .14em; }
.refusal h3 { font-size: 18px; margin-top: 10px; }
.refusal p { font-size: 14.5px; color: var(--body); margin-top: 10px; }

.auditcats {
  margin-top: 28px;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.auditcats li {
  background: var(--surface); padding: 14px 18px;
  display: grid; grid-template-columns: 32px 1fr; gap: 2px 12px; align-items: baseline;
}
.auditcats li span:first-child { font-size: 11.5px; color: var(--accent); grid-row: span 2; }
.auditcats b { font-size: 15.5px; font-weight: 500; }
/* nth-of-type, not last-child: the audit loop appends a "Fix this" link to each
   item, so the description stopped being the last child and silently lost its
   styling the moment that link was added. */
.auditcats li span:nth-of-type(2) { font-size: 13px; color: var(--fg-muted); grid-column: 2; }

/* The audit loop's exit: a weak category leads to the page that fixes it.
   Rendered only when that page exists — build_pages.mjs checks. */
.catfix {
  grid-column: 2;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-block: -11px -8px;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
}
.catfix:hover { text-decoration: underline; text-underline-offset: 3px; }

.tiers {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px; margin-top: 28px;
}
.tier {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 24px 22px;
}
.tier--lead { border-color: var(--accent); box-shadow: var(--shadow); }
.tier > .mono { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-muted); }
.tier-price {
  font-size: 40px; line-height: 1; margin: 12px 0 10px;
  font-variant-numeric: tabular-nums; letter-spacing: -.03em;
}
.tier-sub { font-size: 14px; color: var(--body); }

/* Four cards at minmax(268px) fitted three across and orphaned the fourth on
   its own row. 246px lets all four sit on one line inside .wrap, and still
   drops to two and then one as the viewport narrows. */
.frees {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(246px, 1fr));
  gap: 18px; margin-top: 28px;
}
.free { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; }
.free h3 { font-size: 16.5px; }
.free h3 a { text-decoration-color: var(--accent-soft); text-underline-offset: 3px; }
.free p { font-size: 14px; color: var(--body); margin-top: 10px; }

/* the contact page */

.checklist { margin-top: 24px; display: grid; gap: 14px; counter-reset: c; }
/* The number hangs in the left margin rather than taking a grid column.
   As a two-column grid, each <li> put its ::before in column one and the <b>
   label in column two -- and the sentence after the </b>, being a bare text
   node, became a THIRD grid item that wrapped back into the 30px column and
   printed one word per line. Every width, both themes. */
.checklist li {
  position: relative;
  padding-left: 42px;
  font-size: 15.5px; color: var(--body);
}
.checklist li::before {
  position: absolute; left: 0; top: 3px;
  counter-increment: c; content: counter(c, decimal-leading-zero);
  font-family: var(--font-mono); font-size: 12px; color: var(--accent);
}
.checklist b { color: var(--fg); font-weight: 500; }

.howgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  gap: 20px; margin-top: 28px;
}
.how { border-top: 2px solid var(--accent); padding-top: 16px; }
.how > .mono { font-size: 11px; color: var(--accent); letter-spacing: .14em; }
.how h3 { font-size: 17px; margin-top: 10px; }
.how p { font-size: 14.5px; color: var(--body); margin-top: 10px; }

/* ------------------------------------------------------------------- CTAs */

.cta {
  margin-block: clamp(56px, 8vw, 104px);
  padding-top: clamp(32px, 4vw, 48px);
  border-top: 1px solid var(--line);
}
.cta-title { font-size: clamp(24px, 3.6vw, 42px); max-width: 20ch; }
.cta-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 22px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--fg);
  font-size: 15px; text-decoration: none;
  transition: border-color var(--d-1) var(--e-std), background var(--d-1) var(--e-std), color var(--d-1) var(--e-std);
}
.btn:hover { border-color: var(--fg-muted); }
.btn-primary { background: var(--ink); border-color: var(--fg); color: var(--off-white); }
.btn-primary:hover { background: var(--accent); border-color: var(--accent); color: var(--off-white); }

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

.pfoot {
  border-top: 1px solid var(--line);
  background: var(--bg-sunk);
  padding-block: clamp(40px, 5vw, 68px) 28px;
}
.pfoot-statement { font-size: clamp(20px, 2.6vw, 30px); max-width: 26ch; letter-spacing: -.018em; line-height: 1.2; }
.pfoot-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
  gap: 28px; margin-top: 40px;
}
.pfoot-label { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-muted); font-weight: 400; }
.pfoot-block p { font-size: 14.5px; color: var(--body); margin-top: 10px; }
.pfoot-block a { text-decoration-color: var(--line); text-underline-offset: 3px; }
.pfoot-block a:hover { text-decoration-color: var(--accent); }
.pfoot-links { margin-top: 10px; display: grid; gap: 2px; }
.pfoot-links a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 14px; color: var(--body); text-decoration: none;
}
.pfoot-links a:hover { color: var(--fg); text-decoration: underline; }
.pfoot-note { font-size: 12.5px; color: var(--fg-muted); margin-top: 36px; max-width: 82ch; line-height: 1.65; }
.pfoot-bottom { font-size: 11.5px; color: var(--fg-muted); margin-top: 20px; letter-spacing: .05em; }

/* ------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .srv { grid-template-columns: 34px minmax(0, 1fr); }
  .srv-meta { grid-column: 2; margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
}

@media (max-width: 760px) {
  .pnav-toggle { display: inline-flex; align-items: center; }
  .pnav-list {
    display: none; width: 100%; flex-direction: column; gap: 0;
    padding-top: 8px; margin-top: 8px; border-top: 1px solid var(--line);
  }
  .pnav-list.is-open { display: flex; }
  .pnav-link { width: 100%; }
  .filterbar { top: var(--nav-h, 0px); }
  .srv-meta { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 480px) {
  .stat dd { font-size: 26px; }
  .display { max-width: none; }
  .cta-actions .btn { width: 100%; }
}

/* --------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* ============================================================================
   THE SERVICES TREE
   Added with /services/, the 18 category hubs and the service pages. Six
   components, not twenty-seven: the board and the hubs reuse .filterbar,
   .search, .count, .chips, .catblocks, .srvlist and .srv, which already
   existed and already worked. Inventing a parallel set beside them would have
   been two stylesheets describing one idea.

   Every measure below is capped in ch rather than px. A service page is the
   only place on this site with long-form prose, and a 100-character line is
   the difference between a page that gets read and one that gets skimmed.
   ========================================================================= */

/* ---------------------------------------------------------- breadcrumbs --- */
/* Four levels deep, the visitor needs to know where they are and how to get
   back up. It sits above the hero rather than inside it, so the h1 keeps its
   own space and nothing lands on top of it. */
.crumb-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-size: 11.5px;
  letter-spacing: .06em;
  color: var(--fg-muted);
}
.crumb-list li { display: flex; align-items: center; gap: 10px; }
.crumb-list li + li::before {
  content: "/";
  color: var(--line);
}
/* A breadcrumb link is 18px of text. That is navigation chrome, not inline body
   text, so WCAG 2.5.8's inline exception does not cover it and a thumb has to
   be able to hit it. The padding buys the target; the equal negative margin
   means the trail looks exactly as it did. Measured at 390px: 18px -> 44px. */
.crumb-list a {
  color: var(--fg-muted);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;      /* stated, not derived: padding + line-height landed on 43.99 */
  margin-block: -13px;
}
.crumb-list a:hover { color: var(--fg); text-decoration: underline; text-underline-offset: 3px; }
.crumb-list [aria-current="page"] { color: var(--fg); }

/* ------------------------------------------------------ section rhythm --- */
/* One rule for the vertical rhythm of every new block, so a page cannot end up
   with a 90px gap above one section and 30px above the next. */
.sbody, .ssteps, .sbox, .sfaq, .srel { padding-block: clamp(36px, 5.5vw, 76px) 0; }
.sbody:last-of-type, .srel:last-of-type { padding-bottom: clamp(8px, 2vw, 24px); }

/* ------------------------------------------------------------- prose ----- */
/* The only long-form text on the site. Measure is capped, headings get real
   space above them and less below, and lists keep their own indent so a
   wrapped line never sits under its own bullet. */
.prose { max-width: 68ch; color: var(--body); font-size: clamp(15px, 1.1vw, 17px); line-height: 1.65; }
.prose > * + * { margin-top: 1.1em; }
.prose h2 {
  font-size: clamp(20px, 2.4vw, 28px);
  line-height: 1.2;
  color: var(--fg);
  margin-top: 2em;
  max-width: 24ch;
}
.prose h3 {
  font-size: clamp(16px, 1.6vw, 20px);
  line-height: 1.3;
  color: var(--fg);
  margin-top: 1.8em;
  max-width: 30ch;
}
.prose h2 + *, .prose h3 + * { margin-top: .6em; }
.prose strong { color: var(--fg); font-weight: 500; }
.prose code {
  font-family: var(--font-mono);
  font-size: .92em;
  background: var(--bg-sunk);
  padding: .12em .38em;
  border-radius: 4px;
}
.prose ul, .prose ol { padding-left: 1.35em; }
.prose ul > li { list-style: disc; }
.prose ol > li { list-style: decimal; }
.prose li { margin-top: .5em; padding-left: .2em; }
.prose li::marker { color: var(--fg-muted); }

/* --------------------------------------------------------------- steps --- */
/* A numbered process. The number is a fixed column so the text edges line up
   however long the numbers get; below 560px it moves above the text instead of
   squeezing it into a strip. */
.steps { margin-top: clamp(20px, 3vw, 34px); }
.step {
  display: grid;
  grid-template-columns: 3.2em 1fr;
  gap: 4px 18px;
  padding: clamp(16px, 2vw, 22px) 0;
  border-top: 1px solid var(--line);
}
.step:last-child { border-bottom: 1px solid var(--line); }
.step-n {
  font-size: 12px;
  color: var(--accent);
  letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  padding-top: .35em;
}
.step-t { font-size: clamp(16px, 1.7vw, 20px); letter-spacing: -.01em; }
.step-body p { font-size: 15px; color: var(--body); margin-top: 6px; max-width: 58ch; }
.step-time {
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-top: 10px;
}

/* ----------------------------------------------------------- audit box --- */
.sbox > * { max-width: 62ch; }
.sbox .lede { margin-top: 14px; }
.sbox .cta-actions { margin-top: 22px; }

/* ----------------------------------------------------------------- faq --- */
/* A definition list, not an accordion: every answer is on the page for search
   engines and for anyone using find-in-page, and nothing can be hidden behind
   a control that fails to open. */
.faq { margin-top: clamp(18px, 2.5vw, 30px); }
.faq-item {
  padding: clamp(16px, 2vw, 22px) 0;
  border-top: 1px solid var(--line);
}
.faq-item:last-child { border-bottom: 1px solid var(--line); }
.faq-q {
  font-size: clamp(16px, 1.6vw, 19px);
  color: var(--fg);
  letter-spacing: -.01em;
  max-width: 46ch;
}
.faq-a {
  font-size: 15px;
  color: var(--body);
  line-height: 1.6;
  margin-top: 8px;
  max-width: 64ch;
}

/* ------------------------------------------------------- related links --- */
/* Cards, because these are the page's exit routes and a row of underlined text
   reads as a footnote. Auto-fill rather than a fixed column count: three items
   and two items both have to look deliberate. */
.rel-list {
  display: grid;
  /* auto-fit, not auto-fill, and a smaller floor: with five related services
     and a 1,030px column, auto-fill at 230px made four tracks and left the
     fifth card alone on a row of its own. auto-fit collapses the tracks it
     does not need, so four cards still fill the row. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: 12px;
  margin-top: clamp(18px, 2.5vw, 28px);
}
.rel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 92px;
  height: 100%;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  text-decoration: none;
  color: var(--fg);
  transition: border-color .2s, background-color .2s;
}
.rel:hover { border-color: var(--accent); background: var(--bg-sunk); }
.rel-name { font-size: 16px; letter-spacing: -.01em; line-height: 1.3; }
.rel-cat {
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.rel-meta { font-size: 12px; color: var(--fg-muted); margin-top: auto; padding-top: 8px; }

/* ---------------------------------------------------------- narrow ------- */
@media (max-width: 560px) {
  .step { grid-template-columns: 1fr; gap: 2px; }
  .step-n { padding-top: 0; }
  .rel-list { grid-template-columns: 1fr; }
  .crumb-list { font-size: 11px; }
}

/* Where an enquiry came from — set by the contact page's script when a service
   page sent the visitor here. Hidden until there is something to say. */
.ref {
  margin-top: 18px;
  font-size: 12px;
  letter-spacing: .08em;
  color: var(--accent);
}

/* --------------------------------------------------------------- guides --- */
/* The guides index carries <ul class="cards"> from the pages that predate this
   stylesheet: each item is a category label, a title in <b> and a description,
   all inside one <a>. Unstyled they ran together into a single underlined
   sentence. This is the same card the rest of the site uses -- surface on
   ground, a hairline rule, a gold edge on top. */
.cards {
  display: grid;
  /* 230, not 300: .prose holds a reading measure of about 525px, and at 300 the
     grid collapsed to a single column on a 1250px screen. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  gap: 18px;
  margin: 2em 0 0;
  padding: 0;
  list-style: none;
}
.cards > li { display: flex; }
.cards a {
  display: flex;
  flex-direction: column;
  gap: .5em;
  width: 100%;
  padding: clamp(18px, 1.8vw, 26px);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--accent);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--d-2, .25s) var(--e-std, ease),
              box-shadow var(--d-2, .25s) var(--e-std, ease);
}
.cards a:hover, .cards a:focus-visible {
  border-color: var(--accent);
  box-shadow: var(--shadow);
}
.cards .cat {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}
.cards b {
  font-size: clamp(17px, 1.4vw, 20px);
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -.012em;
}
.cards .cat + b { margin-top: .1em; }
.cards b + span {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--fg-muted);
}

/* --------------------------------------------------- dark mode, flat pages ---
   Same palette, same button. These pages do not load site.css, so the rules are
   repeated rather than shared -- two stylesheets, one for the WebGL home page
   and one for the 227 generated pages, is the shape this site already has. */
html[data-theme="dark"] .pnav { background: color-mix(in srgb, var(--black) 88%, transparent); }
html[data-theme="dark"] .srv,
html[data-theme="dark"] .catblocks .srv,
html[data-theme="dark"] .cards a,
html[data-theme="dark"] .stat,
html[data-theme="dark"] .auditbox { background: #16150F; }

#theme-btn {
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--rule);
  display: inline-grid;
  place-items: center;
  flex: none;
  position: relative;
}
/* The drawn circle is 35.2px and a touch target is 44. Rather than grow the
   button and push the header around, the hit area is extended past the border
   -- a pseudo-element is hit-tested as part of its own element, so a thumb
   landing anywhere in the 44px box presses the button. Found by the site
   checker, on 30 pages, and introduced with the toggle itself. */
#theme-btn::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}
#theme-btn .theme-icon {
  width: .95rem;
  height: .95rem;
  border-radius: 50%;
  background: currentColor;
  position: relative;
  overflow: hidden;
}
#theme-btn .theme-icon::after {
  content: '';
  position: absolute;
  inset: -35% -35% -35% 15%;
  border-radius: 50%;
  background: var(--bg);
  transition: transform .4s cubic-bezier(.35, 0, 0, 1);
}
html[data-theme="dark"] #theme-btn .theme-icon::after { transform: translateX(115%); }

/* --------------------------------------------- retired decoration, hidden ---
   The per-page bundles from the old design append three decorative layers to
   <body> at runtime: canvas.starfield, canvas.meteors and div.ambient-glow.
   They belonged to a dark starfield page that no longer exists.

   They are not merely invisible now, they are IN THE WAY. Both canvases are
   inserted as static-flow elements at 1280x900, so on /sample-report they
   pushed <main> to 1952px and the first two screens of that page were an empty
   field. Kumail found it by scrolling. Measured: page 6943px tall, main
   starting at 1952.

   Hidden rather than unhooked from the JS, because that JS is minified,
   per-page, and also carries each tool's working code. */
.starfield,
.meteors,
.ambient-glow { display: none !important; }

/* ---------------------------------------------------------- sample report ---
   The engine writes this markup at runtime; these are its real class names,
   read off the live DOM rather than guessed. Before this the page rendered as
   "100Security0 findings" and "infoInfrastructure" -- adjacent inline elements
   with nothing separating them. */

/* .prose caps itself at a 676px reading measure, which is right for an essay
   and wrong for a report: the score grid and the finding cards were squeezed
   into half the page while the other half sat empty. The prose that INTRODUCES
   the report keeps the measure; the data does not. */
.sreport .prose { max-width: none; }
.sreport .prose > p,
.sreport .prose > h2 + p,
.sreport .caveat { max-width: 74ch; }

.sreport .caveat {
  margin: 1.6em 0 0;
  padding: clamp(16px, 1.6vw, 24px);
  background: var(--surface);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.sreport .caveat p { margin: 0; }
.sreport .caveat p + p { margin-top: .7em; }

/* --- the headline score --- */
.sreport .overall {
  display: flex;
  align-items: baseline;
  gap: clamp(14px, 1.6vw, 26px);
  margin: clamp(28px, 3vw, 48px) 0 0;
  padding-top: clamp(18px, 2vw, 30px);
  border-top: 2px solid var(--accent);
}
/* Read off the DOM, not assumed: the score is a plain <b> and .rv is the
   tablist's container, not the score. My first pass targeted .rv here and the
   headline number stayed at body size. */
.sreport .overall > b {
  font-size: clamp(46px, 6vw, 88px);
  line-height: .9;
  font-weight: 500;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.sreport .overall > div { max-width: 52ch; }
.sreport .overall strong {
  display: block;
  font-size: clamp(15px, 1.2vw, 18px);
  font-weight: 500;
  margin-bottom: .25em;
}
.sreport .overall span { color: var(--fg-muted); }

/* --- the filter chips --- */
.sreport [role="tablist"], .sreport .rv { display: flex; flex-wrap: wrap; gap: 8px; margin: 1.6em 0 0; }
.sreport [role="tab"] {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .04em;
  padding: .62em 1.1em;
  border: 1px solid var(--rule);
  border-radius: 6.25em;
  color: var(--fg-muted);
  background: transparent;
  cursor: pointer;
  transition: color .2s, border-color .2s, background-color .2s;
}
.sreport [role="tab"]:hover { border-color: var(--accent); color: var(--fg); }
.sreport [role="tab"][aria-selected="true"] {
  background: var(--pill-bg);
  color: var(--pill-fg);
  border-color: var(--pill-bg);
}

/* --- one card per category --- */
.sreport .grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr));
  gap: 12px;
  margin: 1.5em 0 0;
  padding: 0;
  list-style: none;
}
.sreport .sc {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: 12px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--rule);
  border-radius: 12px;
}
/* The number is the first text node; the engine wraps it in a <b> or a <span>
   depending on the category, so both are targeted. */
.sreport .sc > b,
.sreport .sc > span:first-child,
.sreport .sc > strong {
  grid-row: span 2;
  font-size: clamp(21px, 1.9vw, 27px);
  font-weight: 500;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.sreport .sc > *:not(:first-child) { grid-column: 2; }
.sreport .sc em,
.sreport .sc i { display: block; font-style: normal; font-size: 12.5px; color: var(--fg-muted); }
.sreport .sc-good { border-top-color: var(--good); }
.sreport .sc-mid  { border-top-color: var(--warn); }
.sreport .sc-low  { border-top-color: var(--bad); }
.sreport .sc-na   { border-top-color: var(--rule); opacity: .8; }

/* --- findings --- */
.sreport .fl,
.sreport .dal { margin: 1.4em 0 0; padding: 0; list-style: none; display: grid; gap: 12px; }
.sreport .fl > li,
.sreport .dal > li {
  list-style: none;
  padding: clamp(14px, 1.4vw, 22px);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--rule);
  border-radius: 0 12px 12px 0;
}
.sreport .f-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: .6em; }
.sreport .sev {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: .3em .7em;
  border-radius: 4px;
  border: 1px solid currentColor;
}
.sreport .sec {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.sreport .msg { margin: 0; font-size: clamp(15px, 1.2vw, 18px); font-weight: 500; line-height: 1.3; }
.sreport .rec,
.sreport .do  { margin: .55em 0 0; color: var(--fg-muted); line-height: 1.55; }
.sreport .f-info     { border-left-color: var(--info); }
.sreport .f-info .sev { color: var(--info); }
.sreport .f-warning  { border-left-color: var(--warn); }
.sreport .f-warning .sev { color: var(--warn); }
.sreport .f-critical { border-left-color: var(--bad); }
.sreport .f-critical .sev { color: var(--bad); }
.sreport .dal .sev { color: var(--fg-muted); border-color: var(--rule); margin-right: 8px; }
.sreport .dal b { font-weight: 500; }

/* .prose spaces its own children; paragraphs nested one level deeper -- inside
   the aside, the caveat, a finding -- were left touching each other. */
.sreport .onpurpose p + p,
.sreport .note p + p,
.sreport .foot p + p { margin-top: .8em; }

.sreport .onpurpose,
.sreport .note,
.sreport .foot { color: var(--fg-muted); }
.sreport .onpurpose {
  margin: clamp(28px, 3vw, 44px) 0 0;
  padding: clamp(18px, 1.8vw, 26px) clamp(18px, 1.8vw, 26px) clamp(18px, 1.8vw, 26px)
           clamp(20px, 2vw, 28px);
  max-width: 76ch;
  border-left: 2px solid var(--warn);
  background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.sreport .onpurpose h3 { color: var(--fg); font-size: 17px; margin-bottom: .7em; }
.sreport .onpurpose b { color: var(--fg); }


/* The reason a legal page was last touched, beside its date. Quieter than
   the date itself: it explains, it does not announce. */
.meta-note { color: var(--fg-muted); }

/* ------------------------------------------------------- what gets checked ---
   The fifteen categories, what is in each, and what a scanner cannot do. None
   of these class names had a single rule before: the page rendered as sixty-
   three 525px tick marks stacked down forty-five screens. */

/* The grid is a page-width component that happens to sit inside .prose, which
   caps itself at a reading measure. Leave the measure, and do not take the
   gutter twice from the .wrap outside it. */
.wcc-wide { max-width: none; padding-inline: 0; }
/* A child cannot be wider than its parent, and the parent here is .prose, which
   holds a 68-character reading measure. Lifting it only for the page that puts
   a full-width component inside it: the reading widths that should survive --
   the lede, the note, the closing paragraph -- carry their own. */
/* A .wrap inside .prose is always this mistake: .prose holds a 68-character
   reading measure and .wrap is a page-width container, so the page-width thing
   comes out at reading width -- and then takes the gutter a second time on top.
   /what-we-check put a 15-card grid in it, /guides a 22-card one. The reading
   widths that should survive carry their own max-width. */
.prose:has(> .wrap) { max-width: none; }
.prose > .wrap { max-width: none; padding-inline: 0; }
.wcc-wide > h1 { max-width: 20ch; }
.wcc-wide > h2 { max-width: 26ch; }

.wcc-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* Same hairline-separated block as .stats, over a different markup shape. */
.wcc-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 1px; margin-top: 38px;
  background: var(--line); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
}
.wcc-stats > div { background: var(--surface); padding: 16px 18px; }
.wcc-stats b {
  display: block; font-size: 30px; font-weight: 500; line-height: 1;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.wcc-stats span {
  display: block; margin-top: 8px;
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--fg-muted);
}

.wcc-note {
  margin-top: 14px; max-width: 62ch;
  font-size: 14.5px; color: var(--fg-muted);
}

.wcc-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr));
  gap: 16px; margin-top: 30px;
}

.wcc-card {
  padding: clamp(20px, 2vw, 28px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.wcc-card h3 {
  display: flex; align-items: baseline; gap: 12px;
  font-size: 18px; letter-spacing: -.012em;
}
.wcc-n {
  font-family: var(--font-mono); font-size: 12px;
  font-variant-numeric: tabular-nums; color: var(--fg-muted);
}
.wcc-line { margin-top: 8px; font-size: 14.5px; color: var(--fg-muted); }
/* .prose indents lists by 1.35em for a disc that is not drawn here -- the
   items are their own grid, so the marker box is never generated. */
.wcc-card ul { margin-top: 16px; display: grid; gap: 10px; padding-left: 0; }
.wcc-card li { padding-left: 0; margin-top: 0; }
.wcc-card li {
  display: grid; grid-template-columns: 15px minmax(0, 1fr);
  gap: 10px; font-size: 14.5px; line-height: 1.5; color: var(--body);
}

/* The tick. It carries no width, no height, no fill and no stroke of its own,
   so all four come from here -- without the fill:none a browser paints the
   path solid and the tick reads as a black wedge. */
.wcc-card li svg {
  width: 15px; height: 15px; margin-top: 4px;
  fill: none; stroke: var(--accent);
  stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round;
}

/* "with permission or a key" -- the items that need something from the client. */
.cond {
  display: inline-block; margin-left: 8px;
  padding: .18em .6em;
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent-soft, var(--line));
  border-radius: 999px;
  white-space: nowrap;
}

/* Separate cards, not one slab divided by hairlines. These groups hold four
   and three items against a three-column grid, so a slab leaves a lit, empty
   cell beside the last one -- it reads as a block that failed to load. Cards
   leave page background there instead, and match the category grid above. */
.wcc-hands {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 16px; margin-top: 30px;
}
.wcc-hand, .wcc-limit {
  background: var(--surface); padding: clamp(20px, 2vw, 28px);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.wcc-hand h3, .wcc-limit h3 { font-size: 16.5px; letter-spacing: -.01em; }
.wcc-hand p, .wcc-limit p { margin-top: 10px; font-size: 14.5px; color: var(--fg-muted); line-height: 1.6; }
/* What an outside audit cannot see is a caveat, not a feature. Marked as one. */
.wcc-limit { background: transparent; border-style: dashed; }
.wcc-limit h3 { color: var(--fg-muted); }

.wcc-end {
  margin-top: clamp(48px, 7vw, 96px);
  padding: clamp(32px, 4.5vw, 56px) clamp(24px, 3.5vw, 44px);
  background: var(--bg-sunk, var(--surface));
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.wcc-end h2 { font-size: clamp(24px, 3.2vw, 38px); max-width: 22ch; }
.wcc-end p { margin-top: 16px; max-width: 64ch; color: var(--body); }

/* The outline variant of .btn, used beside .btn-primary and never defined. */
.btn-ghost { background: transparent; }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }

/* -------------------------------------------------------- side by side (/compare) ---
   Four sites and their scores. .cmp, .who, .track and .fill had no rules at all,
   and the bar widths lived in generated .u-<hash> utility classes that the
   re-shell dropped, so the illustration rendered as four bare words. The widths
   are on the rows now. They are an illustration and the caption beneath them
   says so in the page's own words -- no real site's score is being drawn here. */

.cmp ol { display: grid; gap: 14px; }
.cmp li {
  display: grid; grid-template-columns: minmax(88px, 8.5rem) minmax(0, 1fr);
  align-items: center; gap: 16px;
}
.cmp .who { font-size: 14.5px; color: var(--fg-muted); }
.cmp .you .who { color: var(--fg); }
.cmp .track {
  display: block; height: 12px; border-radius: 999px;
  background: var(--rule); overflow: hidden;
}
.cmp .fill {
  display: block; height: 100%; border-radius: inherit;
  background: color-mix(in srgb, var(--accent) 45%, var(--rule));
}
.cmp .you .fill { background: var(--accent); }
.cmp li:nth-child(1) .fill { width: 72%; }
.cmp li:nth-child(2) .fill { width: 88%; }
.cmp li:nth-child(3) .fill { width: 61%; }
.cmp li:nth-child(4) .fill { width: 44%; }
.cmp .hint { margin-top: 20px; }

/* The batch form. Same field treatment as .search, which is the only other
   text input on the site; before this it was the browser's default box. */
.multi { display: grid; gap: clamp(20px, 2.4vw, 30px); max-width: none; }
.fieldset { max-width: none; }
.fieldset label { display: block; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-muted); }
.fieldset .why { margin-top: 6px; }
.fieldset input,
.fieldset textarea {
  width: 100%; margin-top: 12px; padding: 14px 16px;
  font: inherit; color: var(--fg);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 10px;
  transition: border-color var(--d-1) var(--e-std);
}
.fieldset input { min-height: 48px; }
.fieldset textarea { min-height: 8.5em; line-height: 1.6; resize: vertical; }
.fieldset input::placeholder,
.fieldset textarea::placeholder { color: var(--fg-muted); }
.fieldset input:hover,
.fieldset textarea:hover { border-color: var(--fg-muted); }
.multi .row { align-items: center; margin-top: 0; }
.err:empty { display: none; }
.err { margin-top: 4px; color: var(--bad); font-size: 14px; }

/* Used on /check and /compare under the lede, and by tools.css on the pages
   that link it. Defined here so the two that do not still get it. */
.sub { margin-top: 14px; font-size: 14.5px; color: var(--fg-muted); max-width: 64ch; }

/* The report's own header line and action row. Two generated .u-<hash> utility
   classes carried this layout on the old site and did not survive the re-shell,
   so the two buttons and the note beneath them ran together as one paragraph. */
.report-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.sreport .meta {
  /* 74ch of the body font is far wider than 74ch of the mono one, so the
     shared paragraph measure broke this line in the middle of a phrase. */
  max-width: none;
  margin-top: 16px;
  font-family: var(--font-mono); font-size: 12px;
  letter-spacing: .04em; color: var(--fg-muted);
}
/* Written by sample-report.js when it inserts the filter row, and inserted
   outside .overall -- so the rule scoped to .overall never reached it. */
.sreport .rv-hint { margin-top: 10px; font-size: 13.5px; color: var(--fg-muted); }

/* ------------------------------------------------------------------ guides ---
   Four components the re-shell left without a stylesheet, plus the breadcrumb,
   which kept its padding and lost its layout. */

/* The guides write bare children; .crumb-list is the <ol> the service pages
   use and its flex rule never reached these, so the separators had no space
   around them at all. */
.crumbs {
  padding-top: clamp(16px, 2.5vw, 26px);
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
  font-size: 13px; color: var(--fg-muted);
}
.crumbs a { color: var(--fg-muted); text-underline-offset: 3px; }
.crumbs a:hover { color: var(--fg); }
.crumbs > span { color: var(--rule); }

/* The category, above the title. */
.prose > .cat {
  margin-top: 18px;
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent);
}
.prose > .cat + h1 { margin-top: 14px; }

/* The standfirst. Same weight as .lede, which is what this is. */
.stand {
  margin-top: 22px; max-width: 62ch;
  font-size: clamp(16.5px, 1.35vw, 20px); color: var(--body);
}

/* What the engine checks, one rule per row: a name and what it does. */
.checks { margin-top: 26px; display: grid; gap: 1px;
          background: var(--line); border: 1px solid var(--line);
          border-radius: var(--radius); overflow: hidden; }
/* Two columns need the room for two. Inside .prose's 68-character measure the
   detail column came out at about 45 characters, which is narrower than the
   prose above it. A container query asks the list's own width rather than the
   viewport's, so it stacks wherever it is actually narrow -- and stacked is the
   default, so a browser without container queries gets the readable one. */
.checks { container-type: inline-size; }
.checks > li {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 6px 24px;
  padding: 16px clamp(16px, 1.6vw, 22px);
  background: var(--surface);
}
@container (min-width: 720px) {
  .checks > li { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); }
}
.checks > li > b { font-weight: 500; color: var(--fg); font-size: 15px; }
.checks > li > span { color: var(--fg-muted); font-size: 14.5px; line-height: 1.6; }


/* Sources. Off-site, and the page says so rather than pretending otherwise. */
.src { margin-top: 22px; display: grid; gap: 10px; max-width: 74ch; }
.src > li { padding-left: 18px; position: relative; font-size: 14.5px; }
.src > li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 8px; height: 1px; background: var(--accent);
}
.src a { color: var(--body); text-decoration: underline;
         text-decoration-color: var(--rule); text-underline-offset: 3px; }
.src a:hover { color: var(--fg); text-decoration-color: var(--accent); }

/* The read-next list at the foot of a guide. */
.more { margin-top: clamp(40px, 5vw, 64px); padding-top: clamp(24px, 3vw, 36px);
        border-top: 1px solid var(--line); }
.more h2 { font-size: 17px; }
.more ul { margin-top: 16px;
           display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
           gap: 10px 24px; }
.more li { font-size: 14.5px; line-height: 1.45; }
.more a { color: var(--body); text-underline-offset: 3px; }
.more a:hover { color: var(--fg); text-decoration: underline; text-decoration-color: var(--accent); }

/* The guides' FAQ. Five of them declared an FAQPage in structured data with
   three questions each and showed none of them, which is both a policy
   violation and fifteen good answers nobody could read. */
.gfaq { margin-top: clamp(40px, 5vw, 64px); padding-top: clamp(24px, 3vw, 36px);
        border-top: 1px solid var(--line); }
.gfaq h2 { font-size: 17px; }
.gfaq-item { margin-top: 12px; border-bottom: 1px solid var(--line); }
.gfaq-item summary {
  cursor: pointer; padding: 12px 0; list-style: none;
  font-size: 15.5px; font-weight: 500; color: var(--fg);
  display: flex; align-items: baseline; gap: 12px;
}
.gfaq-item summary::-webkit-details-marker { display: none; }
.gfaq-item summary::after {
  content: '+'; margin-left: auto; color: var(--accent);
  font-family: var(--font-mono); font-size: 16px; line-height: 1;
}
.gfaq-item[open] summary::after { content: '\2212'; }
.gfaq-item > p { margin: 0 0 16px; color: var(--fg-muted); font-size: 14.5px; line-height: 1.65; max-width: 70ch; }

/* The block that says what a page is not, or what it promises. It lived only in
   tools.css, which /terms does not load, so the refund callout -- the strongest
   commercial promise on that page -- rendered as ordinary body text. One
   definition, in the sheet every page loads. */
.note {
  margin-top: 34px;
  padding: 22px 24px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius);
}
.note p { margin: 0; font-size: 14.5px; line-height: 1.65; color: var(--body); }
.note p + p { margin-top: 12px; }
.note b, .note strong { color: var(--fg); font-weight: 500; }
.note a { color: var(--fg); text-underline-offset: 3px; text-decoration-color: var(--line); }
.note a:hover { text-decoration-color: var(--accent); }
.note code {
  font-family: var(--font-mono); font-size: .88em;
  background: var(--bg-sunk); border: 1px solid var(--line);
  border-radius: 5px; padding: .1em .38em;
}

/* ------------------------------------------------------------- /check flow ---
   The summary the email check writes above its detailed results. Every class
   here is the bundle's own, read off the live DOM.

   THE SHIELDS NEED A SIZE. They are inline SVGs with a viewBox and no width,
   and nothing in this stylesheet knew about them, so each rendered at 848px --
   four near-black shields, one per screen, pushing the verdict 3,600px below
   the button that produced it. */
.flow { display: none; }
.flow.on { display: block; margin: 1.6em 0 0; }

.flow-rail {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 4px;
  margin-bottom: 1.2em;
}
.flow-step {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: .5em .95em;
  border: 1px solid var(--rule);
  border-radius: 6.25em;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .08em;
  white-space: nowrap;
  color: var(--fg-muted);
}
/* 15px, and flex: none so the rail cannot stretch it back out. */
.flow-step .sh {
  flex: none;
  width: 15px;
  height: auto;
  fill: currentColor;
}
.flow-step[data-s="pass"] { color: var(--good); border-color: color-mix(in srgb, var(--good) 45%, transparent); }
.flow-step[data-s="warn"] { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.flow-step[data-s="fail"] { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
.flow-step[data-s="unknown"] { color: var(--fg-muted); }

/* The connector. It shrinks away first when the rail has to wrap. */
.flow-link {
  display: flex;
  align-items: center;
  flex: 1 1 14px;
  min-width: 8px;
  max-width: 40px;
}
.flow-link i { display: block; width: 100%; height: 1px; background: var(--rule); }

.flow-verdict {
  padding: .9em 1.15em;
  background: var(--surface);
  border-left: 3px solid var(--rule);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: clamp(15px, 1.15vw, 17px);
  line-height: 1.55;
  color: var(--body);
}
.flow-verdict b { color: var(--fg); font-weight: 500; }
.flow-verdict[data-v="inbox"] { border-left-color: var(--good); }
.flow-verdict[data-v="spam"]  { border-left-color: var(--warn); }

.flow-note { margin-top: .7em; color: var(--fg-muted); font-size: 14px; line-height: 1.5; }

/* The status colours are chosen to sit on cream and land at 2-3:1 on ink, so
   the dark theme gets its own rather than inheriting unreadable ones. */
html[data-theme="dark"] .flow {
  --good: #7FB36B;
  --warn: #D9A441;
  --bad:  #E08A76;
}

/* -------------------------------------------- Core Web Vitals thresholds ---
   The chart on /guides/core-web-vitals-and-page-speed. It had no rules at all:
   every bar measured 714x0 and the tick labels collapsed into "00.10.251.0".

   Each group carries its own two boundaries, and both the bands and the ticks
   are laid out from them, so a label cannot drift from the boundary it names.
   The generated u-xxxxxxx width classes in the markup are inert and unused. */
.cwv { display: grid; gap: clamp(18px, 2vw, 26px); margin: 1.7em 0; }

.cwv-g:nth-child(1) { --cwv-good: 25%; --cwv-mid: 15%; }   /* 2.5s, 4.0s of 10s */
.cwv-g:nth-child(2) { --cwv-good: 20%; --cwv-mid: 30%; }   /* 200ms, 500ms of 1s */
.cwv-g:nth-child(3) { --cwv-good: 10%; --cwv-mid: 15%; }   /* 0.1, 0.25 of 1.0 */

.cwv-g h4 {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg);
}
.cwv-g .sub { margin: .15em 0 .65em; font-size: 13.5px; color: var(--fg-muted); }

.cwv-bar {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--rule);
}
.cwv-bar span { display: block; height: 100%; }
.cwv-bar .g { flex: 0 0 var(--cwv-good); background: var(--good); }
.cwv-bar .a { flex: 0 0 var(--cwv-mid);  background: var(--warn); }
.cwv-bar .r { flex: 1 1 auto;            background: var(--bad); }

/* Each tick sits at the right edge of the band it closes, so 2.5s lands where
   green becomes amber rather than a third of the way along. */
.cwv-scale {
  display: flex;
  margin-top: 7px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--fg-muted);
  white-space: nowrap;
}
.cwv-scale span:nth-child(1) { flex: 0 0 auto; }
.cwv-scale span:nth-child(2) { flex: 0 0 var(--cwv-good); text-align: right; }
.cwv-scale span:nth-child(3) { flex: 0 0 var(--cwv-mid);  text-align: right; }
.cwv-scale span:nth-child(4) { flex: 1 1 auto;            text-align: right; }

.cwv-key {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 20px;
  margin-top: 1.2em;
  font-size: 13.5px;
  color: var(--fg-muted);
}
.cwv-key > span { display: inline-flex; align-items: center; gap: 7px; }
.cwv-key i { flex: none; width: 12px; height: 12px; border-radius: 3px; }
.cwv-key > span:nth-child(1) i { background: var(--good); }
.cwv-key > span:nth-child(2) i { background: var(--warn); }
.cwv-key > span:nth-child(3) i { background: var(--bad); }

/* The status colours are picked to sit on cream and land at 2-3:1 on ink. */
html[data-theme="dark"] .cwv,
html[data-theme="dark"] .cwv-key {
  --good: #7FB36B;
  --warn: #D9A441;
  --bad:  #E08A76;
}

@media (max-width: 600px) {
  /* Four ticks do not fit a phone at 11.5px; the two that carry the meaning
     are the boundaries, so the end of the scale steps down rather than wrap. */
  .cwv-scale { font-size: 10.5px; }
}

/* ------------------------------------------------ the guides' plain FAQ ---
   Five guides wrap their questions in .gfaq and get the designed accordion.
   Seventeen use a bare <details><summary> with a <div class="a"> body and got
   the browser default: a black triangle and no spacing. Same component, so
   the same rules, keyed off the markup that is actually there. */
.prose > details,
.gbody > details {
  margin-top: 12px;
  border-bottom: 1px solid var(--line);
}
.prose > details:first-of-type,
.gbody > details:first-of-type { border-top: 1px solid var(--line); }

.prose > details > summary,
.gbody > details > summary {
  cursor: pointer;
  padding: 12px 0;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-size: 15.5px;
  font-weight: 500;
  color: var(--fg);
}
.prose > details > summary::-webkit-details-marker,
.gbody > details > summary::-webkit-details-marker { display: none; }
.prose > details > summary::after,
.gbody > details > summary::after {
  content: '+';
  margin-left: auto;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1;
}
.prose > details[open] > summary::after,
.gbody > details[open] > summary::after { content: '\2212'; }

.prose > details > .a,
.gbody > details > .a { margin: 0 0 16px; }
.prose > details > .a > p,
.gbody > details > .a > p {
  margin: 0 0 .8em;
  color: var(--fg-muted);
  font-size: 14.5px;
  line-height: 1.65;
  max-width: 70ch;
}
.prose > details > .a > p:last-child,
.gbody > details > .a > p:last-child { margin-bottom: 0; }

/* The sources list drew its own gold dash in a ::before AND kept the disc that
   .prose ul > li turns on, so every line began "· —". Two classes and one
   element, because .prose ul > li is one class and two and would otherwise
   win. */
.prose .src > li,
.src > li { list-style: none; }

/* The questions heading was 17px above 15.5px summaries and under a 28px body
   h2, so the section heading read as the least important thing on the page. */
.gfaq h2 { font-size: clamp(19px, 1.5vw, 22px); }

/* The footer's contact lines are the only links on the site under the 24px
   the accessibility statement claims for tap targets: measured 19px at 390,
   against 44px for every nav link beside them. They are <a> elements separated
   by <br>, so inline-block plus vertical padding is the whole fix. */
.pfoot-block p a,
.footer-block p a {
  display: inline-block;
  padding-block: 4px;
}

/* ============================================================ the weight ===
   Measured before this existed: 87.6% of every word on the site was set at
   weight 400, including a 144px display headline, while geist-600 was
   downloaded on every page load and used by nothing. Weight now follows role.

   These are deliberately last in the file and deliberately specific enough to
   win, because the sizes they apply to are declared in dozens of separate
   component rules that each invented their own clamp(). */

/* Display: the type that is meant to arrive. 600, and tracked in, because
   Geist at 96px with a 28px heading's tracking reads loose rather than set. */
#hero-title,
#end-title,
#goal-title,
#lightening-title,
#pipeline-title,
#footer-statement,
#reel-frame-title,
.hsec-title,
.cta-title,
.section-title,
.phero h1,
#featured-title,
#goal-tunnel-title,
#reel-title,
#scrollnav-link {
  font-weight: 600;
  letter-spacing: -.03em;
}

/* Headings everywhere else. 500 was a half-step that read as body copy at a
   larger size. */
h1, h2, h3 { font-weight: 600; }

/* There is no Geist 700, so bold was being synthesised -- the browser smears
   the 400 outlines and the result looks cheap next to real type. 600 is a
   real cut and it is already loaded. */
strong, b, .prose strong, .prose b { font-weight: 600; }

/* The mono has 400 and 500 only. Its job is labels and data, so its emphasis
   is the 500, never a synthesised bold. */
.mono strong, .mono b { font-weight: 500; }
