/* InstantPalette - site (layer 3 of 4: tokens -> base -> site -> tool)
   Page grid, ad rails and ad containers, the content section below the tool, the site header
   (guide / privacy / 404), prose (guide / privacy), callouts, TOC, breadcrumb, tables, strips, CTA cards,
   the shared footer and the 404 block. */

/* ================= Page grid + ad rails (index only) =================
   Rails: [48px empty gutter][1px divider][16px][300px ad][16px] = 381px. The divider is its own hairline 48px
   from the palette edge; the ad starts below the top bar, level with the palette.
   A rail is shown by the media query that matches the ad placement rule in UI.placeAds(), so the first paint
   already has the right columns (no layout shift). UI.placeAds() then sets [hidden] on a rail it did not use
   and adds .no-rail-l / .no-rail-r to .page, so that column never appears later on a resize.
   Rail ad behaviour (spec "sticky; top: 16px", without ever sitting level with the action bar):
   1. While the tool is on screen (scroll 0 .. 100svh) the ad moves exactly like a static element: it sits beside
      the palette (top 94px, bottom <= 694px, always above the bar at 736px+) and scrolls away with the tool.
   2. Once the tool, action bar included, has scrolled fully above the viewport (scroll >= 100svh = tool height; the
      rails only exist at min-height 501px, so the tool's 320px min-height never applies), the ad is pinned at
      top 16px beside the content until the end of the page.
   Pure sticky cannot do this (the ad has to leave and come back), so the ad is sticky from scroll = --top-h and a
   scroll-linked translate cancels the pin until scroll = 100svh (translate = --top-h - scroll, i.e. static
   movement). Past that range the translate drops (fill: none) and the pin shows. On the way back up the ad
   leaves at the same point, while it is still off screen (its bottom is at most 94 + 600 - 800 = -106px).
   Browsers without scroll-driven animations keep the static rail (it scrolls away with the tool).
   Nothing here moves the <ins> or changes layout: sticky and transform do not affect other boxes (no CLS). */
.page { display: grid; grid-template-columns: minmax(0, 1fr); }
.col { min-width: 0; }
.rail { display: none; position: relative; padding: calc(var(--top-h) + 16px) 16px 16px calc(var(--rail-gutter) + 17px); }
.rail::before { content: ""; position: absolute; top: 0; bottom: 0; left: var(--rail-gutter); width: 1px; background: var(--line); }
.rail-l { padding: calc(var(--top-h) + 16px) calc(var(--rail-gutter) + 17px) 16px 16px; }
.rail-l::before { left: auto; right: var(--rail-gutter); }
.rail-in { position: static; }
@keyframes rail-follow {
  from { transform: translateY(0); }
  to { transform: translateY(calc(var(--top-h) - 100svh)); }
}
@supports (animation-timeline: scroll()) and (animation-range: 0px 1px) {
  /* !important on the animation longhands: base.css sets `animation: none !important` on * under
     prefers-reduced-motion. This is not motion (the ad scrolls exactly as a static box would) and without it the ad
     would stay pinned while the action bar sweeps past it, so it must survive that reset (.rail-in beats *). */
  .rail-in {
    position: sticky; top: 16px;
    animation-name: rail-follow !important;
    animation-duration: 1ms !important;   /* scroll timelines map a single iteration to the whole range */
    animation-timing-function: linear !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    animation-fill-mode: none !important;
    animation-timeline: scroll(root block) !important;
    animation-range: var(--top-h) 100svh !important;
  }
}

@media (min-width: 1280px) and (min-height: 501px) {
  .page { grid-template-columns: minmax(0, 1fr) var(--rail-w); }
  .page.no-rail-r { grid-template-columns: minmax(0, 1fr); }
  .rail-r { display: block; }
}
@media (min-width: 1600px) and (min-height: 501px) {
  .page { grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--rail-w); }
  .page.no-rail-l { grid-template-columns: minmax(0, 1fr) var(--rail-w); }
  .page.no-rail-r { grid-template-columns: minmax(0, 1fr); }
  .rail-l { display: block; }
}

/* Ad label + boxes. The box reserves the unit's size; it is transparent in production. Never overflow:hidden,
   never max-height (a creative must not be cropped). */
.ad-label { margin: 0 0 6px; font: 400 12px/16px var(--f-sans); color: var(--ink-2); }
.ad-box { display: block; background: var(--ad-fill); border-radius: var(--r-xs); }
.ad-box > .adsbygoogle { width: 100%; }
.ad-rail { width: 300px; height: 250px; }
@media (min-height: 800px) { .ad-rail { height: 600px; } }
.ad-inline { margin: 0 0 64px; }
.ad-fluid { width: 100%; min-height: 250px; }
@media (max-width: 767.98px) { .ad-fluid { min-height: 280px; } }

/* ================= Content section below the tool (index) ================= */
.content {
  max-width: calc(var(--measure) + 40px);
  margin: 0 auto;
  padding: 72px 20px 16px;
  font-size: 16px; line-height: 1.65;
}
.c-sec { margin: 0 0 64px; }
.content h2 { margin: 0 0 12px; font: 600 26px/1.2 var(--f-sans); letter-spacing: -.015em; }
.content h3 { font: 600 17px/1.3 var(--f-sans); }
.content p { margin: 0 0 16px; }
/* Inline code in the content column. Matches .prose code, but wraps: a shared URL is longer than the
   measure and must never widen the page. 0.85em of 16px is 13.6px, so it stays above the 12px floor. */
.content code { font: 500 .85em/1.5 var(--f-mono); overflow-wrap: anywhere; }
.lede { font-size: 18px; line-height: 1.6; }
.c-intro { margin-bottom: 32px; }

.steps { list-style: none; counter-reset: step; margin: 20px 0 0; padding: 0; display: grid; gap: 14px; }
.steps li { counter-increment: step; position: relative; min-height: 28px; padding-left: 42px; }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: -1px;
  display: grid; place-items: center;
  width: 28px; height: 28px;
  border: 1px solid var(--ink-1); border-radius: 6px;
  font: 500 13px/1 var(--f-mono);
}

.modes { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(290px, 100%), 1fr)); gap: 36px 32px; margin-top: 24px; }
.mode { border-top: 1px solid var(--line-2); padding-top: 16px; display: flex; flex-direction: column; gap: 12px; }
.mode header { display: grid; grid-template-columns: 40px 1fr; column-gap: 12px; align-items: center; }
.mode .tpl { grid-row: span 2; width: 40px; height: 40px; }
.mode h3 { margin: 0; }
.mode .ang { font: 500 12px/1.4 var(--f-mono); color: var(--ink-2); }
.mode p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--ink-2); }
.mode .best { color: var(--ink-1); font-size: 14px; }
.mode .best b { font-weight: 600; }

/* Colour strip (mode cards, guide examples, guide CTA). Decorative: aria-hidden, codes as text below. */
.strip { display: flex; height: 44px; border-radius: var(--r-sm); overflow: hidden; }
.strip i, .strip span { flex: 1; background: var(--c, transparent); }
.strip-fig { margin: 20px 0 24px; }
.strip-codes { display: flex; margin-top: 6px; font: 500 12px/1.4 var(--f-mono); color: var(--ink-2); }
.strip-codes span { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* Contrast specimen */
.specimen { display: grid; grid-template-columns: 200px 1fr; gap: 24px; align-items: start; margin: 20px 0 24px; }
.spec-sw {
  margin: 0; height: 150px; padding: 14px;
  border-radius: var(--r);
  background: var(--sw); color: var(--ink);
  display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; gap: 8px;
}
.spec-code { font: 500 26px/1.1 var(--f-mono); font-stretch: 87.5%; }
.spec-aa { display: inline-flex; align-items: center; gap: 7px; font: 500 13px/18px var(--f-mono); }
.spec-aa b { font: 600 16px/1 var(--f-sans); }
.spec-aa em { font: 600 12px/1 var(--f-sans); letter-spacing: .03em; font-style: normal; }
.spec-txt p { font-size: 15px; line-height: 1.6; }
.spec-txt p:last-child { margin-bottom: 0; }

/* Hairline table (index contrast table, any guide table) */
.tbl-wrap { overflow-x: auto; margin: 0 0 16px; }
.ctable { width: 100%; border-collapse: collapse; }
.ctable th, .ctable td { text-align: left; padding: 10px 16px 10px 0; border-bottom: 1px solid var(--line); white-space: nowrap; }
.ctable thead th { font: 500 13px/1.3 var(--f-sans); color: var(--ink-2); border-bottom-color: var(--line-2); }
.ctable td { font: 500 14px/1.3 var(--f-mono); font-variant-numeric: tabular-nums; }
.ctable td.txt { font: 400 15px/1.45 var(--f-sans); white-space: normal; }
.ctable tbody th { font: 600 15px/1.3 var(--f-sans); }
.note { font-size: 14px; color: var(--ink-2); margin-top: 12px; }

/* FAQ (native <details>) */
.faq { border-bottom: 1px solid var(--line); }
.faq details { border-top: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 16px 0;
  font: 600 16px/1.4 var(--f-sans);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .i { color: var(--ink-2); transition: transform 160ms var(--ease); }
.faq details[open] summary .i { transform: rotate(45deg); }
.faq details p { margin: -4px 0 18px; color: var(--ink-2); max-width: 64ch; }

/* Guide CTA card (index) and .cta-box (guide): raised card, strong-outline button, never filled */
.guide-cta {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  margin: 0 0 56px; padding: 24px;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--raised);
}
.content .guide-cta h2 { font-size: 20px; margin-bottom: 6px; }
.guide-cta p { margin: 0; color: var(--ink-2); font-size: 15px; }

/* ================= Site header (guide, privacy, 404) ================= */
.site-top { background: var(--ground); border-bottom: 1px solid var(--line); }
.site-top-in {
  --hd-pad-l: 16px; --hd-pad-r: 8px;
  max-width: 1200px; height: var(--top-h); margin: 0 auto;
  padding: 0 var(--hd-pad-r) 0 var(--hd-pad-l);
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
/* The header sits above .page, so it does not know about the ad rails inside it and would otherwise centre on
   the whole viewport - which puts the nav (and the Tools dropdown under it) on top of a live ad unit. Keep the
   header inside the content column whenever a rail is reserved. The breakpoints match UI.placeAds(). */
@media (min-width: 1280px) and (min-height: 501px) {
  .site-top:has(+ .page > .rail-r:not([hidden])) .site-top-in {
    --hd-pad-r: calc(var(--rail-w) + 8px); max-width: calc(1200px + var(--rail-w));
  }
}
@media (min-width: 1600px) and (min-height: 501px) {
  .site-top:has(+ .page > .rail-l:not([hidden])) .site-top-in {
    --hd-pad-l: calc(var(--rail-w) + 16px); max-width: calc(1200px + var(--rail-w) * 2);
  }
}
.brand-a {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
  color: var(--ink-1); text-decoration: none; border-radius: var(--r-sm);
}
.site-nav { display: flex; align-items: center; gap: 2px; }

/* Tools menu (site header and the generator's top bar).
   A native <details> disclosure: it opens and closes with no JS at all. ui.js only adds the niceties every menu
   needs - Esc and an outside pointerdown close it, and focus goes back to the summary on Esc. */
.menu-d { position: relative; flex: none; }
.menu-d > summary { list-style: none; cursor: pointer; }
.menu-d > summary::-webkit-details-marker { display: none; }
.menu-d > summary .i-chev { margin-left: -2px; transition: transform var(--dur-1) var(--ease); }
.menu-d[open] > summary .i-chev { transform: rotate(180deg); }
.menu-d[open] > summary { background: var(--hover); }
.menu-pop {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: var(--z-pop);
  min-width: 236px; padding: 6px;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--raised); box-shadow: var(--shadow-pop);
  display: flex; flex-direction: column;
}
.menu-d[open] > .menu-pop { animation: pop-in 140ms var(--ease); }
.menu-pop a {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 0 10px;
  border-radius: var(--r-sm);
  font: 500 14px/1.25 var(--f-sans); color: var(--ink-1); text-decoration: none;
}
.menu-pop a .i { width: 18px; height: 18px; color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) { .menu-pop a:hover { background: var(--hover); } }
.menu-pop a[aria-current="page"] { background: var(--sunken); box-shadow: inset 0 0 0 1px var(--line-2); }
.menu-pop hr { margin: 4px 8px; border: 0; border-top: 1px solid var(--line); }

/* ================= "Open in ..." row =================
   The palette handoff. These are real root-relative links, so a crawler sees /contrast-checker; PaletteState.link
   appends ?c= to each one on every render, so a reader carries the palette on screen. Never filled. */
.openin { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.openin-h { margin: 0; font: 600 13px/1.4 var(--f-sans); color: var(--ink-2); flex: none; }
.openin a {
  height: 40px; display: inline-flex; align-items: center; gap: 8px;
  padding: 0 14px;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--raised); color: var(--ink-1);
  font: 500 14px/1 var(--f-sans); text-decoration: none; white-space: nowrap;
  transition: border-color var(--dur-1) var(--ease);
}
.openin a .i { width: 18px; height: 18px; color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) { .openin a:hover { border-color: var(--ink-1); } }
@media (hover: none), (pointer: coarse) { .openin a { height: 44px; } }
/* On index the row is the first block under the tool, above the intro */
.openin-sec { margin: 0 0 40px; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.openin-sec .openin-h { font-size: 14px; }

/* ================= Prose (guide, privacy) ================= */
.prose {
  max-width: calc(var(--measure) + 40px); margin: 0 auto;
  padding: 40px 20px 64px;
  font-size: 17px; line-height: 1.7; color: var(--ink-1);
}
.prose p { margin: 0 0 18px; }
.prose a:not([class]) {
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) { .prose a:not([class]):hover { text-decoration-thickness: 2px; } }
.prose h1 { margin: 0 0 12px; font: 700 32px/1.15 var(--f-sans); letter-spacing: -.02em; }
.prose h2 { margin: 0 0 14px; font: 600 26px/1.2 var(--f-sans); letter-spacing: -.015em; scroll-margin-top: 72px; }
.prose h3 { margin: 32px 0 10px; font: 600 19px/1.3 var(--f-sans); scroll-margin-top: 72px; }
.prose h4 { margin: 24px 0 8px; font: 600 17px/1.4 var(--f-sans); }
.prose h2 + h3, .prose h3 + h4 { margin-top: 16px; }
.prose ul, .prose ol { margin: 0 0 18px; padding-left: 1.35em; }
.prose li { margin: 0 0 8px; padding-left: 2px; }
.prose li::marker { color: var(--ink-2); }
.prose strong, .prose b { font-weight: 600; }
.prose code { font: 500 .85em/1 var(--f-mono); }
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 40px 0; }
.prose > section, .guide-section, .privacy-section { margin-top: 56px; }
/* TOC / in-page links target the <section id>, not its h2: the margin must sit on the section (its 56px top margin
   is not part of the snap) so a jump leaves 72px above the heading */
.prose > section[id], .guide-section, .privacy-section { scroll-margin-top: 72px; }
.prose > section > :last-child { margin-bottom: 0; }

/* Page header block inside .prose */
.page-hd { margin: 0 0 32px; }
.guide-subtitle, .page-sub { margin: 0 0 12px; font-size: 18px; line-height: 1.6; color: var(--ink-2); }
.last-updated { margin: 0 0 4px; font-size: 13px; line-height: 1.6; color: var(--ink-2); }
.last-updated time, .last-updated .mono { font: 500 12px/1.6 var(--f-mono); }
.last-updated strong { font-weight: 600; color: var(--ink-1); }
/* Inside .prose these must beat the generic `.prose p` margin (0,1,1) */
.prose .guide-subtitle, .prose .page-sub { margin: 0 0 12px; }
.prose .last-updated { margin: 0 0 4px; }
/* A <button class="linklike"> inside running text (privacy summary) reads as a normal underlined prose link */
.prose .linklike { font: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
@media (hover: hover) and (pointer: fine) { .prose .linklike:hover { text-decoration-thickness: 2px; } }

/* Breadcrumb: <nav class="breadcrumb" aria-label="Breadcrumb"><ol><li><a href="/">Home</a></li><li><span aria-current="page">...</span></li></ol></nav> */
.breadcrumb { margin: 0 0 14px; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.breadcrumb ol { display: flex; flex-wrap: wrap; margin: 0; padding: 0; list-style: none; }
.breadcrumb li { margin: 0; padding: 0; }
.breadcrumb li + li::before { content: "/"; margin: 0 8px; color: var(--ink-3); }
.breadcrumb a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
@media (hover: hover) and (pointer: fine) { .breadcrumb a:hover { color: var(--ink-1); } }
.breadcrumb [aria-current="page"] { color: var(--ink-1); }

/* Table of contents: <nav class="toc" aria-label="Contents"><h2>Contents</h2><ol|ul>...</ol></nav> */
.toc {
  margin: 0 0 8px; padding: 16px 20px;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--raised);
}
.prose .toc h2, .toc .toc-h { margin: 0 0 6px; font: 600 13px/1.4 var(--f-sans); letter-spacing: 0; color: var(--ink-2); }
.toc ol, .toc ul { margin: 0; padding: 0; list-style: none; font-size: 15px; line-height: 1.9; }
.toc li { margin: 0; padding: 0; }
.toc a, .prose .toc a:not([class]) { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .toc a:hover, .prose .toc a:not([class]):hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
}

/* Callouts: never hue. They differ by icon, label and border style only.
   Markup: <div class="callout is-tip"><p class="co-label">Tip</p><p>...</p></div>
   The old guide classes (.tip-box, .warning-box, .highlight-box, .contact-box) get the same treatment. */
.callout, .tip-box, .warning-box, .highlight-box, .contact-box {
  position: relative;
  margin: 24px 0; padding: 16px 20px 16px 52px;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--raised);
  font-size: 16px; line-height: 1.65;
}
.callout > :last-child, .tip-box > :last-child, .warning-box > :last-child, .highlight-box > :last-child, .contact-box > :last-child { margin-bottom: 0; }
.callout p, .tip-box p, .warning-box p, .highlight-box p, .contact-box p { margin: 0 0 10px; }
.callout ul, .contact-box ul { margin: 0 0 10px; }
.co-label { margin: 0 0 2px !important; font: 600 13px/1.4 var(--f-sans); color: var(--ink-2); }
/* Icon: 20px at left 18, top 18, drawn with a mask so no sprite is needed */
.callout::before, .tip-box::before, .warning-box::before, .contact-box::before {
  content: ""; position: absolute; left: 18px; top: 18px; width: 20px; height: 20px;
  background: var(--ink-1);
  -webkit-mask: var(--co-ico) center / 20px 20px no-repeat;
  mask: var(--co-ico) center / 20px 20px no-repeat;
}
.callout, .tip-box, .is-tip {
  --co-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 17.5h6'/%3E%3Cpath d='M10 20.5h4'/%3E%3Cpath d='M12 3.5a5.5 5.5 0 0 0-3.2 10c.7.5 1.2 1.3 1.2 2.2v.3h4v-.3c0-.9.5-1.7 1.2-2.2A5.5 5.5 0 0 0 12 3.5z'/%3E%3C/svg%3E");
}
.warning-box, .callout.is-warn {
  border: 1.5px dashed var(--ink-1);
  --co-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4.5 3.8 19h16.4z'/%3E%3Cpath d='M12 10v4'/%3E%3Ccircle cx='12' cy='16.6' r='.95' fill='%23000' stroke='none'/%3E%3C/svg%3E");
}
.contact-box, .callout.is-contact, .highlight-box, .callout.is-key {
  --co-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M12 11v5'/%3E%3Ccircle cx='12' cy='8' r='.95' fill='%23000' stroke='none'/%3E%3C/svg%3E");
}
/* Key point: a 3px ink rule on the left instead of the icon inset; the info icon sits inline before the label */
.highlight-box, .callout.is-key { padding-left: 20px; border-left: 3px solid var(--ink-1); }
.highlight-box::before, .callout.is-key::before { content: none; }
.highlight-box .co-label, .callout.is-key .co-label { display: flex; align-items: center; gap: 6px; }
.highlight-box .co-label::before, .callout.is-key .co-label::before {
  content: ""; width: 16px; height: 16px; flex: none; background: var(--ink-2);
  -webkit-mask: var(--co-ico) center / 16px 16px no-repeat;
  mask: var(--co-ico) center / 16px 16px no-repeat;
}

/* Guide CTA (.cta-box): raised card with a live 44px strip on top (UI.fillStrip) and a strong-outline button */
.cta-box {
  margin: 56px 0 32px; padding: 24px;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--raised);
}
.cta-box .strip { margin: 0 0 20px; }
.prose .cta-box h2, .prose .cta-box h3, .cta-box .cta-h { margin: 0 0 8px; font: 600 20px/1.25 var(--f-sans); letter-spacing: -.01em; }
.cta-box p { margin: 0 0 20px; font-size: 16px; line-height: 1.6; color: var(--ink-2); }
.cta-button {
  height: 44px; display: inline-flex; align-items: center; gap: 8px;
  padding: 0 16px;
  border: 1px solid var(--ink-1); border-radius: var(--r);
  background: transparent; color: var(--ink-1);
  font: 500 15px/1 var(--f-sans); text-decoration: none; white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) { .cta-button:hover { box-shadow: inset 0 0 0 1px var(--ink-1); } }
.cta-button .i { width: 18px; height: 18px; }

/* Back link: 36px ghost button "Back to the generator" with a flipped i-arrow */
.back-link { margin-top: 8px; }
.back-link .i { width: 18px; height: 18px; }
/* After a plain section (privacy) the last child has no bottom margin, so give the back link its own gap */
.prose > section + .back-link { margin-top: 40px; }
/* 404: no single-word last line */
.nf h1, .nf p { text-wrap: balance; }

/* Coarse pointers: the 36px ghost button (the content section's "Use <mode>" row, the back link on the guide
   and privacy) reaches the same 44px target as every other control, and the in-prose link button gets its
   target from vertical padding, so it keeps its baseline inside the sentence it sits in. Fine pointers are
   untouched, so nothing moves on desktop. */
@media (hover: none), (pointer: coarse) {
  .ghost { height: auto; min-height: 44px; }
  /* The in-prose button sits inside a sentence, and a <button> is an inline-block: padding would grow the line
     box and open a gap in the paragraph. An overlaid pseudo-element gives it the same 44px touch height with no
     reflow at all. It is a child of the button, so a tap anywhere in it is a tap on the button. */
  .prose .linklike { position: relative; }
  .prose .linklike::after {
    content: ''; position: absolute; z-index: 1;
    left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%);
  }
}

/* ================= Shared footer ================= */
.site-foot { border-top: 1px solid var(--line); padding: 28px 20px 36px; }
/* 72ch must resolve at the font size of the column above it, so the footer lines up with it: 17px under .prose
   (guide, privacy), 16px under the index .content. Every footer child sets its own font, so nothing else changes. */
.foot-in { max-width: var(--measure); font-size: 17px; margin: 0 auto; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px 24px; }
.foot-links { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 20px; }
.foot-links a { color: var(--ink-1); text-decoration: none; font: 500 14px/1.6 var(--f-sans); }
@media (hover: hover) and (pointer: fine) { .foot-links a:hover { text-decoration: underline; text-underline-offset: 3px; } }
/* Tools row: its own full-width line above the main footer links, on every page */
.foot-tools { flex: 1 0 100%; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.foot-tools a { color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) { .foot-tools a:hover { color: var(--ink-1); } }
.foot-note { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.col > .site-foot .foot-in { font-size: 16px; }
@media (hover: none), (pointer: coarse) {
  .foot-links a, .foot-links .linklike { display: inline-flex; align-items: center; min-height: 44px; }
}

/* ================= 404 ================= */
.nf { max-width: 480px; margin: 0 auto; padding: 12vh 20px 64px; text-align: center; }
.nf .wedge { width: 64px; height: 64px; margin: 0 auto 24px; display: block; }
.nf h1 { margin: 0 0 12px; font: 700 32px/1.15 var(--f-sans); letter-spacing: -.02em; }
.nf p { margin: 0 0 28px; font-size: 17px; line-height: 1.6; color: var(--ink-2); }
.nf-acts { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px 20px; }
.nf-acts a:not([class]) { font: 500 15px/1.6 var(--f-sans); text-decoration: underline; text-underline-offset: 3px; min-height: 44px; display: inline-flex; align-items: center; }

/* ================= Small screens ================= */
@media (max-width: 600px) {
  .content { padding-top: 56px; }
  .content h2 { font-size: 23px; }
  .specimen { grid-template-columns: 1fr; }
  .guide-cta { flex-direction: column; align-items: flex-start; }
  .prose h1, .nf h1 { font-size: 26px; }
  .prose h2 { font-size: 23px; }
  .cta-box { padding: 20px; }
}
/* Small phones: the header carries brand + Tools + Guide + theme. The "Generator" link goes, because the brand
   beside it is the same link, and the Tools menu lists it too. Measured at 360px: the nav ends at 352px. */
@media (max-width: 479.98px) {
  .site-nav > .nav-a[href="/"] { display: none; }
}
@media (max-width: 400px) {
  .site-top-in { padding: 0 4px 0 12px; gap: 4px; }
  .site-top .brand-a { gap: 8px; }
  .site-top .wm { font-size: 17px; }
  .site-nav .nav-a { padding: 0 7px; }
}
/* Phones (portrait and landscape): leave room at the end of the page for the Auto ads anchor */
@media (max-width: 767.98px), (orientation: landscape) and (max-height: 500px) {
  .site-foot { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
}
