/* ==========================================================================
   Caching Out — Component Styles
   --------------------------------------------------------------------------
   Professional SaaS design system. Load AFTER tokens.css and motion.css,
   and BEFORE assets/css/blocks/*.css.

   WHAT LIVES HERE, AND WHAT DOES NOT
   --------------------------------------------------------------------------
   This file styles CORE WordPress output — `wp-block-*` selectors — plus the
   handful of site-wide chrome rules the block layer does not own. It does NOT
   style the theme's ACF blocks: each of those has its own file in
   assets/css/blocks/, loaded only on pages that render it.

   Three distinct kinds of rule are in here, and they have different futures:

   1. STILL LOAD-BEARING EVERYWHERE — base, focus rings, selection, nav,
      blog/archive/single, docs tables, code blocks, forms, 404, print, dark
      mode. The blog and documentation are core query/post blocks and always
      will be. These stay.

   2. SHARED WITH THE BLOCK LAYER, DELIBERATELY SPLIT — `.co-nav` is the one
      to know about. This file owns its sticky positioning, translucent
      background, blur, bottom hairline and dark-mode treatment;
      blocks/_chrome.css owns only its padding. They are complementary, not
      duplicated, and BOTH are needed. Deleting section 4 as "superseded"
      removes the sticky header.

   3. (GONE.) The `@legacy` sections that matched the hand-written Gutenberg
      pages were deleted on 2026-09-10, when the last of those pages became
      a block composition. Prose typography for the rebuilt pages lives in
      blocks/_chrome.css section 12, not here.

   Rule: never duplicate into this file a value a blocks/*.css already owns.
   When the two disagree, blocks/ wins on load order and the loser becomes a
   rule that appears to work until someone reorders an enqueue.
   ========================================================================== */

/* ==========================================================================
   1. BASE
   ========================================================================== */

html {
  scroll-behavior: smooth;
}

/* Body background and colour are NOT set here. tokens.css sets them from
   --surface-page / --text-primary, which flip for both the stored theme and
   the OS preference. The primitives that used to be here (--paper, --ink-900)
   loaded after tokens.css and pinned the page white under every dark band -
   visible as a white strip wherever two sections met in dark mode. */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

:focus-visible {
  outline: 2px solid var(--signal-600);
  outline-offset: 2px;
}

::selection {
  background: var(--signal-200);
  color: var(--ink-900);
}

/* ==========================================================================
   2. EYEBROW LABELS
   ========================================================================== */

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--signal-700);
  margin-bottom: 0.75rem;
  display: block;
}

/* ==========================================================================
   3. METRIC NUMBERS
   ========================================================================== */

.metric {
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  line-height: 1;
  margin: 0;
}

.metric-sm {
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0;
}

/* ==========================================================================
   4. NAVIGATION
   --------------------------------------------------------------------------
   SHARED with blocks/_chrome.css, which owns `.co-nav`'s padding and nothing
   else. Everything below — sticky behaviour, the translucent blurred ground,
   the bottom hairline, the logo sizing and the nav links — is owned here and
   is live on every page including the rebuilt ones. Do not "consolidate"
   these into _chrome.css without moving the dark-mode rules in section 20 as
   well; they are a pair.
   ========================================================================== */

/* Sticky lives on the HEADER, not on .co-nav.

   It used to be on .co-nav, and it did not work: a sticky element can only
   travel within its own parent's box, and the nav's parent - the header
   template part - is 120px tall. The nav stuck for 48px and then left the
   viewport with its parent, which on a 13,875px page meant the menu was gone
   for the whole document. Moving it up one level is the entire fix, and it
   needs no JavaScript.

   assets/js/header.js then adds .co-siteheader--hidden while the reader is
   moving DOWN, so a long read is not permanently 72px shorter, and removes it
   the moment they move up. */
.co-siteheader,
header.wp-block-template-part {
  position: sticky;
  top: 0;
  z-index: 50;
  transition: transform 260ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

.co-siteheader--hidden {
  transform: translateY(-100%);
}

/* The top bar (4.1) is printed above the header part, so it scrolls away on
   its own and the pinned header keeps only the menu. */

/* A header that slides is a header that should cast a shadow when it is over
   content rather than at rest against the top of the page. */
.co-siteheader--pinned .co-nav {
  box-shadow: var(--shadow-sm, 0 1px 3px rgb(0 0 0 / 8%));
}

@media (prefers-reduced-motion: reduce) {
  .co-siteheader,
  header.wp-block-template-part {
    transition: none;
  }
}

.co-nav {
  position: relative;
  z-index: 50;
  border-bottom: 1px solid var(--border-subtle);
  min-height: 72px;
  transition: box-shadow 240ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

/* The translucent blurred ground lives on a pseudo-element, NOT on .co-nav
   itself. `backdrop-filter` on an element makes it the containing block for
   every position:fixed descendant, and core's mobile navigation overlay is
   position:fixed - with the filter on .co-nav the "full-screen" drawer was
   confined to the 73px-wide nav box. 94% of whichever page surface is
   current, so it is right in both themes without a [data-theme] override. */
.co-nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb, var(--surface-page) 94%, transparent);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
}

.co-nav .wp-block-site-logo {
  flex-shrink: 0;
}

.co-nav .wp-block-site-logo img {
  height: 32px;
  width: auto;
}

/* Nav links container */
.co-nav__links {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.co-nav__links .wp-block-group {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: wrap;
}

/* Individual nav items */
.co-nav__item {
  margin: 0;
}

.co-nav__item a {
  display: inline-block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-600);
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  text-decoration: none;
  transition: color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              background-color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

.co-nav__item a:hover {
  color: var(--ink-900);
  background: var(--ink-50);
}

/* Mobile */
@media (max-width: 781px) {
  .co-nav__links {
    display: none;
  }
}

/* --- 4.1 Top bar (homepage brief, "Top bar") ------------------------------
   One line on an ink-900 band above the header, printed on wp_body_open by
   inc/class-topbar.php: the free-edition sentence, a Start for Free text
   button, a 44px close. A local token context, like the footer, so it is a
   dark strip in both themes. Dismissed = `co-topbar-off` on <html>, set
   before paint by the snippet in functions.php, so the bar never shifts
   the page on a return visit. */

.co-topbar {
  --surface-page: var(--ink-900);
  --text-primary: var(--paper);
  --text-secondary: var(--ink-300);
  --text-accent: var(--signal-300);
  --border-subtle: var(--ink-800);
  --color-focus: var(--signal-300);

  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  /* The start padding mirrors the close button, so the text is centred on
     the page and not on what is left beside the button. */
  padding: var(--space-1) var(--space-3) var(--space-1) calc(var(--space-3) + 44px);
  background: var(--surface-page);
  color: var(--text-primary);
  font-size: var(--text-caption);
  line-height: 1.4;
}

html.co-topbar-off .co-topbar {
  display: none;
}

.co-topbar__text {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 var(--space-2);
  margin: 0;
  text-align: center;
}

.co-topbar__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  color: var(--text-accent);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  white-space: nowrap;
}

.co-topbar__cta:hover {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.co-topbar__close {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease),
              background-color var(--duration-fast) var(--ease);
}

.co-topbar__close:hover {
  color: var(--text-primary);
  background: var(--border-subtle);
}

.co-topbar__close .co-icon {
  width: 1rem;
  height: 1rem;
}

/* Without JavaScript the button could not dismiss anything; visibility
   keeps its space so the text does not move when the script arrives. */
html:not(.co-theme-ready) .co-topbar__close {
  visibility: hidden;
}

.co-topbar :focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: 2px;
}

@media (max-width: 29.9375em) {
  .co-topbar {
    padding-inline-start: var(--space-3);
  }
}

/* ==========================================================================
   6. BUTTONS
   ========================================================================== */

.wp-block-button__link {
  /* Explicit default face: inside prose the link colour rule would otherwise
     paint the label the same green as the button (seen on /affiliates/,
     2026-09-24). The variants below override both. */
  background: var(--signal-700);
  color: var(--paper);
  font-weight: 600;
  font-size: 0.9375rem;
  padding: 0.75rem 1.5rem;
  border-radius: 8px;
  transition: transform 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              box-shadow 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              background-color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              border-color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  line-height: 1.2;
}

/* Two classes so the label beats the prose link colour (.co-prose a); the
   variant rules below are two classes too and come later, so they still win. */
.wp-block-button .wp-block-button__link {
  color: var(--paper);
}

.wp-block-button__link:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(8, 11, 10, 0.15);
}

.wp-block-button__link:active {
  transform: translateY(0);
  box-shadow: none;
}

/* Primary button (signal-700 bg) */
.wp-block-button__link.has-signal-700-background-color {
  background: var(--signal-700);
  color: var(--paper);
}

.wp-block-button__link.has-signal-700-background-color:hover {
  background: var(--signal-800);
}

/* Signal-400 button (used on dark backgrounds) */
.wp-block-button__link.has-signal-400-background-color {
  background: var(--signal-400);
  color: var(--ink-950);
  font-weight: 700;
}

.wp-block-button__link.has-signal-400-background-color:hover {
  background: var(--signal-300);
}

/* Paper button (on signal-700 CTA band) */
.wp-block-button__link.has-paper-background-color {
  background: var(--paper);
  color: var(--signal-800);
}

.wp-block-button__link.has-paper-background-color:hover {
  background: var(--ink-50);
}

/* Outline / ghost button */
.wp-block-button__link[style*="background-color:transparent"],
.wp-block-button__link.has-background[style*="background-color:transparent"] {
  background: transparent;
  border: 1px solid var(--ink-450);
  color: var(--ink-900);
}

.wp-block-button__link[style*="background-color:transparent"]:hover {
  background: var(--ink-50);
  border-color: var(--ink-600);
}

/* Full-width button */
.wp-block-button__width-100 {
  width: 100%;
}

.wp-block-button__width-100 .wp-block-button__link {
  width: 100%;
}

/* ==========================================================================
   LEGACY SECTIONS REMOVED 2026-09-10
   --------------------------------------------------------------------------
   Sections 5 (cover hero), 7 (bordered feature cards), 8 (dark metrics),
   9 (sand testimonials), 10 (pricing cards), 11 (green CTA band) and 12
   (old footer) matched only the hand-written legacy pages. Every page is a
   block composition now, so they were deleted rather than left to drift.
   ========================================================================== */

/* ==========================================================================
   13. BLOG / ARCHIVE / SEARCH
   ========================================================================== */

/* Post list grid */
.wp-block-post-template {
  display: grid;
  gap: 1.5rem;
  padding: 0;
  list-style: none;
}

.wp-block-post-template > li {
  /* Semantic tokens, not --paper / --ink-100: the primitives kept the cards
     white in dark mode under dark-mode text (axe colour-contrast on the
     blog, 2026-10-24). Light mode resolves to the same colours. */
  border: 1px solid var(--border-subtle);
  border-radius: 12px;
  padding: 1.5rem;
  background: var(--surface-raised);
  transition: border-color 180ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              transform 180ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              box-shadow 180ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
  margin: 0;
}

.wp-block-post-template > li:hover {
  border-color: var(--border-default);
  transform: translateY(-2px);
  box-shadow: 0 4px 20px rgba(8, 11, 10, 0.06);
}

.wp-block-post-template .wp-block-post-title {
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.3;
  margin-bottom: 0.5rem;
}

.wp-block-post-template .wp-block-post-title a {
  color: var(--text-primary);
  text-decoration: none;
  transition: color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

.wp-block-post-template .wp-block-post-title a:hover {
  color: var(--text-link);
}

.wp-block-post-date {
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin-bottom: 0.75rem;
  display: block;
}

.wp-block-post-excerpt__excerpt {
  font-size: 0.9375rem;
  color: var(--text-secondary);
  line-height: 1.65;
}

.wp-block-post-excerpt__more-text {
  margin-top: 0.75rem;
}

.wp-block-post-excerpt__more-link {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-link);
  text-decoration: none;
}

.wp-block-post-excerpt__more-link:hover {
  color: var(--text-link-hover);
  text-decoration: underline;
}

/* Pagination */
.wp-block-query-pagination {
  margin-top: 2rem;
  gap: 0.5rem;
  justify-content: center;
}

.wp-block-query-pagination-numbers .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding: 0 0.5rem;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-600);
  text-decoration: none;
  transition: background-color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

.wp-block-query-pagination-numbers .page-numbers.current {
  background: var(--signal-700);
  color: var(--paper);
}

.wp-block-query-pagination-numbers .page-numbers:hover:not(.current) {
  background: var(--ink-50);
  color: var(--ink-900);
}

/* ==========================================================================
   14. SINGLE POST
   ========================================================================== */

.single .wp-block-post-title {
  font-size: var(--text-h1);
  line-height: 1.1;
  margin-bottom: 1rem;
}

.single .wp-block-post-date {
  margin-bottom: 2rem;
}

.single .wp-block-post-content {
  font-size: 1.0625rem;
  line-height: 1.75;
}

.single .wp-block-post-content h2 {
  margin-top: 2.5rem;
  margin-bottom: 1rem;
}

.single .wp-block-post-content h3 {
  margin-top: 2rem;
  margin-bottom: 0.75rem;
}

.single .wp-block-post-content p {
  margin-bottom: 1.25rem;
}

.single .wp-block-post-content ul,
.single .wp-block-post-content ol {
  margin-bottom: 1.25rem;
  padding-left: 1.5rem;
}

.single .wp-block-post-content li {
  margin-bottom: 0.5rem;
}

.single .wp-block-post-content img {
  border-radius: 8px;
  max-width: 100%;
  height: auto;
}

.single .wp-block-post-content blockquote {
  border-left: 3px solid var(--signal-600);
  padding-left: 1.25rem;
  margin: 2rem 0;
  font-size: 1.125rem;
  color: var(--ink-700);
  font-style: italic;
}

/* --- 14.1 Post header, byline, related (03-page-designs.md 5.1, 5.8) ------
   Semantic tokens; the prose rhythm of the body is .co-post__content in
   blocks/_chrome.css section 12. */

.co-post__header {
  padding-block: var(--space-12) var(--space-6);
  margin-block-end: var(--space-8);
  border-block-end: var(--border-width) solid var(--border-subtle);
}

.co-archive__category,
.co-post__category {
  margin-block-end: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.co-archive__category a,
.co-post__category a {
  color: var(--text-accent);
  text-decoration: none;
}

.co-post__title {
  margin: 0 0 var(--space-5);
  font-size: var(--text-h1);
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.co-post__byline {
  gap: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.02em;
  color: var(--text-muted);
}

.co-post__byline .wp-block-post-date,
.co-post__byline .wp-block-post-author-name {
  margin: 0;
  font-size: inherit;
  color: inherit;
}

.co-post__related {
  margin-block-start: var(--section-y);
  padding-block-start: var(--space-8);
  border-block-start: var(--border-width) solid var(--border-subtle);
}

.co-post__related-heading {
  margin: 0 0 var(--space-6);
  font-size: var(--text-h3);
}

.co-archive__list--related .wp-block-post-template .wp-block-post-title {
  font-size: 1.125rem;
}

/* --- 13.1 Archive header (home.html, archive.html, search.html) ----------- */

.co-archive__header {
  padding-block: var(--space-12) var(--space-8);
}

.co-archive__header .wp-block-query-title {
  margin: 0 0 var(--space-4);
  font-size: var(--text-h1);
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

/* No max-width: inside a constrained layout core centres any narrower
   child with !important auto margins, which put the deck 12px right of the
   heading. The 680px content size already caps the measure. */
.co-archive__deck {
  margin: 0;
  font-size: var(--text-body-lg);
  line-height: 1.6;
  color: var(--text-secondary);
}

.co-archive__search {
  max-width: 480px;
  margin-block-start: var(--space-4);
}

.co-archive__list {
  margin-block-end: var(--section-y);
}

.co-archive__list .wp-block-post-date {
  margin: var(--space-3) 0 0;
}

/* --- 13.2 Featured photographs (2026-09-17) -------------------------------
   One generated editorial photograph per post (02-design-direction.md,
   "Photography", amendment). The 16:9 ratio, radius and hairline live HERE:
   the block's own aspectRatio attribute would print an inline style, which
   this theme does not ship. Cards crop to the ratio; the single-post figure
   sits wide under the header. */
.co-archive__image {
  margin: 0 0 var(--space-4);
}

.co-archive__image img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-lg);
}

.co-post__figure {
  margin: var(--space-8) auto var(--space-10);
}

.co-post__figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-xl);
}

/* ==========================================================================
   15. PAGE TEMPLATES
   ========================================================================== */

/* Default page */
.page .wp-block-post-title {
  font-size: var(--text-h1);
  line-height: 1.1;
  margin-bottom: 2rem;
}

.page .wp-block-post-content {
  font-size: 1.0625rem;
  line-height: 1.7;
}

/* ==========================================================================
   16. DOCUMENTATION
   ========================================================================== */

/* Docs search bar */
.wp-block-group.has-ink-50-background-color .wp-block-search {
  max-width: 560px;
  margin: 0 auto;
}

.wp-block-group.has-ink-50-background-color .wp-block-search__input {
  border: 1px solid var(--ink-200);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  font-size: 0.9375rem;
  background: var(--paper);
  transition: border-color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1)),
              box-shadow 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

.wp-block-group.has-ink-50-background-color .wp-block-search__input:focus {
  border-color: var(--signal-600);
  box-shadow: 0 0 0 3px rgba(5, 127, 88, 0.12);
  outline: none;
}

/* Tables */
.wp-block-table {
  overflow-x: auto;
  margin: 1.5rem 0;
}

.wp-block-table table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.875rem;
}

.wp-block-table th {
  background: var(--ink-50);
  font-weight: 600;
  text-align: left;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--ink-100);
  white-space: nowrap;
}

.wp-block-table td {
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--ink-100);
}

.wp-block-table tr:nth-child(even) td {
  background: rgba(242, 245, 244, 0.5);
}

/* Code blocks */
.wp-block-code {
  background: var(--ink-950);
  color: var(--ink-300);
  border-radius: 10px;
  padding: 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.6;
  overflow-x: auto;
  margin: 1.5rem 0;
}

/* ==========================================================================
   17. FORMS
   ========================================================================== */

.wp-block-search__input {
  border: 1px solid var(--ink-200);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
  font-size: 0.875rem;
  transition: border-color 120ms var(--mo-ease, cubic-bezier(0.2, 0, 0, 1));
}

.wp-block-search__input:focus {
  border-color: var(--signal-600);
  outline: none;
}

.wp-block-search__button {
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
}

/* ==========================================================================
   18. 404 PAGE
   ========================================================================== */

.error404 main {
  text-align: center;
  padding: 6rem 1rem;
}

/* ==========================================================================
   19. RESPONSIVE
   ========================================================================== */

@media (max-width: 781px) {
  .wp-block-columns {
    flex-wrap: wrap !important;
  }

  .wp-block-column {
    flex-basis: 100% !important;
    margin-bottom: 1.5rem;
  }

  .wp-block-post-template {
    grid-template-columns: 1fr;
  }

  .wp-block-cover .wp-block-heading {
    font-size: clamp(1.75rem, 5vw, 2.5rem) !important;
  }
}

@media (min-width: 782px) and (max-width: 1023px) {
  .wp-block-post-template {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .wp-block-post-template {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1280px) {
  .wp-block-post-template {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ==========================================================================
   20. DARK MODE
   ========================================================================== */

/* body and .co-nav need no dark rule any more: both read semantic tokens
   (tokens.css section 7, components.css section 4, _chrome.css section 11). */

[data-theme="dark"] .wp-block-post-template > li {
  background: var(--ink-900);
  border-color: var(--ink-800);
}

[data-theme="dark"] .wp-block-post-template > li:hover {
  border-color: var(--ink-700);
}

[data-theme="dark"] .wp-block-post-template .wp-block-post-title a {
  color: var(--ink-50);
}

[data-theme="dark"] .wp-block-post-template .wp-block-post-title a:hover {
  color: var(--signal-300);
}

[data-theme="dark"] .wp-block-post-date {
  color: var(--ink-400);
}

[data-theme="dark"] .wp-block-post-excerpt__excerpt {
  color: var(--ink-300);
}

[data-theme="dark"] .wp-block-table th {
  background: var(--ink-800);
  border-color: var(--ink-700);
}

[data-theme="dark"] .wp-block-table td {
  border-color: var(--ink-700);
}

[data-theme="dark"] .wp-block-table tr:nth-child(even) td {
  background: rgba(22, 32, 30, 0.5);
}

[data-theme="dark"] .wp-block-search__input {
  background: var(--ink-900);
  border-color: var(--ink-700);
  color: var(--ink-50);
}

[data-theme="dark"] .wp-block-search__input:focus {
  border-color: var(--signal-400);
}

[data-theme="dark"] .wp-block-query-pagination-numbers .page-numbers {
  color: var(--ink-300);
}

[data-theme="dark"] .wp-block-query-pagination-numbers .page-numbers:hover:not(.current) {
  background: var(--ink-800);
  color: var(--ink-50);
}

[data-theme="dark"] .wp-block-group.has-border-color:hover {
  border-color: var(--ink-600) !important;
}

/* ==========================================================================
   21. PRINT
   ========================================================================== */

@media print {
  .co-nav,
  .wp-block-group.has-signal-700-background-color,
  footer {
    display: none;
  }

  body {
    font-size: 12pt;
    line-height: 1.5;
    color: #000;
    background: #fff;
  }

  a {
    color: #000;
    text-decoration: underline;
  }
}
/* ==========================================================================
   22. START FOR FREE MODAL (homepage brief, "Start for Free modal")
   --------------------------------------------------------------------------
   One native <dialog id="start-free"> per page, printed by
   inc/class-start-free-modal.php on wp_footer and driven by
   assets/js/co-modal.js. Sitewide, so it lives here and not in a block file.

   Two display paths:
   - With the script: showModal() puts the dialog in the top layer; the
     ::backdrop is the scrim; html.co-modal-open locks the page scroll.
   - Without it: `#start-free:target` shows the dialog as a fixed overlay,
     scrim from a spread box-shadow, close link to `#`. The script adds
     html.co-modal-ready so the fallback never fights showModal().

   Every value is a token. Surfaces are semantic, so the dialog is right in
   both themes without a [data-theme] rule. The mock plugin card and the
   mock upload panel are HTML and CSS, aria-hidden, no images.
   ========================================================================== */

.co-modal {
  width: min(1080px, calc(100% - var(--space-8)));
  max-height: calc(100vh - var(--space-8));
  max-height: calc(100dvh - var(--space-8));
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-2xl);
  background: var(--surface-raised);
  color: var(--text-primary);
  box-shadow: var(--elevation-overlay);
  overflow: auto;
  overscroll-behavior: contain;
}

/* The light theme's raised surface is paper; the dark theme's is ink-800,
   which the brief's "white panel" becomes. */

.co-modal::backdrop {
  background: color-mix(in srgb, var(--ink-950) 60%, transparent);
}

/* Motion: fade and an 8px rise, none under reduced motion. */
.co-modal[open] {
  animation: co-modal-rise var(--duration-base) var(--ease) both;
}

@keyframes co-modal-rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .co-modal[open] {
    animation: none;
  }
}

html.co-modal-open {
  overflow: hidden;
}

/* --- No-JavaScript fallback ---------------------------------------------- */

html:not(.co-modal-ready) .co-modal:target {
  display: block;
  position: fixed;
  inset: var(--space-4);
  z-index: var(--z-modal);
  /* A scrim without a backdrop pseudo-element: the shadow spreads past
     every edge of the viewport. */
  box-shadow: var(--elevation-overlay), 0 0 0 100vmax color-mix(in srgb, var(--ink-950) 60%, transparent);
}

/* Two classes, so this outranks the generic .co-modal__close rules below at
   every width; the link exists only for the no-JavaScript path. */
.co-modal__close.co-modal__close--nojs {
  display: none;
}

html:not(.co-modal-ready) .co-modal__close.co-modal__close--nojs {
  display: flex;
}

html:not(.co-modal-ready) .co-modal__close:not(.co-modal__close--nojs) {
  display: none;
}

/* --- Panel ---------------------------------------------------------------- */

.co-modal__panel {
  position: relative;
  min-height: 100%;
}

.co-modal__close {
  position: absolute;
  inset-block-start: var(--space-4);
  inset-inline-end: var(--space-4);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease),
              background-color var(--duration-fast) var(--ease);
}

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

/* --- Header band: the tint, the title, the laptop ------------------------- */

.co-modal__head {
  display: grid;
  gap: var(--space-6);
  align-items: center;
  padding: var(--space-8) var(--space-6) calc(var(--space-8) + 44px);
  background: var(--surface-accent-subtle);
}

.co-modal__eyebrow {
  margin-block-end: var(--space-3);
}

.co-modal__title {
  margin: 0 0 var(--space-3);
  font-size: var(--text-h2);
  line-height: var(--leading-h2);
  letter-spacing: var(--tracking-h2);
  text-wrap: balance;
}

/* The focus target on open. The ring would draw a box round a heading
   nobody clicked; the dialog's own edge is the visible boundary. */
.co-modal__title:focus {
  outline: none;
}

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

.co-modal__accent {
  color: var(--text-accent);
}

.co-modal__intro {
  margin: 0;
  max-width: var(--measure);
  font-size: var(--text-body-lg);
  line-height: 1.6;
  color: var(--text-secondary);
}

.co-modal__art {
  display: none;
  width: 160px;
  height: auto;
  justify-self: end;
  fill: none;
  stroke: var(--text-accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.co-modal__art-screen {
  stroke: var(--text-primary);
}

.co-modal__art-base {
  stroke: var(--text-primary);
}

.co-modal__art-tray {
  stroke: var(--border-default);
}

/* --- The two options: overlap the band by 44px, side by side from 900px --- */

.co-modal__options {
  display: grid;
  gap: var(--space-5);
  margin-block-start: -44px;
  padding: 0 var(--space-6);
}

.co-modal__option {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-xl);
  background: var(--surface-raised);
  box-shadow: var(--elevation-raised);
}

.co-modal__option--recommended {
  border-color: var(--border-accent);
}

.co-modal__option-label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

.co-modal__option-number {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--text-muted);
}

.co-modal__option-title {
  margin: 0;
  font-size: var(--text-h4);
  line-height: var(--leading-h4);
  letter-spacing: var(--tracking-h4);
}

.co-modal__steps {
  margin: 0;
  padding-inline-start: var(--space-5);
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--text-secondary);
}

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

.co-modal__steps strong,
.co-modal__text strong,
.co-modal__note strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}

.co-modal__text {
  margin: 0;
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--text-secondary);
}

.co-modal__zip {
  align-self: flex-start;
}

.co-modal__link {
  margin-block-start: auto;
}

/* --- Mock plugin card and mock upload panel (decorative) ------------------ */

.co-modal__mock {
  display: none;
  overflow: hidden;
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-sunken);
  font-size: var(--text-caption);
  line-height: 1.45;
  color: var(--text-secondary);
}

.co-modal__mock-card {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface-raised);
}

.co-modal__mock-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--surface-accent-strong);
}

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

.co-modal__mock-name,
.co-modal__mock-heading {
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.co-modal__mock-author {
  color: var(--text-muted);
}

.co-modal__mock-actions {
  display: grid;
  gap: var(--space-2);
  justify-items: end;
  align-content: start;
}

.co-modal__mock-btn {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-sm);
  font-size: var(--text-caption);
  white-space: nowrap;
  color: var(--text-primary);
}

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

.co-modal__mock-btn--ghost {
  background: var(--surface-raised);
}

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

.co-modal__mock-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-block-start: var(--border-width) solid var(--border-subtle);
  color: var(--text-muted);
}

.co-modal__mock-ok {
  color: var(--text-success);
}

.co-modal__mock-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-raised);
  border-block-end: var(--border-width) solid var(--border-subtle);
}

.co-modal__mock-drop {
  display: grid;
  gap: var(--space-3);
  justify-items: center;
  margin: var(--space-4);
  padding: var(--space-5);
  border: var(--border-width) dashed var(--border-interactive);
  text-align: center;
}

.co-modal__mock-file {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.co-modal__mock-filename {
  font-family: var(--font-mono);
  color: var(--text-primary);
}

/* --- Footer: the wizard note and the Pro link ----------------------------- */

.co-modal__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-6);
  margin-block-start: var(--space-6);
  padding: var(--space-5) var(--space-6);
  border-block-start: var(--border-width) solid var(--border-subtle);
  background: var(--surface-sunken);
}

.co-modal__note {
  margin: 0;
  max-width: var(--measure);
  font-size: var(--text-body-sm);
  line-height: 1.6;
  color: var(--text-secondary);
}

.co-modal__pro {
  flex: none;
}

/* --- Breakpoints ---------------------------------------------------------
   Below 600px the dialog fills the screen, no radius, scrolls inside, the
   close button pinned top right. From 600px the mocks and the laptop show.
   From 900px the options sit side by side. */

@media (max-width: 37.4375em) {
  .co-modal {
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    border-radius: 0;
  }

  html:not(.co-modal-ready) .co-modal:target {
    inset: 0;
  }

  /* Pinned top right while the dialog scrolls inside: a sticky block that
     takes no vertical room (its own height is given back by the negative
     end margin) and sits at the end of the line. */
  .co-modal__close {
    position: sticky;
    display: flex;
    inset-block-start: var(--space-3);
    margin: var(--space-3) var(--space-3) -44px auto;
  }

  /* Phone rhythm: 16px gutters, the option cards a step tighter, and the
     download button full width (the brief: paired buttons stack full width
     below 480px). Nothing is wider than the screen. */
  .co-modal__head {
    padding: var(--space-6) var(--space-4) calc(var(--space-8) + 44px);
  }

  .co-modal__options,
  .co-modal__foot {
    padding-inline: var(--space-4);
  }

  .co-modal__option {
    padding: var(--space-5);
  }

  .co-modal__zip {
    align-self: stretch;
    text-align: center;
  }

  .co-modal__pro {
    flex: 1 1 auto;
  }
}

@media (min-width: 37.5em) {
  .co-modal__head {
    grid-template-columns: 1fr auto;
    padding-inline: var(--space-10);
  }

  .co-modal__art {
    display: block;
  }

  .co-modal__mock {
    display: block;
  }

  .co-modal__options {
    padding-inline: var(--space-10);
  }

  .co-modal__foot {
    padding-inline: var(--space-10);
  }
}

@media (min-width: 56.25em) {
  .co-modal__options {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
  }
}
