/* ==========================================================================
   Caching Out — Block styles
   --------------------------------------------------------------------------
   Styles for the theme's ACF blocks. Load AFTER tokens.css and motion.css.

   Rule (design/00-README.md): reference SEMANTIC tokens only
   (--surface-*, --text-*, --border-*, --action-*). Reaching past the semantic
   layer to a primitive breaks dark mode silently.

   Nothing in here is inline. Every block template emits classes only.
   ========================================================================== */

/* ==========================================================================
   0a. LAYOUT ESCAPE
   --------------------------------------------------------------------------
   theme.json constrains post-content to 680px. Section blocks must break out
   of that column or their content is squeezed into a phone-width strip on a
   desktop screen.

   Symptom this fixes: an H1 wrapping one word per line and a panel pushed off
   the right edge with a horizontal scrollbar.
   ========================================================================== */

.co-section {






  width: 100%;
  max-width: 100%;
  margin-inline: 0;
}

/* ==========================================================================
   0. SHARED PRIMITIVE COMPONENTS (used by more than one block)
   ========================================================================== */

/* --- Icons: 1.5px line, 24px grid, currentColor, no fills ---------------- */

.co-icon {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- Buttons -------------------------------------------------------------
   Geometry from 04-component-library.md §1-2. Never two primaries adjacent. */

.co-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: 14px var(--space-6);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}

.co-btn--lg {
  min-height: 56px;
  padding: 18px var(--space-8);
}

.co-btn--primary {
  background: var(--action-primary-bg);
  color: var(--action-primary-text);
  box-shadow: var(--shadow-sm);
}

.co-btn--primary:hover {
  background: var(--action-primary-bg-hover);
  color: var(--action-primary-text);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.co-btn--primary:active {
  background: var(--action-primary-bg-active);
  transform: translateY(0);
  box-shadow: none;
}

.co-btn--secondary {
  background: var(--action-secondary-bg);
  border-color: var(--action-secondary-border);
  color: var(--action-secondary-text);
}

.co-btn--secondary:hover {
  background: var(--action-secondary-bg-hover);
  border-color: var(--action-secondary-border-hover);
  color: var(--action-secondary-text);
}

/* --- "Learn more" style link --------------------------------------------- */

.co-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  color: var(--text-link);
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
}

.co-link:hover {
  color: var(--text-link-hover);
}

.co-link__chevron {
  width: 1rem;
  height: 1rem;
  transition: transform var(--duration-fast) var(--ease);
}

.co-link:hover .co-link__chevron {
  transform: translateX(2px);
}

/* --- Footnotes ------------------------------------------------------------
   Section B of docs/website-claims-provision.md: a caveat is a visible,
   clickable footnote on the same page - not a tooltip, not a legal page. The
   text lives in inc/class-footnotes.php; a block only names the key. Used by
   feature-grid and feature-detail, so it is a shared primitive. */

.co-fn-ref {
  font-size: 0.72em;
  line-height: 0;
  vertical-align: super;
  /* Clear the sticky header when a backlink lands here. */
  scroll-margin-block-start: calc(var(--nav-height, 64px) + var(--space-4));
}

.co-fn-ref a {
  padding-inline: 0.2em;
  color: var(--text-link);
  font-family: var(--font-mono);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.co-fn-ref a:hover {
  color: var(--text-link-hover);
  text-decoration: underline;
}

/* The list is collapsed behind a one-line summary. The notes stay in the
   markup - printed, crawlable, readable with JavaScript off - but the reader
   opts in, which is the whole point: on Home this list was 540px (5.8% of the
   page) of text most readers skip. The rule that used to sit on .co-fn moves
   here so the collapsed state carries it too. */
.co-fn-disclosure {
  max-width: 72ch;
  margin-block-start: var(--space-8);
  padding-block-start: var(--space-4);
  border-block-start: var(--border-width) solid var(--border-subtle);
}

.co-fn-disclosure__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.04em;
  color: var(--text-muted);
  list-style: none;
}

/* Safari still paints its own triangle without this. */
.co-fn-disclosure__summary::-webkit-details-marker {
  display: none;
}

.co-fn-disclosure__summary::before {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-inline-end: var(--border-width-thick) solid currentColor;
  border-block-end: var(--border-width-thick) solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--duration-fast, 150ms) ease;
}

.co-fn-disclosure[open] > .co-fn-disclosure__summary::before {
  transform: rotate(45deg);
}

.co-fn-disclosure__summary:hover {
  color: var(--text-secondary);
}

@media (prefers-reduced-motion: reduce) {
  .co-fn-disclosure__summary::before {
    transition: none;
  }
}

.co-fn {
  max-width: 72ch;
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-caption);
  line-height: 1.55;
  color: var(--text-secondary);
}

.co-fn__item {
  display: grid;
  grid-template-columns: 2ch 1fr;
  gap: var(--space-2);
  align-items: baseline;
  margin: 0;
  padding: 0;
  scroll-margin-block-start: calc(var(--nav-height, 64px) + var(--space-4));
}

.co-fn__item + .co-fn__item {
  margin-block-start: var(--space-3);
}

.co-fn__num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.co-fn__text {
  margin: 0;
  text-wrap: pretty;
}

.co-fn__back {
  color: var(--text-link);
  /* Underlined: inside running text a link needs a non-colour cue (axe
     link-in-text-block; link and body ink differ by only 1.3:1). */
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.co-fn__back:hover {
  color: var(--text-link-hover);
}

/* --- Footnote popover -----------------------------------------------------
   Built by assets/js/footnotes.js, which positions it in viewport coordinates
   and never inlines a style beyond left/top. Where the Popover API exists the
   panel is in the top layer, so it cannot be clipped by an ancestor's overflow
   or fought over by the sticky header's z-index; the fallback below reproduces
   that with a plain fixed element. */

.co-fn-pop {
  position: fixed;
  /* The UA stylesheet for [popover] sets `inset: 0; margin: auto` to centre
     it. Both are cleared here so the left/top the script computes are the
     only things placing the panel. */
  inset: auto;
  z-index: 90;
  box-sizing: border-box;
  width: min(38ch, calc(100vw - 2 * var(--space-4)));
  margin: 0;
  padding: var(--space-4);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg, 0 12px 32px rgb(0 0 0 / 18%));
  color: var(--text-secondary);
  font-size: var(--text-caption);
  line-height: 1.55;
  overflow: visible;
}

/* The element carries popover="auto" where supported, so the UA hides it;
   this is the fallback path, where visibility is a class. */
.co-fn-pop:not([popover]) {
  display: none;
}

.co-fn-pop:not([popover]).is-open {
  display: block;
}

.co-fn-pop__body {
  display: grid;
  grid-template-columns: 2ch 1fr;
  gap: var(--space-2);
  align-items: baseline;
  /* Room for the close button, which is positioned over the corner. */
  padding-inline-end: var(--space-5);
}

.co-fn-pop__num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.co-fn-pop__text {
  margin: 0;
  text-wrap: pretty;
}

.co-fn-pop__close {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-end: var(--space-2);
  display: flex;
  align-items: center;
  justify-content: center;
  /* 32px: a real touch target, not a 12px glyph. */
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-muted);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}

.co-fn-pop__close:hover {
  background: var(--surface-sunken);
  color: var(--text-primary);
}

/* The panel takes focus when it opens, so it must show a ring like anything
   else that can be focused. */
.co-fn-pop:focus-visible,
.co-fn-pop__close:focus-visible {
  outline: var(--border-width-thick) solid var(--border-accent);
  outline-offset: 2px;
}

/* Nothing to pop up on paper: print the notes, not the trigger state. */
@media print {
  .co-fn-pop {
    display: none !important;
  }

  .co-fn-disclosure > .co-fn {
    display: block !important;
  }
}

/* --- Edition badges -------------------------------------------------------
   Says which edition owns a feature. Used by feature-grid, feature-detail and
   the pricing plans, so it is a shared primitive like the footnotes above it.

   Filled, not outlined. The first version was a quiet outlined pill sitting
   beside the heading; across twelve cards it was neither findable nor
   scannable, because an inline badge moves with the length of the title in
   front of it. These are solid, and on a card they are pinned to the corner so
   every one lands in the same place.

   Free and Pro differ in FILL as well as hue - Pro is the accent, Free is ink
   on a neutral ground - so the pair survives a greyscale print and any form of
   colour blindness. The visible text is aria-hidden and a longer form is read
   instead (see CachingOut_Editions). */

.co-edition {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1, 4px);
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: var(--weight-semibold, 600);
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Free: the default state, so it is the calm one - but solid, not a ghost. */
.co-edition--free {
  background: var(--surface-sunken);
  border: var(--border-width) solid var(--border-subtle);
  color: var(--text-secondary);
}

/* Pro: the thing you are being sold. The only filled accent on the card. */
.co-edition--pro {
  background: var(--text-accent);
  border: var(--border-width) solid var(--text-accent);
  color: var(--surface-page);
}

/* Both, and honest about it: an accent edge on a free ground. */
.co-edition--mixed {
  background: var(--surface-sunken);
  border: var(--border-width) solid var(--text-accent);
  color: var(--text-accent);
}

/* Optional (homepage brief badge styles): off until switched on, in either
   edition. Dashed, so it reads as "not yet" rather than as a tier. */
.co-edition--optional {
  background: transparent;
  border: var(--border-width) dashed var(--text-secondary);
  color: var(--text-secondary);
}

/* Pinned to the card corner. The card is the positioning context; the tag is
   taken out of the grid flow so it does not push the icon down. */
.co-features__card {
  position: relative;
}

.co-features__card > .co-edition {
  position: absolute;
  inset-block-start: var(--space-5);
  inset-inline-end: var(--space-6);
  /* Never let a long tag collide with the icon on a narrow card. */
  max-width: calc(100% - var(--space-6) * 2);
}

/* In a feature-detail item there is no card to pin to, so it stays beside the
   title - same tag, placed where the context allows. */
.co-fdetail__item-title > .co-edition {
  margin-inline-start: var(--space-2);
  vertical-align: middle;
}

/* --- Chips ---------------------------------------------------------------
   A state pill is distinguished from a brand element by shape and a dot,
   never by hue — both are green, deliberately (02-design-direction.md §2.1). */

.co-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
  line-height: 1.4;
  text-transform: uppercase;
}

.co-chip--brand {
  background: var(--chip-brand-bg);
  color: var(--chip-brand-text);
}

.co-chip__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: currentColor;
}

/* --- Theme toggle --------------------------------------------------------
   Lives in the header. The design ships light and dark token sets and
   tokens.css already honours both `[data-theme]` and `prefers-color-scheme`;
   this is the control that lets a visitor override the OS.

   PROGRESSIVE ENHANCEMENT, and the default state is the safe one: the button
   is `display: none` until theme-toggle.js puts `.co-theme-ready` on <html>.
   A theme switch is meaningless without JavaScript, and a visible control
   that does nothing when clicked is worse than no control — the visitor
   assumes the site is broken, or that they mis-clicked.

   Set in mono like every other label in this system: it is a state readout,
   not marketing copy. */

.co-theme-toggle {
  display: none;
  align-items: center;
  gap: var(--space-2);
  /* 44px: the minimum comfortable touch target, and it matches .co-link so
     the control sits on the nav's optical baseline rather than above it. */
  min-height: 44px;
  padding: 6px var(--space-3);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: none;
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.1em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

.co-theme-ready .co-theme-toggle {
  display: inline-flex;
}

.co-theme-toggle:hover {
  border-color: var(--border-default);
  background: var(--surface-sunken);
  color: var(--text-primary);
}

.co-theme-toggle__icon {
  width: 0.9375rem;
  height: 0.9375rem;
  color: var(--text-accent);
}

/* Show the icon for the state the button MOVES TO, matching the text label
   the JS writes. In light mode the button offers dark, so the moon shows. */
.co-theme-toggle__icon--sun {
  display: none;
}

[data-theme="dark"] .co-theme-toggle__icon--sun {
  display: block;
}

[data-theme="dark"] .co-theme-toggle__icon--moon {
  display: none;
}

/* Before any explicit choice is stored the OS preference is in force, so the
   icons must follow it too — otherwise a visitor whose system is dark sees a
   correctly dark page offering to "switch to dark". */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .co-theme-toggle__icon--sun {
    display: block;
  }

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

  /* An explicit light choice must still win over the OS. */
  :root[data-theme="light"] .co-theme-toggle__icon--sun {
    display: none;
  }

  :root[data-theme="light"] .co-theme-toggle__icon--moon {
    display: block;
  }
}

/* The word is confirmation, not the signal — the icon and aria-pressed both
   carry the state. Dropped on small screens where nav space is scarce. */
.co-theme-toggle__text {
  display: none;
}

@media (min-width: 1024px) {
  .co-theme-toggle__text {
    display: inline;
  }
}


/* ==========================================================================
   11. HEADER AND FOOTER TEMPLATE PARTS
   --------------------------------------------------------------------------
   These are NOT blocks. They are here because they were the actual source of
   the site's remaining inline styles, and the fix belongs with the rest of the
   values rather than scattered through components.css.

   Cause, worth stating once: a block's style / spacing / typography / width
   ATTRIBUTES are serialised by WordPress core into a style="" attribute on the
   rendered element. So {"width":"33%"} in a wp:column comment becomes
   style="flex-basis:33%" in the HTML. That is an inline style the minifier
   this plugin demonstrates cannot act on. The template parts therefore carry
   className only, and every value lives here.

   Do not "improve" the parts by adding spacing or width attributes back.
   ========================================================================== */

/* --- 11.0 Top-level rhythm -----------------------------------------------
   theme.json's root blockGap makes core put a margin between the top-level
   blocks of every template: header, main, CTA band, footer. On the pages
   where two dark bands meet (final CTA over footer) that margin showed as a
   white strip, and in dark mode it showed as a light strip between the page
   header and the pricing section. Sections own their own vertical space, so
   the site-level gap is zero. `body` prefix outranks core's own selector. */

body .wp-site-blocks > * + * {
  margin-block-start: 0;
}

/* The same gap inside post content: core's flow layout puts blockGap between
   sibling blocks, so two adjacent full-width section blocks showed a strip of
   page background between them (dark band over dark band on How It Works,
   tinted over grey on Pricing). Sections own their own padding. Scoped to
   full-width siblings so prose blocks on the legacy pages keep their rhythm. */
.wp-block-post-content > .alignfull + .alignfull {
  margin-block-start: 0;
}

.wp-block-post-content > .alignfull:first-child {
  margin-block-start: 0;
}

/* --- 11.0b (retired 2026-10-23) --------------------------------------------
   The announcement bar's rules lived here. The release bar left the header
   part for the top bar (components.css section 4.1, inc/class-topbar.php);
   cachingout/announce stays registered but renders nowhere. */

/* --- 11.1 Header ---------------------------------------------------------
   components.css section 4 owns the sticky positioning, blur and hairline.
   This section owns the padding, the link treatment, the CTA, the mobile
   overlay and the docs search band. All semantic tokens, so both themes
   work without a [data-theme] rule. */

.co-nav {
  padding: var(--space-3) var(--space-4);
}

@media (min-width: 48em) {
  .co-nav {
    padding: var(--space-3) var(--space-6);
  }
}

/* Inline lockup. The arc and wordmark take the text colour of wherever the
   logo sits, the response stroke and "Out" take the accent - so the same
   markup is ink-on-paper in the header and paper-on-ink in the footer. */
.co-logo {
  display: inline-flex;
  flex: none;
  align-items: center;
  color: var(--text-primary);
  text-decoration: none;
}

.co-logo__svg {
  display: block;
  height: 28px;
  width: auto;
  fill: none;
  overflow: visible;
}

.co-logo__arc {
  fill: none;
  stroke: currentColor;
}

.co-logo__stroke {
  fill: none;
  stroke: var(--text-accent);
}

.co-logo__word {
  font-family: var(--font-heading);
  fill: currentColor;
}

.co-logo__word-accent {
  fill: var(--text-accent);
}

.co-nav__right {
  gap: var(--space-2);
  min-width: 0;
}

@media (min-width: 64em) {
  .co-nav__right {
    gap: var(--space-4);
  }
}

.co-nav .wp-block-navigation-item__content {
  display: inline-block;
  padding: var(--space-2) var(--space-3);
  border-radius: 6px;
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease),
              background-color var(--duration-fast) var(--ease);
}

.co-nav .wp-block-navigation-item__content:hover {
  color: var(--text-primary);
  background: var(--surface-sunken);
}

.co-nav .current-menu-item > .wp-block-navigation-item__content {
  color: var(--text-accent);
}

/* --- 11.1b Dropdown menus (2026-10-25) -----------------------------------
   Features and Docs open a panel on wide screens (inc/class-menus.php,
   assets/js/co-menu.js). The panel is absent below 1024px and inside the
   phone drawer, which is already the full list; the caret goes with it.
   Open state is .is-open on the item; the motion is a fade and a 6px rise
   over --duration-base, none under reduced motion. An invisible bridge
   above the panel keeps a diagonal pointer move from closing it. */

.co-menu__caret,
.co-menu__panel {
  display: none;
}

@media (min-width: 64em) {
  .co-nav .co-menu {
    position: relative;
  }

  .co-nav .co-menu__link {
    display: inline-flex;
    align-items: center;
    gap: 2px;
  }

  .co-nav .co-menu__caret {
    display: block;
    width: 0.875rem;
    height: 0.875rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform var(--duration-base) var(--ease);
  }

  .co-nav .co-menu.is-open .co-menu__caret {
    transform: rotate(180deg);
  }

  .co-nav .co-menu__panel {
    position: absolute;
    inset-block-start: calc(100% + var(--space-3));
    inset-inline-start: 50%;
    z-index: var(--z-drawer);
    display: block;
    width: 22rem;
    padding: var(--space-3);
    border: var(--border-width) solid var(--border-subtle);
    border-radius: var(--radius-xl);
    background: var(--surface-raised);
    box-shadow: var(--elevation-overlay);
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, 6px);
    transition: opacity var(--duration-base) var(--ease),
                transform var(--duration-base) var(--ease),
                visibility 0s linear var(--duration-base);
  }

  .co-nav .co-menu__panel--wide {
    width: min(44rem, calc(100vw - var(--space-8)));
  }

  /* The bridge across the gap between the link and the panel. */
  .co-nav .co-menu__panel::before {
    content: "";
    position: absolute;
    inset: calc(-1 * var(--space-4)) 0 auto;
    height: var(--space-4);
  }

  .co-nav .co-menu.is-open .co-menu__panel {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition: opacity var(--duration-base) var(--ease),
                transform var(--duration-base) var(--ease),
                visibility 0s linear 0s;
  }

  .co-menu__grid {
    display: grid;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .co-menu__panel--wide .co-menu__grid {
    grid-template-columns: 1fr 1fr;
  }

  .co-menu__entry {
    margin: 0;
  }

  .co-nav .co-menu__item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3);
    border-radius: var(--radius-lg);
    color: var(--text-primary);
    text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease);
  }

  .co-nav .co-menu__item:hover,
  .co-nav .co-menu__item:focus-visible {
    background: var(--surface-sunken);
  }

  .co-menu__icon {
    display: grid;
    flex: none;
    place-items: center;
    width: var(--space-10);
    height: var(--space-10);
    border-radius: var(--radius-md);
    background: var(--tint-mint);
    color: var(--text-on-tint);
  }

  .co-menu__icon--2 {
    background: var(--tint-peach);
  }

  .co-menu__icon--3 {
    background: var(--tint-sun);
  }

  /* In the dark theme the sand tint is the panel's own shade; the hairline
     keeps the tile visible there. */
  .co-menu__icon--4 {
    border: var(--border-width) solid var(--border-default);
    background: var(--tint-sand);
  }

  .co-menu__text {
    display: grid;
    gap: 2px;
    min-width: 0;
  }

  .co-menu__title {
    font-size: var(--text-body-sm);
    font-weight: var(--weight-semibold);
    line-height: 1.3;
  }

  .co-menu__desc {
    font-size: var(--text-caption);
    line-height: 1.45;
    color: var(--text-secondary);
  }

  .co-menu__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-6);
    margin-block-start: var(--space-2);
    padding: var(--space-3) var(--space-3) var(--space-1);
    border-block-start: var(--border-width) solid var(--border-subtle);
  }

  .co-nav .co-menu__foot-link {
    font-size: var(--text-body-sm);
    font-weight: var(--weight-semibold);
    color: var(--text-link);
    text-decoration: none;
  }

  .co-nav .co-menu__foot-link:hover {
    color: var(--text-link-hover);
  }

  /* Inside the phone drawer the list is the menu; no panel, no caret. */
  /* (The caret also waits for 1280px: the row at 1024 has 8px to spare.) */
  .co-nav .co-nav__menu .is-menu-open .co-menu__panel,
  .co-nav .co-nav__menu .is-menu-open .co-menu__caret {
    display: none;
  }
}

@media (min-width: 64em) and (max-width: 79.9375em) {
  .co-nav .co-menu__caret {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .co-nav .co-menu__panel,
  .co-nav .co-menu.is-open .co-menu__panel,
  .co-nav .co-menu__caret {
    transition: none;
  }
}

/* --- 11.1a The phone menu -------------------------------------------------
   Core's navigation overlay, restyled (operator, 2026-10-01: the unstyled
   one was a narrow right-aligned column of links on white with no brand and
   no call to action). A full-height ink panel in both themes - a local token
   context like the footer and the final CTA - with the lockup at the top,
   the five links as large left-aligned rows, and the call to action and the
   theme switch at the foot.

   Core's behaviour is kept: its script opens and closes the overlay, traps
   focus and handles Escape. Only the look is ours.

   Specificity: core paints the open overlay white with
   `.wp-block-navigation:not(.has-background) [overlay].is-menu-open` (four
   classes), and its column alignment comes from
   --navigation-layout-justification-align on the same elements, so the
   rules here carry `.co-nav .co-nav__menu` - five classes on the panel
   itself - to outrank it wherever the two stylesheets land in the combined
   file. */

/* Shown only inside the open panel; the header has its own lockup, call to
   action and theme switch. */
.co-nav__drawer-brand,
.co-nav__drawer-foot {
  display: none;
}

.co-nav .co-nav__menu.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open {
  --surface-page: var(--ink-950);
  --surface-raised: var(--ink-900);
  --surface-sunken: var(--ink-900);
  --text-primary: var(--ink-50);
  --text-secondary: var(--ink-300);
  --text-muted: var(--ink-400);
  --text-accent: var(--signal-300);
  --border-subtle: var(--ink-800);
  --border-default: var(--ink-700);
  --border-accent: var(--signal-400);
  --action-primary-bg: var(--signal-400);
  --action-primary-bg-hover: var(--signal-300);
  --action-primary-bg-active: var(--signal-500);
  --action-primary-text: var(--ink-950);
  /* The drawer's Buy Pro is a secondary button on ink: the dark theme's
     values, whatever the page theme (tokens.css section 5). */
  --action-secondary-bg: transparent;
  --action-secondary-bg-hover: var(--ink-800);
  --action-secondary-bg-active: var(--ink-700);
  --action-secondary-border: var(--ink-400);
  --action-secondary-border-hover: var(--ink-300);
  --action-secondary-text: var(--ink-50);

  padding: var(--space-4) var(--space-5) var(--space-6);
  background: var(--surface-page);
  color: var(--text-primary);
}

/* Every wrapper core puts between the overlay and the list is a full-width,
   full-height column, so the foot can sit at the bottom of the screen. */
.co-nav .co-nav__menu .is-menu-open .wp-block-navigation__responsive-close,
.co-nav .co-nav__menu .is-menu-open .wp-block-navigation__responsive-dialog,
.co-nav .co-nav__menu .is-menu-open .wp-block-navigation__responsive-container-content,
.co-nav .co-nav__menu .is-menu-open .wp-block-navigation__container {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  gap: 0;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
}

.co-nav .co-nav__menu .is-menu-open .co-nav__drawer-brand {
  display: flex;
  align-items: center;
  min-height: 48px;
  margin-block-end: var(--space-6);
}

/* The rows. Heading face at a size a thumb can hit, a hairline between
   them, and the chevron every list of destinations on this site carries. */
.co-nav .co-nav__menu .is-menu-open .wp-block-navigation-item {
  display: block;
  border-block-end: var(--border-width) solid var(--border-subtle);
}

.co-nav .co-nav__menu .is-menu-open .wp-block-navigation-item__content {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  min-height: 64px;
  padding: var(--space-3) 0;
  border-radius: 0;
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: var(--weight-semibold);
  letter-spacing: -0.015em;
  line-height: 1.2;
  color: var(--text-primary);
}

.co-nav .co-nav__menu .is-menu-open .wp-block-navigation-item__content::after {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  margin-inline-end: var(--space-1);
  border-inline-end: var(--border-width-thick) solid var(--text-muted);
  border-block-start: var(--border-width-thick) solid var(--text-muted);
  transform: rotate(45deg);
}

.co-nav .co-nav__menu .is-menu-open .wp-block-navigation-item__content:hover,
.co-nav .co-nav__menu .is-menu-open .current-menu-item > .wp-block-navigation-item__content {
  background: none;
  color: var(--text-accent);
}

.co-nav .co-nav__menu .is-menu-open .wp-block-navigation-item__content:hover::after,
.co-nav .co-nav__menu .is-menu-open .current-menu-item > .wp-block-navigation-item__content::after {
  border-color: var(--text-accent);
}

/* Focus inside the panel: the accent on ink. On a row the ring is inset, so
   it reads as the row being selected and not as a box drawn round a word. */
.co-nav .co-nav__menu .is-menu-open a:focus-visible,
.co-nav .co-nav__menu .is-menu-open button:focus-visible {
  outline: var(--border-width-thick) solid var(--border-accent);
  outline-offset: 2px;
}

.co-nav .co-nav__menu .is-menu-open .wp-block-navigation-item__content:focus-visible {
  outline-offset: -2px;
}

/* The stray box the operator saw round "Features". Core moves focus to the
   first link when the panel opens, and theme.json's link element draws an
   outline on plain :focus - so a tap or a click, which never asked for a
   focus ring, got one. Inside the panel the ring is for :focus-visible only
   (the rules above); a keyboard still gets it, a finger does not. */
.co-nav .co-nav__menu .is-menu-open a:focus:not(:focus-visible),
.co-nav .co-nav__menu .is-menu-open button:focus:not(:focus-visible) {
  outline: none;
}

.co-nav .co-nav__menu .is-menu-open .co-nav__drawer-foot {
  display: grid;
  gap: var(--space-5);
  justify-items: start;
  margin-block-start: auto;
  padding-block-start: var(--space-10);
}

.co-nav__drawer-cta {
  width: 100%;
}

/* There is room for the word here, unlike in the header. */
.co-nav__drawer-foot .co-theme-toggle__text {
  display: inline;
}

.co-nav .wp-block-navigation__responsive-container-open,
.co-nav .wp-block-navigation__responsive-container-close {
  color: var(--text-primary);
}

/* A 44px target in the panel's top corner, level with the lockup. */
.co-nav .co-nav__menu .is-menu-open .wp-block-navigation__responsive-container-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  inset-block-start: 2px;
  inset-inline-end: -10px;
  color: var(--text-primary);
}

/* Header buttons (homepage brief, "Header"): Start for Free (primary) and
   Buy Pro (secondary), the compact size of .co-btn, 44px tall for the touch
   target. Start for Free stays in the bar at every width; Buy Pro shows
   from 1024px and otherwise lives in the drawer foot with the account link.

   The brief says 860px. By arithmetic the bar does not fit there: lockup
   178 + six links about 460 + toggle 44 + the two buttons 214 + gaps and
   padding about 70 is about 970px before any nav gap, so the inline menu
   waits for 1024 (the gate 1 reviewer's N1; the local render confirms). */
.co-nav__cta {
  min-height: 44px;
  padding: 10px var(--space-4);
  font-size: var(--text-body-sm);
  white-space: nowrap;
}

.co-nav__cta--pro {
  display: none;
}

@media (min-width: 64em) {
  .co-nav__cta--pro {
    display: inline-flex;
  }
}

/* Between 1024 and 1279 the row is tight: the links already carry 12px of
   padding each side, so the block gap between them is given up (it was
   theme.json's blockGap, 24px, five times over). */
@media (min-width: 64em) and (max-width: 79.9375em) {
  .co-nav .co-nav__menu .wp-block-navigation__container {
    gap: 0;
  }

  /* The local render at 1024 (2026-10-23): with the gap gone the row was
     still about 90px too wide and "How It Works" and "Sign in" broke onto
     two lines. The links keep to one line on 8px side padding, the
     toggle is icon-only as it is below 1024 (the word returns at 1280),
     and the right group's gap drops to 12px; measured 1016px at 1024. */
  .co-nav .wp-block-navigation-item__content {
    padding-inline: var(--space-2);
    white-space: nowrap;
  }

  .co-nav__right {
    gap: var(--space-3);
  }

  .co-nav__right > .co-theme-toggle .co-theme-toggle__text {
    display: none;
  }
}

/* Phones: the bar holds the lockup, the compact Start for Free and the menu
   button. The header's theme toggle yields its room (the drawer foot keeps
   one); three classes to outrank the toggle's own reveal rule. */
@media (max-width: 29.9375em) {
  .co-theme-ready .co-nav__right > .co-theme-toggle {
    display: none;
  }

  .co-nav__cta--free {
    padding-inline: var(--space-3);
  }

  /* The header lockup at 24px (about 152px wide) so lockup, button and menu
     button fit a 360px screen with the nav's own padding: the drawer's
     lockup keeps 28px. */
  .co-nav > .co-logo .co-logo__svg {
    height: 24px;
  }
}

/* 320px: the compact button gives up a little more so nothing leaves the
   viewport; the hamburger is a fixed 44px. */
@media (max-width: 22.5em) {
  .co-nav__cta--free {
    padding-inline: var(--space-2);
    font-size: var(--text-caption);
  }

  .co-nav > .co-logo .co-logo__svg {
    height: 22px;
  }
}

/* The menu button is a 44px target in the bar, and never shrinks. */
.co-nav .wp-block-navigation__responsive-container-open {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  justify-content: center;
}

/* The overlay opens below 1024px, not core's 600px: between the two the
   links and the account link move into the drawer and the hamburger shows.
   Core paints the inline menu with three classes at min-width: 600px; these
   carry four. */
@media (min-width: 37.5em) and (max-width: 63.9375em) {
  .co-nav .co-nav__menu .wp-block-navigation__responsive-container:not(.is-menu-open) {
    display: none;
  }

  .co-nav .co-nav__menu .wp-block-navigation__responsive-container-open:not(.always-shown) {
    display: flex;
  }
}

/* Docs search band under the docs header. */
.co-docs-search {
  padding: var(--space-3) var(--space-4);
  background: var(--surface-alt);
  border-bottom: var(--border-width) solid var(--border-subtle);
}

.co-docs-search__form {
  max-width: 560px;
  margin-inline: auto;
}

.co-docs-search .wp-block-search__input {
  border: var(--border-width) solid var(--field-border);
  border-radius: var(--radius-md);
  background: var(--field-bg);
  color: var(--field-text);
  font-size: var(--text-body-sm);
}

.co-docs-search .wp-block-search__button {
  border-radius: var(--radius-md);
  background: var(--action-primary-bg);
  color: var(--action-primary-text);
  font-weight: var(--weight-semibold);
}

/* --- 11.2 Footer, a local token context ----------------------------------
   The FOURTH dark surface on the site, after .co-evidence (§4),
   .co-testimonials (§7) and .co-final (§10) — and it follows the same rule
   they do: redeclare the semantic tokens for this subtree, then let every
   rule below go on speaking semantically.

   Hardcoding ink-950 here would make the footer disappear into the page in
   dark mode, where the page is already that colour. This is one of the few
   places allowed to name primitives, because it DEFINES a context rather than
   consuming one. */

.co-footer {
  --surface-page: var(--ink-950);
  --text-primary: var(--ink-50);
  --text-secondary: var(--ink-300);
  /* ink-400, not ink-500: ink-500 on ink-950 is about 3.9:1 and the fine
     print failed WCAG AA in Lighthouse; ink-400 is 5.61:1 (tokens.css). */
  --text-muted: var(--ink-400);
  --border-subtle: var(--ink-800);

  padding: var(--space-16) var(--space-4);
  background: var(--surface-page);
  color: var(--text-secondary);
}

@media (min-width: 48em) {
  .co-footer {
    padding: var(--space-20) var(--space-6);
  }
}

/* The brand column is wider than the three link columns. Previously this was
   four serialised flex-basis values (33%/22%/22%/22%) — one inline style per
   column, on every page of the site. */
.co-footer__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-10);
}

@media (min-width: 48em) {
  .co-footer__cols {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 62em) {
  .co-footer__cols {
    grid-template-columns: 1.6fr repeat(4, 1fr);
    gap: var(--space-10);
  }
}

.co-footer__version {
  margin-block-start: var(--space-4);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* The footer's toggle sits on the dark context, so its hairline and hover
   come from the footer's redeclared tokens. Text label always shown here:
   there is room, unlike the header. */
.co-footer__toggle {
  margin-inline-start: auto;
}

.co-footer__toggle .co-theme-toggle__text {
  display: inline;
}

/* Grid children default to min-width:auto and refuse to shrink below their
   content, which produces a horizontal scrollbar. Same rule as every other
   grid in this file. */
.co-footer__col {
  min-width: 0;
}

.co-footer .co-logo__svg {
  height: 26px;
}

.co-footer__blurb {
  margin-block-start: var(--space-4);
  max-width: 32ch;
  font-size: var(--text-body-sm);
  color: var(--text-secondary);
}

.co-footer__heading {
  margin: 0 0 var(--space-4);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

/* Was three serialised typography.fontSize values, one per nav block. */
.co-footer__nav {
  font-size: var(--text-body-sm);
}

.co-footer__nav a {
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease);
}

.co-footer__nav a:hover {
  color: var(--text-primary);
}

/* The "Featured on" row of launch-directory badges (inc/class-featured-on.php,
   operator 2026-10-27): under the link columns, above the rule. The badges
   are the directories' own dark artwork, self-hosted; shown at 44px tall so
   a row of them stays quieter than the columns, and wrapping on phones. */
.co-footer__featured {
  margin-block-start: var(--space-10);
}

.co-footer__featured-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.co-footer__featured-item {
  margin: 0;
}

.co-footer__featured-link {
  display: inline-block;
  border-radius: var(--radius-md);
  line-height: 0;
}

.co-footer__featured-img {
  width: auto;
  height: 44px;
}

.co-footer__rule {
  height: var(--border-width);
  margin-block: var(--space-12);
  border: 0;
  background: var(--border-subtle);
}

.co-footer__base {
  gap: var(--space-4);
}

.co-footer__fine {
  margin: 0;
  font-size: var(--text-caption);
  color: var(--text-muted);
}

/* The bar's end group: the social links (03-page-designs.md 1.14) and the
   theme toggle side by side. One flex child of the bar, so its
   space-between spacing is unchanged (an auto margin on a child is reset by
   the core flex layout). Same pill, hairline and type as the toggle; one
   list item per network, room for more. */
.co-footer__end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

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

.co-footer__social-item {
  margin: 0;
}

.co-footer__social-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 6px var(--space-3);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.1em;
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  transition: border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

.co-footer__social-link:hover {
  border-color: var(--border-default);
  color: var(--text-primary);
}

/* The glyph follows the link's own colour: --text-accent is not redeclared
   in the footer context, and in light mode it is signal-700 on ink-950. */
.co-footer__social-icon {
  width: 0.9375rem;
  height: 0.9375rem;
}

/* --- 11.4 Cookie consent banner (inc/class-consent.php, 2026-10-27) -------
   Operator: small, not a wall. A slim bar along the bottom on phones, a
   compact card at the bottom left from 40em. Fixed, so it never moves the
   page (no layout shift). Decline and Accept share one style and one size:
   equal prominence is what EU consent guidance asks of the first layer.
   Just BELOW the header's layer: the phone drawer opens inside the sticky
   header's stacking context (components.css, .co-siteheader z-index: 50 -
   not the --z-header token), so a banner above it covered the drawer's Buy
   Pro button and theme toggle (testbed render, 2026-10-27). Header and
   banner sit at opposite ends of the screen, so they never meet; the
   drawer, the footnote popover (90) and the Start for Free modal all cover
   the banner. Printed with [hidden]; co-consent.js shows it only while no
   choice is stored. */
.co-consent {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 49;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: var(--border-width) solid var(--border-default);
  background: var(--surface-raised);
  color: var(--text-secondary);
  box-shadow: var(--elevation-overlay);
}

.co-consent[hidden] {
  display: none;
}

.co-consent__text {
  flex: 1 1 16rem;
  margin: 0;
  font-size: var(--text-caption);
  line-height: 1.45;
}

.co-consent__link {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.co-consent__actions {
  display: flex;
  gap: var(--space-2);
}

.co-consent .co-consent__btn {
  min-height: 40px;
  padding: 8px var(--space-4);
  font-size: var(--text-body-sm);
}

@media (min-width: 40em) {
  .co-consent {
    inset: auto auto var(--space-4) var(--space-4);
    max-width: 23rem;
    border: var(--border-width) solid var(--border-default);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
  }

  .co-consent__actions {
    flex: 1 1 100%;
  }

  .co-consent .co-consent__btn {
    flex: 1 1 0;
  }
}

/* --- 11.3 (retired) ------------------------------------------------------
   The shared green .co-cta band and parts/cta.html are gone: every page now
   closes on acf/final-cta, either in its content or via parts/final-cta.html
   on the blog templates. */

/* ==========================================================================
   12. PROSE PAGES AND SHARED CONTENT PRIMITIVES
   --------------------------------------------------------------------------
   The body of every page that is not a block composition - documentation,
   Contact, About, the legal pages, Affiliates, Partners, and single blog
   posts. The page-header block above supplies the H1 and deck; this section
   owns the measure and rhythm of what follows (03-page-designs.md 5.4 for
   the type, 6.4 for the docs additions).

   .co-prose is a constrained group, so theme.json's 680px content size is
   the measure and children are centred by core; only typography, spacing
   and the few content primitives (tables, embeds, forms) live here.
   ========================================================================== */

.co-prose {
  padding-block: var(--space-2) var(--section-y);
}

.co-prose > * + *,
.co-post__content > * + * {
  margin-block-start: var(--space-5);
}

.co-prose h2,
.co-post__content h2 {
  margin-block: var(--space-16) var(--space-4);
  font-size: var(--text-h3);
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.co-prose h3,
.co-post__content h3 {
  margin-block: var(--space-10) var(--space-3);
  font-size: var(--text-h4);
  line-height: 1.35;
}

.co-prose > h2:first-child,
.co-prose > h3:first-child {
  margin-block-start: 0;
}

.co-prose p,
.co-prose li,
.co-post__content p,
.co-post__content li {
  font-size: var(--text-body-lg);
  line-height: 1.65;
  color: var(--text-primary);
  text-wrap: pretty;
}

.co-prose ul,
.co-prose ol,
.co-post__content ul,
.co-post__content ol {
  padding-inline-start: var(--space-6);
}

.co-prose li + li,
.co-post__content li + li {
  margin-block-start: var(--space-2);
}

/* Prose links are always underlined - colour alone fails WCAG 1.4.1. Card
   links (the docs index) are whole-block targets and are excluded. */
.co-prose a:not(.co-btn):not(.co-link):not(.co-docs-index__link):not(.wp-block-button__link),
.co-post__content a:not(.co-btn):not(.co-link) {
  color: var(--text-link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.co-prose a:not(.co-btn):not(.co-link):not(.co-docs-index__link):not(.wp-block-button__link):hover,
.co-post__content a:not(.co-btn):not(.co-link):hover {
  color: var(--text-link-hover);
  text-decoration-thickness: 2px;
}

.co-prose code,
.co-post__content code {
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  font-size: 0.9em;
}

/* Code blocks: a local dark context, like the terminal. */
.co-prose .wp-block-code,
.co-post__content .wp-block-code {
  --text-primary: var(--ink-50);

  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--surface-code);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: var(--text-code);
  line-height: 1.6;
  overflow-x: auto;
}

.co-prose .wp-block-code code,
.co-post__content .wp-block-code code {
  padding: 0;
  background: none;
  font-size: inherit;
}

/* The documentation fragments (docs/site/) use plain <pre><code> and wrap
   their tables in <div class="co-table">; both get the same treatment as
   the block equivalents above. */
.co-prose pre:not(.wp-block-code),
.co-post__content pre:not(.wp-block-code) {
  --text-primary: var(--ink-50);

  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--surface-code);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: var(--text-code);
  line-height: 1.6;
  overflow-x: auto;
}

.co-prose pre code,
.co-post__content pre code {
  padding: 0;
  background: none;
  font-size: inherit;
}

.co-prose div.co-table {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.co-prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-body-sm);
  line-height: 1.45;
}

.co-prose table th,
.co-prose table td {
  padding: var(--space-2) var(--space-3);
  border-block-end: var(--border-width) solid var(--border-subtle);
  text-align: left;
  vertical-align: top;
}

.co-prose table th {
  background: var(--surface-sunken);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.co-prose table td,
.co-prose table th {
  font-size: var(--text-body-sm);
}

.co-prose table code {
  white-space: nowrap;
}

.co-prose blockquote,
.co-post__content blockquote {
  margin: var(--space-8) 0;
  padding-inline-start: var(--space-5);
  border-inline-start: 3px solid var(--border-accent);
  font-size: var(--text-body-lg);
  font-style: italic;
  color: var(--text-secondary);
}

.co-prose img,
.co-post__content img {
  border-radius: var(--radius-lg);
}

.co-prose__note {
  font-size: var(--text-caption);
  line-height: 1.5;
  color: var(--text-muted);
}

.co-prose .co-prose__note {
  font-size: var(--text-caption);
  color: var(--text-muted);
}

/* Two-column prose (Contact): wider than the measure, so the form has room. */
.co-prose > .wp-block-columns {
  max-width: 1000px;
  gap: var(--space-10);
}

.co-prose .wp-block-columns h2:first-child {
  margin-block-start: 0;
}

/* --- 12.1 Forms (Contact Form 7, WPForms) -------------------------------- */

.co-prose .wpcf7-form label,
.co-prose .wpforms-field-label {
  display: block;
  margin-block-end: var(--space-1);
  font-size: var(--text-body-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}

.co-prose .wpcf7-form p,
.co-prose .wpforms-field {
  margin-block: 0 var(--space-4);
}

.co-prose .wpcf7-form-control:not(.wpcf7-submit),
.co-prose .wpforms-field input:not([type="submit"]),
.co-prose .wpforms-field textarea {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 10px var(--space-3);
  border: var(--border-width) solid var(--field-border);
  border-radius: var(--radius-md);
  background: var(--field-bg);
  color: var(--field-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  transition: border-color var(--duration-fast) var(--ease);
}

.co-prose .wpcf7-form-control:not(.wpcf7-submit):hover,
.co-prose .wpforms-field input:hover,
.co-prose .wpforms-field textarea:hover {
  border-color: var(--field-border-hover);
}

.co-prose .wpcf7-form-control:not(.wpcf7-submit):focus,
.co-prose .wpforms-field input:focus,
.co-prose .wpforms-field textarea:focus {
  border-color: var(--field-border-focus);
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

.co-prose textarea.wpcf7-form-control,
.co-prose .wpforms-field textarea {
  min-height: 160px;
  resize: vertical;
}

.co-prose .wpcf7-submit,
.co-prose .wpforms-submit {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 14px var(--space-6);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-md);
  background: var(--action-primary-bg);
  color: var(--action-primary-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease);
}

.co-prose .wpcf7-submit:hover,
.co-prose .wpforms-submit:hover {
  background: var(--action-primary-bg-hover);
}

.co-prose .wpcf7-spinner {
  display: none;
}

.co-prose .wpcf7-response-output {
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-4);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-md);
  font-size: var(--text-body-sm);
}

/* --- 12.2 Data tables ------------------------------------------------------
   The 52-row compatibility matrix on /docs/caching, and any prose table.
   Scrolls inside a focusable group so a keyboard can pan it. */

.co-table-scroller {
  max-width: var(--container);
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.co-table-scroller:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

.co-prose > .co-table-scroller {
  /* Wider than the measure: eight columns will not fit in 68ch. */
  max-width: var(--container);
}

/* The testbed matrix table. (Not `.co-table`: that class is the wrapper div
   the documentation fragments use, styled under .co-prose above.) */
.co-matrix {
  width: 100%;
  min-width: 880px;
  border-collapse: collapse;
  font-size: var(--text-body-sm);
  line-height: 1.45;
}

.co-matrix th,
.co-matrix td {
  padding: var(--space-2) var(--space-3);
  border-block-end: var(--border-width) solid var(--border-subtle);
  text-align: left;
  vertical-align: top;
}

.co-matrix th {
  background: var(--surface-sunken);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}

.co-matrix__center {
  text-align: center;
}

.co-matrix__mono,
.co-matrix__status {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
}

.co-matrix__status--pass {
  color: var(--text-success);
}

.co-matrix__status--partial,
.co-matrix__status--css-only {
  color: var(--text-warning);
}

.co-matrix__status--conflict {
  color: var(--text-error);
}

/* --- 12.3 Embeds and the third-party counter (testbed edge cases) --------- */

.co-embed {
  aspect-ratio: 16 / 9;
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-sunken);
  overflow: hidden;
}

.co-embed--map {
  aspect-ratio: 2 / 1;
}

.co-embed__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.co-counter {
  padding: var(--space-8) var(--space-6);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-sunken);
  text-align: center;
}

.co-counter__figure {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: var(--text-metric);
  font-weight: var(--weight-bold);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--text-accent);
}

.co-counter__label {
  margin-block-start: var(--space-3);
  font-size: var(--text-body);
  color: var(--text-secondary);
}

.co-counter__updated {
  margin-block-start: var(--space-1);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --- 12.4 Documentation index (the /docs/ landing page) -------------------
   The index fragment from docs/site/ groups the pages into sections, each a
   list of link + description. Rendered as a ruled list, not cards. */

.co-prose .co-index__section + .co-index__section {
  margin-block-start: var(--space-10);
}

.co-prose .co-index__list {
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.co-prose .co-index__list > li {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
  font-size: var(--text-body-sm);
  line-height: 1.55;
  color: var(--text-secondary);
}

.co-prose .co-index__list > li + li {
  margin: 0;
  border-block-start: var(--border-width) solid var(--border-subtle);
}

/* Specificity matches the prose underline rule above (four classes), and
   this comes later, so the index titles stay clean until hovered. */
.co-prose .co-index__section .co-index__list > li > a {
  font-family: var(--font-heading);
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.01em;
  text-decoration: none;
}

.co-prose .co-index__section .co-index__list > li > a:hover {
  text-decoration: underline;
}

.co-prose .co-lead {
  font-size: var(--text-body-lg);
  color: var(--text-secondary);
}

