/* ============================================================
   Mindset Plus — theme-era overrides (APPEND-ONLY)

   tokens.css, base.css and components.css are the frozen design
   source and are READ-ONLY (docs/redesign/DESIGN-SOURCE.md).
   Everything WordPress needs that the static concept never had goes
   here, appended at the bottom under a dated heading. Never reorder
   or rewrite an existing block — that is what makes a re-port of the
   design source a clean copy instead of a merge conflict.

   Loaded last (inc/enqueue.php, MP_STYLES), so plain selectors here
   beat components.css without !important.

   ⚠️ 2026-07-29 · P0c — the original 2026-07-28 P0 block was written
   against concept 05 and was DELETED, not appended to. Every token it
   used (--fg, --maxw, --maxw-prose, --sand-100, --line-200, --space-1,
   --space-3) and its nav selector (.nav-links.open) ceased to exist
   when the design source changed to 02 Neural Tech. Append-only
   resumes from the P0c block below.
   ============================================================ */

/* ---------- 2026-07-29 · P0c · WordPress chrome the concept has no equivalent for ---------- */

/* The design's own header measurement. components.css:30 sets .nav
   min-height:68px and components.css:721 pins the open mobile nav to
   top:68px. Both numbers below are derived from that one value. */
:root {
  --mp-header-h: 68px;
}

/* Admin bar is position:fixed at the top for logged-in users; the sticky
   header (components.css:6) would sit underneath it. WordPress ships the
   32px/46px breakpoint at 783px, so match that exactly rather than the
   design's own 720px nav breakpoint. */
.admin-bar .site-header { top: 46px; }
@media (min-width: 783px) {
  .admin-bar .site-header { top: 32px; }
}

/* Mobile nav drops from directly under the bar. components.css:721 pins it
   at 68px, the .nav min-height, measured from the header box. */
.admin-bar .nav__links.is-open { top: var(--mp-header-h); }

/* In-page anchors (#services, #proof, #contact) must clear the sticky header
   or the target heading lands behind it. Header + one step of air. */
:target { scroll-margin-top: calc(var(--mp-header-h) + var(--space-lg)); }
.admin-bar :target { scroll-margin-top: calc(var(--mp-header-h) + 46px + var(--space-lg)); }
@media (min-width: 783px) {
  .admin-bar :target { scroll-margin-top: calc(var(--mp-header-h) + 32px + var(--space-lg)); }
}

/* WordPress core's screen-reader class. base.css:130 defines .visually-hidden
   with the same intent; core markup (skip links, form labels, comment
   navigation) emits this name instead, so alias it. */
.screen-reader-text {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.screen-reader-text:focus {
  position: absolute; left: 1rem; top: 1rem;
  width: auto; height: auto; clip: auto; margin: 0;
  background: var(--ink-850); color: var(--text-100);
  padding: 0.75rem 1.25rem; border-radius: var(--radius-sm); z-index: 1000;
}

/* Alignment classes for `align-wide` theme support. --container-narrow is the
   default rail; wide steps out to --container, full breaks the gutter. */
.alignwide {
  max-width: var(--container);
  margin-inline: auto;
}
.alignfull {
  max-width: none;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}
.aligncenter { margin-inline: auto; }
.alignleft   { float: left; margin: 0 var(--space-lg) var(--space-lg) 0; }
.alignright  { float: right; margin: 0 0 var(--space-lg) var(--space-lg); }

/* Core caption + gallery, styled to the design's mono caption voice. */
.wp-caption { max-width: 100%; }
.wp-caption-text,
.wp-element-caption {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text-500);
  margin-top: var(--space-xs);
  line-height: 1.4;
}

/* Uploaded custom logo lives where the .brand__mark SVG otherwise sits
   (components.css:44, 34px). */
.brand .custom-logo {
  width: auto;
  height: 34px;
  flex: none;
}

/* === P1 shell === 2026-07-29 · header / footer / shared parts ===============
   Appended by phase P1. Everything after "=== end P1 shell ===" was appended
   by the P5 consolidation pass; append new rules at the very bottom of the
   file, never inside a block. */

/* .mp-svg-defs and its host, template-parts/shared/svg-defs.php, were
   REMOVED 2026-09-01 (FEAT-017) - see footer.php's docblock. The part
   rendered exactly one filter, `#duo-neuraltech`, and nothing in the
   theme applies it any more (components.css's Team section dropped the
   duotone treatment, client call 2026-08-20; verified with a full-theme
   grep before deleting). Not left in place as dead weight. */

/* wp_nav_menu() emits <li class="menu-item …"> inside .nav__links, which
   components.css never sees (the concept's markup is bare <li>). Neutralise the
   list chrome so a real WordPress menu measures like the static one. */
.nav__links li { margin: 0; padding: 0; list-style: none; }

/* === end P1 shell === */


/* === P5 consolidation === 2026-07-29 ==========================
   The four assets/css/parts/*.css files written by teams T-HOME, T-BLOG,
   T-ABOUT and T-MOTION are appended below VERBATIM, in enqueue order, and
   the parts/ directory is deleted. They were split only to let four teams
   write CSS in parallel without a write race on this file; each was
   enqueued from its own template, which scattered four handles across three
   templates and left t-blog.css - the block-editor contract - loading on
   Pages but not on any blog surface.

   Nothing below was reformatted, reordered or rewritten. The only edits are
   to sentences in the part headers that described the now-deleted
   per-template enqueues; each is marked "P5:".

   Append-only resumes AFTER the T-MOTION block at the bottom.
   ================================================================== */


/* ============================================================
   Mindset Plus — T-HOME (front-page.php + template-parts/home/*)

   tokens.css, base.css and components.css are the frozen concept-02
   design source and are READ-ONLY. Everything the home page needs
   that the static concept never had goes here.

   P5: this block is part of overrides.css itself, the last sheet in
   MP_STYLES (inc/enqueue.php), so plain selectors below beat
   components.css without !important. It was previously a separate
   file enqueued from front-page.php.

   2026-09-01 · FEAT-017 reconciliation — this block was written for the
   home page's old trending-grid rail + events-strip posters, replaced by
   the #stories field-timeline (§10, FEAT-011). Two of the original four
   rules had no surviving caller across the nine bundle pages and were
   dropped: `.mp-intent__lede` (the bundle keeps the lede's margin as an
   inline style, same as before FEAT-013) and the whole-card
   `.event-poster` affordance + the "read all articles" spacer
   (`.mp-trending__more`), both specific to the removed events strip. The
   sixth reveal-delay step and the `.trending-card` whole-card-link rules
   stay: template-parts/shared/card-article.php still emits `.trending-card`
   for the blog archive and search results, and the seven-row MINDSET /
   RESPECT lists on About and the RESPECT approach page still stage a
   seventh item at delay steps 6 and 7.
   ============================================================ */

/* ---------- 1 · Reveal-delay steps 6 and 7 ----------

   components.css:706-710 defines [data-reveal-delay="1".."5"] only
   (80/160/240/320/400 ms). The theme originally added a sixth step — a
   copy-paste artifact in the original concept made ="5" do double duty on
   the two trailing rows of a seven-row list, and the theme corrected it by
   adding a real ="6" step (REDESIGN-IMPLEMENTATION-PLAN §5.5). FEAT-017
   adds a seventh: the RESPECT approach page's seven-row stage track and
   the relocated MINDSET register both stage a full seven items on the same
   80ms cadence (FEAT-013 overrides.css §1).

   Writing ="6" or ="7" against the stock sheet emits a DEAD attribute — the
   row silently drops back to 0 ms with no error. This rule is what makes
   both real, so it must ship together with any template that emits them.

   480ms / 560ms continue the 80ms arithmetic series exactly. */
[data-reveal-delay="6"] { transition-delay: 480ms; }
[data-reveal-delay="7"] { transition-delay: 560ms; }

/* ---------- 2 · Whole-card links ----------

   The concept's trending tiles are inert — a static prototype had nowhere
   to send them. On WordPress every card must reach its post.

   One real anchor per card, stretched over the card, rather than a second
   link on the image: two anchors to the same destination would double the
   tab stops and read twice to a screen reader. The anchor keeps the
   heading's own colour so the card looks exactly as designed. */
.trending-card { position: relative; }
.trending-card__link { color: inherit; text-decoration: none; }
.trending-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* A stretched link's own focus ring would draw around the heading text
   only, which reads as if the wrong thing is focused. Move the ring to the
   card. Guarded by @supports so a browser without :has() keeps the
   default base.css:139 outline rather than losing focus visibility entirely. */
@supports selector(:has(*)) {
  .trending-card:has(.trending-card__link:focus-visible) {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
  }
  .trending-card .trending-card__link:focus-visible { outline: none; }
}

/* === T-BLOG === */
/* ============================================================
   Mindset Plus — blog / archive surface (P4, team T-BLOG)

   Scope: index.php · archive.php · single.php · search.php · 404.php
   and everything the block editor can emit inside `.entry-content`.

   RULES OBSERVED
   - tokens.css, base.css and components.css are the frozen design source and
     are READ-ONLY. Nothing here edits them; every value below resolves to a
     token those files already declare. No new colour, no new radius, no new
     easing, no new font.
   - P5: this block was a PART (assets/css/parts/t-blog.css) and is now
     concatenated into overrides.css, which loads last, so plain selectors
     already beat components.css without !important. There is exactly one
     `!important` in this block and it is inside a reduced-motion block,
     mirroring base.css:162.
   - Everything below is EXTRAPOLATED. The design source (concept 02 Neural
     Tech) contains no archive header, no pagination, no search UI, no
     comments, no author box and no form of any kind
     (REDESIGN-IMPLEMENTATION-PLAN §6.2). Where a surface had to be invented,
     it reuses an existing component's geometry rather than inventing a look:
       search field / comment field  -> `.chip` border + `.btn` radius
       pagination                    -> `.chip` pill, jade current state
       author box                    -> `.person` (components.css:557)
       post navigation               -> `.service-card` panel geometry
       comment thread                -> `.mindset__row` left-rail rhythm
   - Selectors are scoped to blog surfaces (`.entry-content`, `.comment-form`,
     `.search-form`, `.blog-*`, `.entry-*`, `.post-nav`, `.comments`) so this
     file cannot repaint Home or About while those are built in parallel.
   ============================================================ */


/* ============================================================
   1 · Card grid — the listing surface

   The card itself is NOT styled here. `.trending-card` and its children are
   components.css:398-431 (read-only), and the WordPress-era additions the
   shared part needs — `position: relative`, the stretched
   `.trending-card__link` and its focus ring — live in the T-HOME block
   above, because template-parts/shared/card-article.php is T-HOME's file.
   Duplicating them here would put two copies of the same rule in this file.

   The one thing the listing surface owns is the track size. The concept's
   grid is `minmax(220px, 1fr)`, tuned for a 5-up teaser strip on Home. A full
   archive of ten posts needs a reading-sized card, so the blog modifier steps
   the track up; nothing else about the card changes.
   ============================================================ */

.trending-grid--blog {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}


/* ============================================================
   2 · Single post — header, media, terms
   ============================================================ */

.entry-header__kicker { margin-bottom: var(--space-md); }
.entry-header__kicker a { color: inherit; }
.entry-header__kicker a:hover { color: var(--jade-300); }

.entry-title { margin-bottom: var(--space-lg); }

.entry-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6em;
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  color: var(--text-500);
}
.entry-meta__sep { color: var(--jade-700); }

/* Lead image. Same frame language as `.real-work__photo`
   (components.css:346-359) minus the scrim — an article's own feature image
   has to stay readable, it is not a background. */
.entry-media {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--ink-850);
}
/* This library's feature images are mostly event POSTERS - 4:5 and taller.
   Left uncapped, one of them fills the whole first screen and pushes the
   article below the fold. Capped and centred rather than cropped, because
   cropping a poster cuts the very text that makes it a poster. Landscape
   photos are unaffected: they hit max-width first. */
.entry-media img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(70vh, 640px);
  margin-inline: auto;
}
.entry-media figcaption {
  padding: var(--space-sm) var(--space-lg);
  border-top: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text-500);
}

.entry-terms {
  margin-top: var(--space-2xl);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--border);
}
.entry-terms__list { list-style: none; margin: 0; padding: 0; }
.entry-terms__list a.chip { color: var(--text-300); }
.entry-terms__list a.chip:hover {
  color: var(--text-100);
  border-color: var(--jade-700);
  background: var(--surface-raised);
}


/* ============================================================
   3 · `.entry-content` — 🔴 AC9, the block-editor contract

   Everything the block editor writes lands here through the_content(). These
   rules key off the classes CORE emits (`wp-block-*`, `wp-element-*`,
   `align*`) and off bare tags, so the same styling covers three authoring
   histories at once: Gutenberg blocks, the classic editor's raw HTML, and the
   12 legacy Elementor posts whose post_content is plain HTML.

   Nothing here inspects or rewrites content. Add a block in the editor, it
   inherits this. That is the acceptance criterion.
   ============================================================ */

.entry-content {
  color: var(--text-300);
  font-size: var(--step-0);
  line-height: 1.75;
}
.entry-content > * { margin-block: 0 var(--space-lg); }
.entry-content > :last-child { margin-bottom: 0; }

/* --- Headings (core/heading + bare tags) --- */
.entry-content h2,
.entry-content h3,
.entry-content h4,
.entry-content h5,
.entry-content h6 {
  color: var(--text-100);
  font-family: var(--font-serif);
  line-height: 1.15;
  letter-spacing: -0.015em;
  font-weight: 500;
  text-wrap: balance;
}
.entry-content > h2 { margin-top: var(--space-2xl); font-size: var(--step-3); }
.entry-content > h3 { margin-top: var(--space-xl); font-size: var(--step-2); }
.entry-content > h4 { margin-top: var(--space-xl); font-size: var(--step-1); }
.entry-content > h5,
.entry-content > h6 {
  margin-top: var(--space-lg);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--jade-400);
}
.entry-content > :first-child { margin-top: 0; }

/* Anchored headings must clear the sticky header (overrides.css:46 does this
   for :target; block anchors are the same problem one layer down). */
.entry-content [id] { scroll-margin-top: calc(var(--mp-header-h) + var(--space-lg)); }

/* --- Text --- */
.entry-content p { max-width: none; }
.entry-content a:not(.wp-block-button__link):not(.wp-element-button) {
  text-decoration: underline;
  text-decoration-color: var(--jade-700);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
.entry-content a:not(.wp-block-button__link):not(.wp-element-button):hover {
  text-decoration-color: var(--jade-300);
}
.entry-content .has-drop-cap:first-letter {
  float: left;
  font-family: var(--font-serif);
  font-size: 3.6em;
  line-height: 0.78;
  margin: 0.08em 0.12em 0 0;
  color: var(--jade-400);
}
.entry-content mark,
.entry-content .has-inline-color {
  background: rgba(95, 201, 172, 0.16);
  color: var(--text-100);
  padding: 0.05em 0.25em;
  border-radius: var(--radius-sm);
}
.entry-content abbr[title] { text-decoration-color: var(--jade-700); }
.entry-content sub,
.entry-content sup { line-height: 0; }

/* --- Lists (core/list) --- */
.entry-content ul,
.entry-content ol { padding-left: 1.4em; }
.entry-content li { margin-bottom: 0.4em; }
.entry-content li::marker { color: var(--jade-400); }
.entry-content ul ul,
.entry-content ol ol,
.entry-content ul ol,
.entry-content ol ul { margin-block: 0.4em; }
.entry-content .wp-block-list { margin-bottom: var(--space-lg); }

/* --- Quote (core/quote) + pullquote --- */
.entry-content blockquote,
.entry-content .wp-block-quote {
  margin-inline: 0;
  padding: var(--space-lg) var(--space-xl);
  border: 1px solid var(--border);
  border-left: 3px solid var(--jade-400);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: linear-gradient(90deg, var(--surface), transparent);
  color: var(--text-100);
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.5;
}
.entry-content blockquote > :last-child { margin-bottom: 0; }
.entry-content blockquote cite,
.entry-content .wp-block-quote cite,
.entry-content .wp-block-pullquote cite {
  display: block;
  margin-top: var(--space-md);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-style: normal;
  letter-spacing: 0.08em;
  color: var(--jade-400);
}
.entry-content .wp-block-quote.is-style-plain {
  border-inline: 0;
  background: none;
  padding-inline: 0;
}
.entry-content .wp-block-pullquote {
  border-block: 1px solid var(--border);
  border-inline: 0;
  border-radius: 0;
  background: none;
  padding-block: var(--space-xl);
  text-align: center;
}
.entry-content .wp-block-pullquote blockquote {
  border: 0;
  background: none;
  padding: 0;
  font-size: var(--step-2);
}

/* --- Images, figures, galleries (core/image, core/gallery, core/media-text) --- */
.entry-content figure { margin-inline: 0; }
.entry-content img,
.entry-content .wp-block-image img {
  height: auto;
  border-radius: var(--radius-md);
}
.entry-content .wp-block-image.is-style-rounded img { border-radius: 50%; }
.entry-content figcaption,
.entry-content .wp-element-caption {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text-500);
  margin-top: var(--space-xs);
  line-height: 1.4;
  text-align: left;
}
.entry-content .wp-block-gallery { gap: var(--space-md); }
.entry-content .wp-block-media-text { gap: var(--space-lg); }
.entry-content .wp-block-cover {
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.entry-content .wp-block-cover .wp-block-cover__inner-container { color: var(--text-100); }

/* Wide alignment inside a `.container--narrow` rail. overrides.css:68 only
   raises max-width, which does nothing when the parent is already narrower —
   the block has to be widened AND re-centred against the viewport. */
.entry-content > .alignwide {
  --mp-wide: min(var(--container), calc(100vw - 2 * clamp(1.15rem, 5vw, 2.5rem)));
  width: var(--mp-wide);
  max-width: none;
  margin-inline: calc(50% - (var(--mp-wide) / 2));
}
.entry-content > .alignfull img { border-radius: 0; }

/* --- Tables (core/table) --- */
.entry-content table,
.entry-content .wp-block-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
}
.entry-content .wp-block-table { overflow-x: auto; }
.entry-content th,
.entry-content td {
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}
.entry-content th {
  color: var(--text-100);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
  background: var(--surface);
}
.entry-content .wp-block-table.is-style-stripes tbody tr:nth-child(odd) {
  background: rgba(22, 38, 31, 0.5);
}
.entry-content .wp-block-table figcaption { text-align: left; }

/* --- Code, preformatted, verse (core/code, core/preformatted, core/verse) --- */
.entry-content code,
.entry-content kbd,
.entry-content samp {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--ink-850);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.15em 0.4em;
  color: var(--jade-300);
}
.entry-content pre,
.entry-content .wp-block-code,
.entry-content .wp-block-preformatted,
.entry-content .wp-block-verse {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  line-height: 1.6;
  background: var(--ink-850);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-300);
}
.entry-content pre code {
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font-size: inherit;
}

/* --- Separator (core/separator) --- */
.entry-content hr,
.entry-content .wp-block-separator {
  border: 0;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--jade-400), transparent);
  opacity: 0.6;
  margin-block: var(--space-2xl);
}
.entry-content .wp-block-separator.is-style-dots {
  background: none;
  opacity: 1;
  color: var(--jade-400);
  text-align: center;
  height: auto;
}

/* --- Buttons (core/buttons) — routed onto the design's own `.btn` --- */
.entry-content .wp-block-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}
.entry-content .wp-block-button__link,
.entry-content .wp-element-button {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.85em 1.5em;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: var(--jade-400);
  color: var(--ink-900);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.entry-content .wp-block-button__link:hover,
.entry-content .wp-element-button:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-glow);
  background: var(--jade-300);
  color: var(--ink-900);
}
.entry-content .wp-block-button.is-style-outline .wp-block-button__link {
  background: transparent;
  color: var(--text-100);
  border-color: var(--border);
}
.entry-content .wp-block-button.is-style-outline .wp-block-button__link:hover {
  background: var(--ink-750);
  border-color: var(--jade-400);
  box-shadow: none;
}

/* --- Embeds, video, audio, file, details --- */
.entry-content .wp-block-embed__wrapper,
.entry-content iframe,
.entry-content video {
  border-radius: var(--radius-md);
  overflow: hidden;
  max-width: 100%;
}
.entry-content .wp-block-file {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.entry-content .wp-block-details {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: var(--space-md) var(--space-lg);
}
.entry-content .wp-block-details summary {
  cursor: pointer;
  color: var(--text-100);
  font-weight: 600;
}

/* --- Group / columns --- */
.entry-content .wp-block-columns { gap: var(--space-lg); }
.entry-content .wp-block-group.has-background {
  padding: var(--space-lg);
  border-radius: var(--radius-md);
}

/* --- Paged posts (<!--nextpage-->) --- */
.page-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-xl);
  font-family: var(--font-mono);
  font-size: var(--step--1);
}
.page-links__label {
  color: var(--text-500);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-right: var(--space-xs);
}
.page-links a,
.page-links > span:not(.page-links__label) {
  display: inline-grid;
  place-items: center;
  min-width: 2.4em;
  padding: 0.4em 0.7em;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-300);
  text-decoration: none;
}
.page-links > span:not(.page-links__label) {
  border-color: var(--jade-700);
  background: var(--jade-900);
  color: var(--text-100);
}


/* ============================================================
   4 · Pagination — the_posts_pagination()
   Core emits `nav.navigation.pagination > .nav-links > a/span.page-numbers`.
   Styled as `.chip` pills (components.css:661) so the archive floor matches
   the values chips on About.
   ============================================================ */

.navigation.pagination { margin-top: var(--space-2xl); }
.navigation.pagination .nav-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-xs);
}
.navigation.pagination .page-numbers {
  display: inline-grid;
  place-items: center;
  min-width: 2.6em;
  padding: 0.55em 1em;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text-300);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.navigation.pagination a.page-numbers:hover {
  border-color: var(--jade-700);
  background: var(--surface-raised);
  color: var(--text-100);
}
.navigation.pagination .page-numbers.current {
  border-color: var(--jade-400);
  background: var(--jade-900);
  color: var(--text-100);
}
.navigation.pagination .page-numbers.dots {
  border-color: transparent;
  background: none;
  color: var(--text-500);
  min-width: 0;
  padding-inline: var(--space-2xs);
}


/* ============================================================
   5 · Post navigation — the_post_navigation()
   Panel geometry lifted from `.service-card` (components.css:282-292), minus
   the cursor-reactive gradient, which main.js only drives on `.service-card`.
   ============================================================ */

.post-nav { margin-top: var(--space-2xl); }
.post-nav .nav-links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-md);
}
.post-nav .nav-previous a,
.post-nav .nav-next a {
  display: grid;
  gap: var(--space-xs);
  height: 100%;
  padding: var(--space-lg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text-100);
  text-decoration: none;
  transition: transform var(--dur-mid) var(--ease-out),
              border-color var(--dur-mid) var(--ease-out),
              background var(--dur-mid) var(--ease-out);
}
.post-nav .nav-previous a:hover,
.post-nav .nav-next a:hover {
  transform: translateY(-4px);
  border-color: var(--jade-700);
  background: var(--surface-raised);
}
.post-nav .nav-next { text-align: right; }
.post-nav__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--jade-400);
}
.post-nav__title {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-100);
}


/* ============================================================
   6 · Author box — reuses `.person` (components.css:557-596)
   No extra markup needed: the avatar already matches the team grid on
   About just by sharing `.person__photo`. (Until FEAT-017, the shared
   class also carried the site-wide `#duo-neuraltech` duotone via footer.php
   - that filter and its host were removed 2026-09-01, see footer.php's
   docblock, so both surfaces now render headshots in their original
   colours instead, still identically to each other.)
   ============================================================ */

.entry-author { margin-top: var(--space-2xl); }
.entry-author h2 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--step-1);
  color: var(--text-100);
  margin-bottom: 0.1em;
}
.entry-author .person__role { margin-bottom: var(--space-md); }
.entry-author__avatar { border-radius: 0; }


/* ============================================================
   7 · Forms — search field, comment field
   The concept ships NO form (§6.2). These controls are built from the
   `.chip` border/background pair and the `.btn` pill so a field reads as a
   sibling of the components that do exist.
   ============================================================ */

.search-bar { margin-bottom: var(--space-2xl); }

.search-form,
.wp-block-search__inside-wrapper {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: stretch;
  max-width: 34rem;
}
.search-form label {
  flex: 1 1 14rem;
  display: block;
  margin: 0;
}

.search-form .search-field,
.wp-block-search__input,
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--text-100);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75em 1em;
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.search-form .search-field::placeholder,
.wp-block-search__input::placeholder,
.comment-form textarea::placeholder { color: var(--text-500); }

.search-form .search-field:hover,
.comment-form input[type="text"]:hover,
.comment-form input[type="email"]:hover,
.comment-form input[type="url"]:hover,
.comment-form textarea:hover { border-color: var(--jade-700); }

.search-form .search-field:focus,
.wp-block-search__input:focus,
.comment-form input[type="text"]:focus,
.comment-form input[type="email"]:focus,
.comment-form input[type="url"]:focus,
.comment-form textarea:focus {
  border-color: var(--jade-400);
  background: var(--surface-raised);
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

.comment-form textarea { min-height: 9rem; resize: vertical; }

.search-form .search-submit,
.wp-block-search__button,
.comment-form .comment-form__submit,
.comment-form input[type="submit"] {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.85em 1.5em;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--jade-400);
  color: var(--ink-900);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.search-form .search-submit:hover,
.wp-block-search__button:hover,
.comment-form .comment-form__submit:hover,
.comment-form input[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-glow);
  background: var(--jade-300);
}


/* ============================================================
   8 · Comments
   Core's default walker markup (`.comment-list`, `.comment-body`,
   `.comment-meta`, `.comment-content`, `.reply`) plus comment_form()'s
   (`.comment-respond`, `.comment-notes`, `.form-submit`).
   ============================================================ */

.comments {
  margin-top: var(--space-3xl);
  padding-top: var(--space-xl);
  border-top: 1px solid var(--border);
}
.comments__title {
  font-size: var(--step-2);
  margin-bottom: var(--space-xl);
}

.comment-list,
.comment-list .children {
  list-style: none;
  margin: 0 0 var(--space-2xl);
  padding: 0;
}
.comment-list .children {
  margin: var(--space-md) 0 0;
  padding-left: var(--space-lg);
  border-left: 1px solid var(--border);
}
.comment-list li { margin-bottom: var(--space-md); }

.comment-body {
  padding: var(--space-lg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.comment-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}
.comment-author {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--text-100);
  font-weight: 600;
}
.comment-author .avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  flex: none;
}
.comment-author .says { display: none; }
.comment-metadata,
.comment-metadata a {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  color: var(--text-500);
  text-decoration: none;
}
.comment-metadata a:hover { color: var(--jade-300); }
.comment-content > :last-child { margin-bottom: 0; }
.comment-awaiting-moderation {
  display: block;
  margin-top: var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--amber-400);
}
.comment .reply { margin-top: var(--space-md); }
.comment-reply-link {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--jade-400);
  text-decoration: none;
}
.comment-reply-link:hover { color: var(--jade-300); }
.bypostauthor > .comment-body { border-color: var(--jade-700); background: var(--surface-raised); }
.pingback .comment-body,
.trackback .comment-body { font-size: var(--step--1); }

.comment-respond {
  padding: var(--space-xl);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--surface-raised), var(--surface));
}
.comment-reply-title { font-size: var(--step-1); margin-bottom: var(--space-md); }
.comment-reply-title small { font-size: var(--step--1); font-family: var(--font-mono); }
.comment-notes,
.comment-form .logged-in-as {
  font-size: var(--step--1);
  color: var(--text-500);
  margin-bottom: var(--space-lg);
}
.comment-form p { margin-bottom: var(--space-lg); }
.comment-form label {
  display: block;
  margin-bottom: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--jade-400);
}
.comment-form .required { color: var(--amber-400); }
.comment-form-cookies-consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
}
.comment-form-cookies-consent label {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-500);
}
.comment-form-cookies-consent input[type="checkbox"] { accent-color: var(--jade-400); margin-top: 0.25em; }
.comment-form .form-submit { margin-bottom: 0; }
.comment-navigation .nav-links { display: flex; gap: var(--space-md); }


/* ============================================================
   9 · Empty states — no results, no posts, 404
   ============================================================ */

.blog-empty {
  max-width: 46rem;
  padding: var(--space-xl);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.blog-empty .lede { margin-bottom: var(--space-lg); }
.blog-empty__chips { list-style: none; margin: var(--space-lg) 0 0; padding: 0; }
.blog-empty__chips a.chip,
.error-topics a.chip { color: var(--text-300); }
.blog-empty__chips a.chip:hover,
.error-topics a.chip:hover {
  color: var(--text-100);
  border-color: var(--jade-700);
  background: var(--surface-raised);
}
.blog-empty__actions { margin: var(--space-lg) 0 0; }

.error-topics { margin-top: var(--space-xl); }
.error-topics .eyebrow { margin-bottom: var(--space-md); }
.error-topics ul { list-style: none; margin: 0; padding: 0; }
.error-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-xl);
}


/* ============================================================
   10 · Responsive + reduced motion
   Breakpoints match the design source's own (components.css:713, :717) so
   the blog surface never reflows at a width nothing else does.
   ============================================================ */

@media (max-width: 720px) {
  .trending-grid--blog { grid-template-columns: 1fr; }
  .post-nav .nav-next { text-align: left; }
  .entry-content > .alignwide { width: auto; margin-inline: 0; }
  .comment-list .children { padding-left: var(--space-md); }
  .comment-respond { padding: var(--space-lg); }
  .entry-content blockquote,
  .entry-content .wp-block-quote { padding-inline: var(--space-lg); }
}

/* base.css:162-185 already neutralises every motion the design source ships.
   These are the only NEW transforms this file adds, so they are neutralised
   here on the same terms. */
@media (prefers-reduced-motion: reduce) {
  .post-nav .nav-previous a:hover,
  .post-nav .nav-next a:hover,
  .search-form .search-submit:hover,
  .wp-block-search__button:hover,
  .comment-form .comment-form__submit:hover,
  .comment-form input[type="submit"]:hover,
  .entry-content .wp-block-button__link:hover,
  .entry-content .wp-element-button:hover { transform: none !important; }
}


/* === T-ABOUT === */
/* ============================================================
   Mindset Plus — About surface (P3, team T-ABOUT) — HISTORICAL

   Scope was template-about.php · template-parts/about/*

   This block held the six inline `style=` declarations lifted verbatim
   off the OLD about.html onto `.mp-about-*` / `.mp-chapter__chips`
   classes (REDESIGN-IMPLEMENTATION-PLAN §5.9).

   2026-09-01 · FEAT-017 reconciliation — every one of those selectors was
   grepped against the nine bundle pages and none survive: the approved
   about.html rewrite renders the page hero as `.preview-about-hero` /
   `.preview-accent` (styled by the new assets/css/preview.css and
   assets/css/legibility.css, both added to MP_STYLES by this run) with no
   inline styles at all, and the chapter-04 chip row it once padded is
   gone from the new page structure. The four rule declarations that used
   to sit below this comment were removed rather than carried forward
   dead. Kept as a historical marker so a future append does not reuse
   the `.mp-about-*` prefix for something unrelated.

   NOT converted, deliberately, back when this block was written: the
   `#duo-neuraltech` <svg> filter wrapper, then still rendered site-wide
   from footer.php via template-parts/shared/svg-defs.php. 2026-09-01
   update: that whole part, its footer.php call, and its `.mp-svg-defs`
   rule have since been REMOVED (FEAT-017) - components.css's Team section
   dropped the duotone treatment it fed (client call 2026-08-20), leaving
   `#duo-neuraltech` with no remaining caller. See footer.php's docblock.
   ============================================================ */


/* === T-MOTION === */
/* ============================================================
   Mindset Plus — T-MOTION (motion / WebGL-hero layer)

   This block is INTENTIONALLY RULE-FREE. That is the finding, not
   an oversight. P5 kept it as the audit trail for why the theme
   ships no motion CSS of its own, and as the marked landing spot
   for any that is added later.

   T-MOTION's brief was to VERIFY the hero's four guards after P0c's
   re-port, not to extend them (REDESIGN-IMPLEMENTATION-PLAN §6.5:
   "Don't improve it."). All four were exercised in a real Chrome
   against the theme running on WordPress and all four fired. The
   design source's own reduced-motion block (base.css:162-185)
   already neutralises every motion the enhancement layer adds, and
   the two sibling part files that ship new transforms neutralise
   their own:

     T-BLOG block above                    its three :hover lifts
     T-HOME block above                    [data-reveal-delay="6"]
     T-ABOUT block above                   ships no motion at all
     overrides.css P0c/P1 blocks           ship no motion at all

   (P5: the four assets/css/parts/*.css paths named here were
   concatenated into this file and deleted. Line numbers in the
   T-BLOG/T-HOME references above are the pre-merge ones.)

   So there was nothing left for this file to declare. Rather than
   invent a rule to justify the file, it ships empty with the audit
   trail attached.

   ------------------------------------------------------------
   WHAT BELONGS HERE LATER

   Any CSS that drives or suppresses motion, and any rule that
   supports a JS-created element. tokens.css / base.css /
   components.css are the frozen concept-02 design source and are
   READ-ONLY, so overrides.css is the only sheet motion CSS may
   land in — append it below this block.

   P5: overrides.css is the last handle in MP_STYLES
   (inc/enqueue.php), so plain selectors here beat components.css
   without !important.

   ------------------------------------------------------------
   NOT FIXED HERE, ON PURPOSE — see the T-MOTION report

   1. [data-magnetic] keeps its inline JS transform (up to 16px)
      if the user turns on "reduce motion" mid-session. main.js:7
      reads the media query once at parse time and never re-reads
      it, so nothing clears the offset until the next pointerleave.
      A `@media (prefers-reduced-motion: reduce) { [data-magnetic]
      { transform: none !important } }` rule would close it, but it
      would also kill the .btn:hover lift under reduced motion —
      a change to frozen design-source behaviour, which is outside
      a verification pass. Escalated, not patched.

   2. If main.js loads but throws at runtime, `js` is already on
      <html> (main.js:12 runs before every IIFE) while the reveal
      observer never does, so [data-reveal] stays at opacity 0 and
      the .js collapse rules never release. CSS cannot detect this;
      the mitigation is a <head>-level guard in inc/enqueue.php,
      which this workstream does not own. See DOM-CONTRACT §13.4.

   P5: resolved. The file was still rule-free, so it was not wired
   as a fifth request — it was folded in here as comment-only.
   ============================================================ */

/* === end P5 consolidation === APPEND NEW RULES BELOW THIS LINE === */


/* ============================================================
   4 · `.entry-content` inline `<svg>` — legacy icon lists

   §3 sizes `img` but never bare `<svg>`, and the 12 legacy Elementor posts
   carry Font Awesome icons inlined as `<svg aria-hidden="true"
   viewBox="0 0 512 512">` with NO width/height attribute, one per list item.

   An SVG with no intrinsic size resolves to 100% of its containing block, and
   the viewBox is square, so each icon rendered 675x675px inside the 700px
   measure. On the worst post that was 11 icons = 7,700px of the body's
   9,690px height. They were not even visible while doing it: with no `fill`
   the path defaults to black, on a near-black surface. That is the "huge
   empty space" - giant black checkmarks, with the real copy pushed a
   screenful apart between them.

   (The same 9,690px height then broke the scroll reveal outright, because
   intersectionRatio is measured against the element. Fixed at source in
   main.js:94-118, not here.)

   Bare-tag selectors only, per §3: nothing inspects or rewrites content, and
   an editor-inserted SVG that carries its own dimensions is left alone.
   ============================================================ */

.entry-content svg:not([width]):not([height]) {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  color: var(--jade-400);
  fill: currentColor;
  flex: none;
}

/* The legacy markup is `<svg></svg><br />label`, which was harmless when the
   icon was its own 675px block and would strand the label on its own line now
   that it is 1em. Presentation only - the <br> stays in the content. */
.entry-content li > svg:first-child + br { display: none; }

/* An icon-led item supplies its own bullet; ::marker would double it. */
.entry-content li:has(> svg:first-child) { list-style: none; }

/* ---------------------------------------------------------------------------
   template-contact.php - contact details list.

   A <dl> rather than a <ul> because these are label/value pairs, and a screen
   reader should announce "Email address" as the term for the address that
   follows. The grid collapses to one column below the card breakpoint so the
   term never ends up orphaned from its value.
   --------------------------------------------------------------------------- */
.mp-contact-list {
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  gap: var(--space-md) var(--space-xl);
  margin-block-start: var(--space-xl);
}

.mp-contact-list dt {
  font-family: var(--font-mono, monospace);
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--jade-400);
}

.mp-contact-list dd { margin: 0; }

@media (max-width: 40rem) {
  .mp-contact-list { grid-template-columns: minmax(0, 1fr); }
  .mp-contact-list dd { margin-block-end: var(--space-md); }
}


/* ---------- 2026-07-29 · article surface polish ---------- */

/* ============================================================
   A · `color-scheme`

   Hygiene, not a bug fix - the black article text this block was first
   written to chase turned out to be Elementor's, see §D. This is still a
   dark design (--bg #0F1B17) that never declared what scheme it is, which
   leaves the UA painting form controls, scrollbars and the comment form's
   spellcheck underline from the light palette.
   ============================================================ */

:root { color-scheme: dark; }


/* ============================================================
   B · Post navigation, continued from §5

   §5 was written correctly and never applied: single.php passed two classes
   to the_post_navigation() and sanitize_html_class() deleted the space, so
   `.post-nav` was never on the element. single.php now passes one class.
   Everything below is what §5 was missing once it started matching.
   ============================================================ */

/* The nav's own heading is the only `.screen-reader-text` this theme shows.
   Line 55 hides the class for every core surface that emits it; the article
   foot is the one place where a visible label earns its space, because the
   two panels are otherwise unheralded blocks between the author box and the
   comment form. Scoped to `.post-nav >` so no other core heading surfaces. */
.post-nav > .screen-reader-text {
  /* WooCommerce ships its own `.screen-reader-text` in wc-blocks.css, which
     inc/enqueue.php cannot outrank because Woo enqueues after the theme and
     writes `position: absolute !important`. An !important declaration is only
     beatable by another one; this is the only one in this block. */
  position: static !important;
  width: auto;
  height: auto;
  margin: 0 0 var(--space-md);
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-500);
}

/* A rule and a full band of air separate the nav from the author box above
   it - §5's margin alone read as "more article", not "end of article". */
.post-nav {
  padding-top: var(--space-xl);
  border-top: 1px solid var(--border-soft);
}

/* Label and title are separate grid rows already (§5). What was missing is
   the arrow's alignment and a title that wraps instead of overflowing its
   panel - several titles in this library run past 90 characters. */
.post-nav__label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.post-nav .nav-next .post-nav__label { justify-content: flex-end; }
.post-nav__arrow { font-family: var(--font-mono); }

.post-nav__title {
  display: block;
  text-wrap: pretty;
  overflow-wrap: anywhere;
  /* §5 mirrors the whole `.nav-next` panel to the right. That reads well on
     the label, which is three words, and badly on the title, which runs to
     five ragged-left lines on this library's longest headlines. The arrow and
     the label keep the direction cue; the title goes back to ragged-right. */
  text-align: left;
}

.post-nav .nav-previous a:hover .post-nav__title,
.post-nav .nav-next a:hover .post-nav__title,
.post-nav .nav-previous a:focus-visible .post-nav__title,
.post-nav .nav-next a:focus-visible .post-nav__title { color: var(--jade-300); }



/* ============================================================
   C · Legacy Elementor articles — palette

   The 12 published articles are Elementor documents, not block-editor posts.
   Elementor renders them from `_elementor_data` and emits a generated sheet
   per post (uploads/elementor/css/post-<id>.css) plus one per kit. Those
   sheets load after MP_STYLES and carry the OLD light site's palette, which
   this theme never replaced:

     --e-global-color-primary   #A4C3A2
     --e-global-color-secondary #000000   <- body copy and the section kickers
     --e-global-color-text      #7A7A7A   <- 4.1:1 on --ink-900, under AA

   Every generated rule reads those variables rather than a literal, e.g.
   `.elementor-5867 .elementor-element-9427675 { color: var(--e-global-color-secondary) }`.
   That is why article text renders black on the dark surface, at every
   viewport - it is not a mobile bug and not a `color-scheme` one.

   Rebinding the three variables on the document root inside `.entry-content`
   fixes every generated rule at once, in one place, with no specificity war
   against per-post selectors whose names change with the post ID. Scoped to
   `.entry-content` so it cannot reach an Elementor-built page elsewhere.

   The kit also defines four CUSTOM globals under hashed names. Counting every
   `colors?id=` in the 12 posts' `_elementor_data` shows which are load-bearing:

     accent    62 uses  #4B9D86  brand green, 5.4:1 - left alone
     secondary 45 uses  #000000  rebound below
     480aa1e8  20 uses  #000     rebound below - pure black, 1.19:1
     56fbba8a   3 uses  #FFF     ~16:1 on --ink-900, left alone
     text        1 use  #7A7A7A  rebound below

   The other two kit customs (#23A455, #4054B2) are referenced by no published
   post, so rebinding them would be inventing a rule for nothing.

   480aa1e8 is why four of the twelve stayed black after the first pass: it is a
   separate variable from `secondary` and carries the same #000. Rebind by the
   hash, not by guessing which posts use it.
   ============================================================ */

.entry-content .elementor {
  --e-global-color-primary: var(--text-100);
  --e-global-color-secondary: var(--text-300);
  --e-global-color-text: var(--text-300);
  --e-global-color-480aa1e8: var(--text-300);
}

/* `secondary` does double duty - body copy AND the per-post heading rule - so
   the rebind above resolves headings to body colour. Put them back. Four
   classes to clear the generated `.elementor-<id> .elementor-element.<id> h*`
   selectors, which specify at three. */
.entry-content .elementor .elementor-widget-heading .elementor-heading-title {
  color: var(--text-100);
}


/* ============================================================
   D · Social follow row — Elementor social-icons widget

   Authored as an Elementor widget, so the rendered row is
   `a.elementor-social-icon.elementor-social-icon-<network>` holding an inline
   brand <svg>, with the label in a visually-hidden `.elementor-screen-only`
   span. Not a block-editor paragraph of links - a previous pass here styled
   the raw `post_content` fallback that only appears when Elementor is not
   rendering, which is why it did nothing useful in production.

   Elementor paints every icon `var(--e-global-color-accent)`, the brand green,
   and the theme's §4 rule paints the glyph --jade-400 on top: a jade mark on a
   jade disc, which is the "bland" the row was reported for. Official brand
   colour goes on the disc, white on the glyph - the standard lockup for all
   three networks, and white-on-brand clears 3:1 as a graphic under WCAG 1.4.11
   for each (#1877F2 4.23:1, #E1306C 4.35:1, #0A66C2 5.68:1).

   Size and shape are Elementor's and stay untouched. An earlier attempt set
   min-height here; the widget sizes its disc from font-size, so that stretched
   a 40px circle into an oval and collapsed the glyph to under a pixel.
   ============================================================ */

/* Five classes plus the element, because the generated rule that paints the
   disc specifies at five:

     .elementor-5867 .elementor-element.elementor-element-31adc6a
     .elementor-repeater-item-ceeddb1.elementor-social-icon

   Two of those - the widget hash and the repeater-item hash - are per post and
   per icon, so they cannot be matched directly. `.elementor-icon` is the stable
   class that buys the sixth component instead. */
.entry-content .elementor a.elementor-icon.elementor-social-icon.elementor-social-icon-facebook {
  background-color: #1877F2;
}
.entry-content .elementor a.elementor-icon.elementor-social-icon.elementor-social-icon-linkedin {
  background-color: #0A66C2;
}
/* Instagram has no flat brand colour; the gradient is the mark. */
.entry-content .elementor a.elementor-icon.elementor-social-icon.elementor-social-icon-instagram {
  background-color: #DD2A7B;
  background-image: linear-gradient(45deg, #F58529 0%, #DD2A7B 45%, #8134AF 70%, #515BD4 100%);
}

.entry-content .elementor a.elementor-social-icon > svg {
  color: #FFFFFF;
  fill: #FFFFFF;
}


/* ============================================================
   9 · Library navigation — FEAT-009

   Two surfaces on single.php, both new:
     .entry-layout / .library-rail   sticky rail beside the article
     .library-index                  the index band after the author box

   Design record: docs/archives/2026-08-18-184459-article-nav-proposals/ARTICLE-NAV-PROPOSALS.md (proposal B + C).

   RULES OBSERVED, same as the rest of this file:
   - tokens.css / base.css / components.css are the frozen design source and
     are READ-ONLY. Every value below resolves to a token they already
     declare. No new colour, no new radius, no new easing, no new font.
   - The spine and its nodes are NOT a new invention. They reuse the About
     page's `.narrative__spine` + `.chapter::before` geometry
     (components.css:504-539), because that is already this theme's language
     for a sequence you are moving through. The lit node marking the current
     article is the `.hero__badge .dot` treatment (components.css:179).
   - Selectors stay scoped to `.entry-layout`, `.entry-column`, `.library-*`
     so this block cannot repaint Home, About or the archive.
   ============================================================ */


/* ---------- 9.1 · The two-column shell ---------- */

/*
 * ⚠️ THE MEASURE IS 780px MINUS THE CONTAINER PADDING, NOT 780px.
 *
 * single.php used to wrap this content in `.container.container--narrow`.
 * That is `max-width: 780px` PLUS `padding-inline: clamp(1.15rem, 5vw, 2.5rem)`
 * under `box-sizing: border-box` (base.css:5, 67-73), so the actual text
 * column was 780 - 2 x padding = **700px** at desktop, not 780px.
 *
 * `.entry-column` now sits INSIDE `.container`, which has already applied that
 * padding. Setting `max-width: var(--container-narrow)` here therefore made
 * the article 80px WIDER than it used to be, while `.entry-header`
 * (single.php:56) stayed on `.container--narrow` at 700px - so the h1 and the
 * first paragraph no longer shared a left edge. Subtracting the padding
 * restores the original measure exactly and keeps header and body aligned.
 */
.entry-column {
  max-width: calc(var(--container-narrow) - 2 * clamp(1.15rem, 5vw, 2.5rem));
  margin-inline: auto;
  min-width: 0;
}

/*
 * 700 (column) + 272 (rail) + 64 (gap) = 1036px, inside `.container`'s 1200px
 * minus its own inline padding. The breakpoint sits at 1160px so the measure
 * is never squeezed to make room for the rail.
 *
 * `:has(> .library-rail)` matters: library-rail.php renders NOTHING when the
 * category holds fewer than two posts. Declaring the second track
 * unconditionally would leave those articles sitting off-centre beside a
 * 272px void. Where :has() is unsupported the block layout stands and the
 * rail simply falls below the article - degraded, never broken.
 */
@media (min-width: 1160px) {
  .entry-layout:has(> .library-rail) {
    display: grid;
    grid-template-columns: minmax(0, calc(var(--container-narrow) - 2 * clamp(1.15rem, 5vw, 2.5rem))) 17rem;
    gap: var(--space-2xl);
    justify-content: center;
    align-items: start;
  }

  /*
   * single.php emits the rail FIRST so keyboard users reach it before the
   * article rather than after the comments. These two rules put it back on
   * the right visually. Explicit placement, not `order` - the tracks are
   * named here so the mapping is readable rather than implied.
   */
  .entry-layout > .library-rail { grid-column: 2; grid-row: 1; }
  .entry-layout > .entry-column { grid-column: 1; grid-row: 1; }

  /*
   * ⚠️ THE HEADER HAS TO FOLLOW THE COLUMN.
   *
   * Once the rail claims a second track, the article column can no longer be
   * centred on the viewport - the grid centres the column+rail PAIR, which
   * pushes the text 168px to the left. `.entry-header` is a separate section
   * still on `.container--narrow`, so it stayed viewport-centred and the
   * kicker, title and byline ended up 168px to the RIGHT of the first
   * paragraph. Measured in a real browser: header content at x=370, body at
   * x=202.
   *
   * Rather than re-deriving that offset with arithmetic that would drift the
   * moment a token changes, the header borrows the SAME grid: identical
   * tracks, identical gap, identical centring. Alignment is then true by
   * construction, not by a magic number.
   */
  body:has(.library-rail) .entry-header > .container {
    max-width: var(--container);
    display: grid;
    grid-template-columns: minmax(0, calc(var(--container-narrow) - 2 * clamp(1.15rem, 5vw, 2.5rem))) 17rem;
    gap: var(--space-2xl);
    justify-content: center;
  }
  /* Without this every element after the first would flow into the rail track. */
  body:has(.library-rail) .entry-header > .container > * { grid-column: 1; }

  /*
   * Wide/full blocks escape the measure with `margin-inline: calc(50% - w/2)`
   * (overrides.css:531-535), where 50% is .entry-content's own box. That math
   * assumed the article was viewport-centred. Inside the grid the column
   * centre sits ~168px left of the viewport centre, so wide blocks would shift
   * left and be clipped by `body { overflow-x: hidden }` (base.css:22).
   * No published post uses these yet - this keeps it that way by choice
   * rather than by luck.
   */
  .entry-layout:has(> .library-rail) .entry-content > .alignwide,
  .entry-layout:has(> .library-rail) .entry-content > .alignfull {
    width: 100%;
    max-width: 100%;
    margin-inline: 0;
  }
}


/* ---------- 9.2 · The rail ---------- */

.library-rail { margin-top: var(--space-2xl); }

@media (min-width: 1160px) {
  .library-rail {
    position: sticky;
    top: calc(var(--mp-header-h) + var(--space-lg));
    margin-top: 0;
    max-height: calc(100vh - var(--mp-header-h) - var(--space-xl));
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--ink-700) transparent;
  }
  .admin-bar .library-rail { top: calc(var(--mp-header-h) + 32px + var(--space-lg)); }
}

/*
 * The disclosure is the small-screen form. It is closed by default so it
 * never pushes the author box off the fold; main.js opens and locks it open
 * once the rail becomes a sidebar, so the summary is not a dead control there.
 */
.library-rail__disclosure > summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--jade-400);
  padding: var(--space-md) 0;
  border-block: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
}
.library-rail__disclosure > summary::-webkit-details-marker { display: none; }
.library-rail__disclosure > summary::after { content: "+"; font-size: 1.1em; color: var(--text-500); }
.library-rail__disclosure[open] > summary::after { content: "\2013"; }
.library-rail__disclosure > summary:hover { color: var(--jade-300); }
.library-rail__disclosure[open] > summary { border-bottom-color: transparent; }
.library-rail__disclosure > summary + * { margin-top: var(--space-lg); }

@media (min-width: 1160px) {
  .library-rail__disclosure > summary { display: none; }
  .library-rail__disclosure > summary + * { margin-top: 0; }
}

/*
 * Segmented control, not underline tabs. A shared bottom border under two
 * mono-caps labels reads as one continuous run of text rather than two
 * choices - a track with a raised thumb makes the selected panel a distinct
 * object. Geometry is `.chip`'s (components.css:661), so it reads as theme
 * furniture rather than a new widget.
 */
.library-rail__tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  max-width: 22rem;
  margin-bottom: var(--space-xl);
  padding: 3px;
  background: var(--ink-900);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}
.library-rail__tab {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  background: transparent;
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  color: var(--text-500);
  padding: 0.62em 0.5em;
  transition: color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.library-rail__tab:hover { color: var(--text-100); }
.library-rail__tab[aria-selected="true"] {
  background: var(--ink-750);
  color: var(--jade-300);
  box-shadow: inset 0 0 0 1px var(--border-soft);
}
/*
 * main.js hides this strip when only one panel survives (a post with fewer
 * than two headings loses the contents tab, and a one-button tablist is not a
 * choice). `display: grid` above is an author rule and would otherwise beat
 * the user-agent `[hidden] { display: none }`, leaving a lone dead button.
 */
.library-rail__tabs[hidden] { display: none; }

/*
 * ⚠️ EXPLICIT FOCUS RING, NOT INHERITED. base.css:139 sets the global ring
 * through `:where(a, button, ...):focus-visible`, and `:where()` carries ZERO
 * specificity by design - so a bundled plugin shipping a plain
 * `button, input { outline: 0 }` (specificity 0,0,1) silently wins and these
 * tabs focus invisibly. Confirmed in a real browser: the button matched
 * :focus-visible while computing `outline-style: none`.
 *
 * The selected tab's inset box-shadow is not a substitute. It marks SELECTION,
 * is present whether or not the control has focus, and selection follows the
 * arrow keys here - so it can never distinguish "focused" from "selected".
 */
.library-rail .library-rail__tab:focus-visible,
.library-rail .library-rail__disclosure > summary:focus-visible,
.library-rail .library-rail__list a:focus-visible,
.library-rail .library-toc a:focus-visible,
.library-index .library-index__link:focus-visible,
.library-index .btn:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.library-rail__head { margin-bottom: var(--space-lg); }
.library-rail__head .eyebrow { margin-bottom: var(--space-xs); }
.library-rail__count {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text-500);
}

.library-rail__list {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--space-lg);
  position: relative;
}
/* The spine. Draws itself in on reveal, as `.narrative__spine` does. */
.library-rail__list::before {
  content: "";
  position: absolute;
  inset-block: 0.55em 0.75em;
  inset-inline-start: 0;
  width: 1px;
  background: linear-gradient(to bottom, var(--jade-700), var(--border), transparent);
  transform-origin: top center;
}
.js .library-rail__list::before {
  transform: scaleY(0);
  transition: transform var(--dur-slow) var(--ease-soft);
}
[data-reveal].is-visible .library-rail__list::before { transform: scaleY(1); }

.library-rail__item { position: relative; margin-bottom: var(--space-md); }
.library-rail__item::before {
  content: "";
  position: absolute;
  inset-inline-start: calc(var(--space-lg) * -1);
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-900);
  border: 1px solid var(--border);
  transform: translateX(-3px);
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.library-rail__item:hover::before { border-color: var(--jade-400); }

.library-rail__item a,
.library-rail__item p {
  display: block;
  margin: 0;
  font-size: var(--step--1);
  line-height: 1.45;
  color: var(--text-300);
  text-decoration: none;
  text-wrap: pretty;
}
.library-rail__item a:hover { color: var(--text-100); }

/* Current article: filled, lit node - "you are here" stated once, visually. */
.library-rail__item--current::before {
  background: var(--jade-400);
  border-color: var(--jade-400);
  box-shadow: 0 0 12px var(--jade-400);
}
.library-rail__item--current p { color: var(--text-100); font-weight: 600; }

.library-rail__date {
  display: block;
  margin-top: 0.15em;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--text-500);
}

.library-rail__foot {
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--border-soft);
}
.library-rail__foot a {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  color: var(--jade-300);
  text-decoration: none;
}
.library-rail__foot a:hover { color: var(--jade-400); }
.library-rail__foot a::after {
  content: "\2192";
  transition: transform var(--dur-fast) var(--ease-out);
}
.library-rail__foot a:hover::after { transform: translateX(3px); }


/* ---------- 9.3 · Contents list + reading progress ---------- */

.library-toc {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--space-lg);
  position: relative;
}
.library-toc::before {
  content: "";
  position: absolute;
  inset-block: 0.4em;
  inset-inline-start: 0;
  width: 1px;
  background: var(--border);
}
/* Progress overlay. Transform-only, so it never triggers layout. */
.library-toc::after {
  content: "";
  position: absolute;
  inset-block-start: 0.4em;
  inset-inline-start: 0;
  width: 1px;
  height: calc(100% - 0.8em);
  background: var(--jade-400);
  transform: scaleY(var(--mp-progress, 0));
  transform-origin: top center;
}
.library-toc li { margin-bottom: var(--space-sm); }
.library-toc li a {
  display: block;
  font-size: var(--step--1);
  line-height: 1.4;
  color: var(--text-500);
  text-decoration: none;
  text-wrap: pretty;
  transition: color var(--dur-fast) var(--ease-out);
}
.library-toc li a:hover { color: var(--text-100); }
.library-toc li a[aria-current="true"] { color: var(--jade-300); }
.library-toc li[data-depth="3"] { padding-left: var(--space-md); }


/* ---------- 9.4 · The index band ---------- */

.library-index {
  border-top: 1px solid var(--border-soft);
  margin-top: var(--space-2xl);
}

.library-index__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-xl);
}
.library-index__head h2 { font-size: var(--step-2); margin: 0; }
.library-index__head .eyebrow { margin-bottom: var(--space-xs); }

.library-index__groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-xl) var(--space-2xl);
}

.library-index__group h3 {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--jade-400);
  margin: 0 0 var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--border);
}

.library-index__list { list-style: none; margin: 0; padding: 0; }
.library-index__list li { border-bottom: 1px solid var(--border-soft); }
.library-index__list li:last-child { border-bottom: 0; }

.library-index__link,
.library-index__list li[aria-current="true"] > span {
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: var(--space-sm);
  align-items: baseline;
  padding: var(--space-sm) 0;
  color: var(--text-300);
  text-decoration: none;
}
.library-index__link {
  transition: color var(--dur-fast) var(--ease-out),
              padding-left var(--dur-fast) var(--ease-out);
}
.library-index__link:hover { color: var(--text-100); padding-left: var(--space-xs); }
.library-index__list li[aria-current="true"] > span { color: var(--text-100); }

/*
 * The ordinal is the article's place in its category run, oldest first - real
 * information about where the piece sits, not decoration.
 */
.library-index__ord {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--text-500);
  font-variant-numeric: tabular-nums;
}
.library-index__link:hover .library-index__ord { color: var(--jade-400); }
.library-index__list li[aria-current="true"] .library-index__ord { color: var(--jade-400); }

.library-index__title { font-size: var(--step--1); line-height: 1.45; text-wrap: pretty; }
.library-index__here {
  display: block;
  margin-top: 0.2em;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber-400);
}


/* ---------- 9.5 · Reduced motion (mirrors base.css:162) ---------- */

@media (prefers-reduced-motion: reduce) {
  .library-rail__list::before,
  .library-toc::after { transform: none !important; }
}

/* ---------- 2026-08-18 · 10 · Home "From field" — Variant C timeline (#stories) — FEAT-011 ---------- */

/*
 * Ported verbatim from the Variant C prototype (design source, read-only),
 * archived 2026-08-18 at
 * docs/archives/2026-08-18-203004-partners-prototype-archive/partners/
 * assets/css/variant-c.css - it used to sit at frontend/prototypes/partners/,
 * which older docs still name. Block
 * "3 · #stories — reverse-chronological timeline with year rails" (~L204-314).
 * Every value below resolves to a token tokens.css already declares — no new
 * colour, radius, spacing step or font was introduced. .field-stories itself
 * carries no rules in the source; the section wrapper only needs .section /
 * .seam / .container, which already exist.
 *
 * This section replaces the home page's former `.trending-grid` rail and
 * `.events-strip` posters (template-parts/home/trending.php + events.php, both
 * deleted with this change). Their rules stay in components.css: that file is
 * a read-only port of the design source (docs/redesign/DESIGN-SOURCE.md) and
 * is never edited to chase a removal, so they are dead now and deliberately
 * left alone. `.trending-card` is NOT dead — the blog archive and search
 * results still render template-parts/shared/card-article.
 */

/* ---------- 10.1 · Timeline shell + year rail ---------- */
.field-timeline { margin-top: 2.2rem; display: flex; flex-direction: column; gap: var(--space-2xl); }

.field-timeline__year-label {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0 0 var(--space-lg);
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 600;
  font-size: var(--step-2);
  color: var(--text-100);
}
.field-timeline__year-label span { color: var(--jade-400); font-style: normal; }

.field-timeline__entries {
  list-style: none;
  margin: 0;
  padding-left: var(--space-lg);
  border-left: 2px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* ---------- 10.2 · Entries + media ---------- */
.field-timeline__entry {
  position: relative;
  display: flex;
  gap: var(--space-lg);
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(17, 38, 33, 0.95), rgba(12, 29, 24, 0.98));
  overflow: hidden;
}
.field-timeline__entry::before {
  content: "";
  position: absolute;
  top: 1.6rem;
  left: calc(-1 * var(--space-lg) - 5px);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--jade-400);
  box-shadow: 0 0 0 3px var(--ink-900);
}

.field-timeline__media { flex: none; width: 12rem; position: relative; overflow: hidden; background: var(--ink-750); }
.field-timeline__media img { width: 100%; height: 100%; object-fit: cover; display: block; }

.field-timeline__entry--no-media .field-timeline__media {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  background: radial-gradient(circle at 30% 20%, rgba(107, 207, 187, 0.14), transparent 60%), var(--ink-850);
  border-right: 1px solid var(--border);
}
.field-timeline__entry--no-media .field-timeline__media span {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--jade-700);
  text-align: center;
  line-height: 1.5;
}

/* ---------- 10.3 · Body copy ---------- */
.field-timeline__body { display: flex; flex-direction: column; justify-content: center; padding: var(--space-md) var(--space-lg) var(--space-md) 0; min-width: 0; }
.field-timeline__meta {
  display: flex;
  gap: 0.55rem;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-500);
}
.field-timeline__tag {
  padding: 0.28rem 0.55rem;
  border: 1px solid rgba(107, 207, 187, 0.26);
  border-radius: var(--radius-pill);
  background: rgba(19, 49, 43, 0.72);
  color: var(--jade-300);
}
.field-timeline__body h4 { margin: 0; font-size: var(--step-1); line-height: 1.18; overflow-wrap: break-word; }
.field-timeline__body h4 a { color: var(--text-100); text-decoration: none; }
.field-timeline__body h4 a:hover { color: var(--jade-300); }
.field-timeline__body p { margin: var(--space-xs) 0 0; font-size: var(--step-0); line-height: 1.55; color: var(--text-300); }

/* ---------- 10.4 · "Read everything" link + responsive ---------- */
.field-timeline__more { margin-top: var(--space-xl); text-align: center; }

@media (prefers-reduced-motion: reduce) {
  .field-timeline__body h4 a { transition: none; }
}

@media (max-width: 860px) {
  .field-timeline__media { width: 8.5rem; }
}

@media (max-width: 640px) {
  .field-timeline__entry { flex-direction: column; }
  .field-timeline__media { width: 100%; aspect-ratio: 16 / 9; border-right: none; border-bottom: 1px solid var(--border); }
  .field-timeline__entry--no-media .field-timeline__media { border-right: none; border-bottom: 1px solid var(--border); }
  .field-timeline__body { padding: 0 var(--space-md) var(--space-md); }
}


/* ============================================================
   2026-09-01 · FEAT-017 · 11 · FEAT-013 overrides

   Folded in from the approved bundle's own overrides.css (frontend/proposals/
   2026-08-18-home-restructure/assets/css/overrides.css §§2-4, 7-9 - its own
   §1 and part of its §5 duplicated the reveal-delay steps already covered by
   §11.1 above and are not re-added here; its §6 (#stories field timeline) is
   already present verbatim at §10 above and is not re-added either).

   components.css is READ-ONLY (DOM-CONTRACT). Everything this round adds
   lives here, loaded last so it wins on equal specificity.

   Contents:
     11.1  Dropdown navigation (header.php's canonical nav, assets/js/nav.js)
     11.2  Read-more affordances (the summary-layer pattern)
     11.3  Section helpers for the restructured home / partners / scope
     11.4  RESPECT — approved treatment (home teaser + respect-approach.html)
     11.5  Footer column titles
     11.6  Paired calls to action
     11.7  Read-more alignment inside a card row
   ============================================================ */

/* ---------- 11.1 · Dropdown navigation ----------
   Markup contract (see assets/js/nav.js for why it is shaped this way):

     <li class="nav__item nav__item--has-children">
       <a href="real-page.html">Label</a>
       <button class="nav__disclosure" aria-expanded="false"
               aria-controls="submenu-id" aria-label="Show Label pages">…</button>
       <ul class="nav__submenu" id="submenu-id"> … </ul>
     </li>

   The link and the disclosure are separate controls on purpose: every
   parent resolves to a real page, and the toggle is a real button. */

.nav__links {
  /* seven items plus disclosures need to wrap gracefully rather than
     push the brand off the row */
  flex-wrap: wrap;
}

.nav__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.15rem;
}

.nav__disclosure {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-500);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.nav__disclosure svg {
  width: 12px;
  height: 12px;
  transition: transform var(--dur-fast) var(--ease-out);
}
.nav__disclosure:hover,
.nav__disclosure:focus-visible { color: var(--text-100); background: var(--surface-2, rgba(255,255,255,0.06)); }
.nav__item.is-open > .nav__disclosure { color: var(--jade-400); }
.nav__item.is-open > .nav__disclosure svg { transform: rotate(180deg); }

.nav__submenu {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Desktop: real dropdown. */
@media (min-width: 961px) {
  .nav__submenu {
    position: absolute;
    top: calc(100% + 0.55rem);
    left: -0.75rem;
    min-width: max(13rem, 100%);
    padding: 0.4rem;
    background: var(--ink-850);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45);
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-out),
                transform var(--dur-fast) var(--ease-out);
  }
  .nav__item.is-open > .nav__submenu {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .nav__submenu a {
    display: block;
    padding: 0.6rem 0.75rem;
    border-radius: 9px;
    white-space: nowrap;
  }
  .nav__submenu a::after { display: none; }
  .nav__submenu a:hover,
  .nav__submenu a:focus-visible { background: rgba(95, 201, 172, 0.12); color: var(--text-100); }

  /* A pointer travelling from the parent to the panel must not cross a
     dead gap, or the pointerleave closes the menu mid-journey. */
  .nav__item--has-children.is-open::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    height: 0.6rem;
  }
}

/* Drawer: the stock drawer starts at 720px, but seven parents plus
   disclosures crowd the row well before that, so the drawer starts
   earlier here. Everything below mirrors components.css:717-736 for the
   wider range and adds the accordion. */
@media (max-width: 960px) {
  .nav__toggle { display: inline-flex; }
  .nav__links {
    /* DRAWER-NOWRAP */
    /* .nav__links wraps globally (§11.1) so seven desktop items fit one row.
       In the drawer that same wrap throws the last items into a second,
       off-canvas column. The drawer scrolls only vertically, so those links
       are unreachable rather than merely off-screen — and documentElement
       reports no horizontal overflow, which is why an automated pass on the
       closed drawer never saw it. */
    flex-wrap: nowrap;
    position: absolute;
    top: 68px; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--ink-850);
    border-bottom: 1px solid var(--border);
    padding: var(--space-sm) clamp(1.15rem, 5vw, 2.5rem) var(--space-lg);
    transform: translateY(-12px);
    opacity: 0;
    pointer-events: none;
    max-height: calc(100vh - 68px);
    overflow-y: auto;
    transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  }
  .nav__links.is-open { opacity: 1; transform: none; pointer-events: auto; }
  .nav__links > li > a { padding: 0.85em 0; border-bottom: 1px solid var(--border-soft); }
  .nav__links a::after { display: none; }

  .nav__item {
    flex-wrap: wrap;
    justify-content: space-between;
    border-bottom: 1px solid var(--border-soft);
  }
  .nav__item > a { flex: 1; border-bottom: 0 !important; }
  .nav__disclosure { width: 2.75rem; height: 2.75rem; }

  /* Accordion: in flow, height-collapsed, no positioning. */
  .nav__submenu {
    flex-basis: 100%;
    display: grid;
    grid-template-rows: minmax(0, 0fr);
    /* grid-template-rows sizes the FIRST row only; the remaining <li>
       children fall into implicit auto rows and stay visible and clickable
       while the disclosure still reports aria-expanded="false". */
    grid-auto-rows: minmax(0, 0fr);
    transition: grid-template-rows var(--dur-mid, 320ms) var(--ease-out);
  }
  .nav__submenu > * { overflow: hidden; }
  .nav__item.is-open > .nav__submenu { grid-template-rows: minmax(0, 1fr); grid-auto-rows: minmax(0, 1fr); }
  .nav__submenu a {
    display: block;
    padding: 0.7em 0 0.7em 1rem;
    color: var(--text-300);
    border-left: 2px solid var(--border-soft);
  }
  .nav__submenu li:last-child a { padding-bottom: 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  .nav__submenu,
  .nav__disclosure svg { transition: none; }
}

/* ---------- 11.2 · Read-more affordances ----------
   Every list-shaped home section is a summary that hands off to a page.
   One consistent affordance makes that legible as a pattern rather than
   eight unrelated links. */

.read-more {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: var(--space-sm);
  font-family: var(--font-mono, inherit);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--jade-400);
  border-bottom: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.read-more svg { width: 14px; height: 14px; flex: none; transition: transform var(--dur-fast) var(--ease-out); }
.read-more:hover, .read-more:focus-visible { color: var(--text-100); border-bottom-color: var(--jade-400); }
.read-more:hover svg { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .read-more svg { transition: none; }
  .read-more:hover svg { transform: none; }
}

/* Card-level read-more sits at the foot of a card, pinned so a row of
   cards with uneven copy still aligns its affordances. */
.card-read-more {
  margin-top: auto;
  padding-top: var(--space-sm);
}

/* Handoffs that used to carry an affordance of their own — the RESPECT
   teaser's button, the partner wall's arrow link, the field timeline's
   ghost button — now run through .read-more, so every hand-off on the
   home page reads as one pattern. Each keeps the spacing its own block
   already set; the partner wall keeps its 44px touch target. */
.respect-teaser__cta .read-more,
.field-timeline__more .read-more { margin-top: 0; }
.partner-wall__see-all { padding: 0.6em 0; }

/* ---------- 11.3 · Section helpers ---------- */

/* Who We Are summary — the client asked for "evidence" and "compassion"
   to carry weight. Presentational only: no words added, no words moved. */
.emphasis-word {
  color: var(--jade-400);
  font-style: italic;
}

/* Partners now carries two blocks that must not read as one list: the
   partner wall is proof, the six segments are an offer. */
.segments-block {
  margin-top: var(--space-2xl, var(--space-xl));
  padding-top: var(--space-xl);
  border-top: 1px solid var(--border-soft);
}

/* The block's heading and lede sat flush against the card grid — the grid
   supplies column gap, not the space above its first row. */
.segments-block__title {
  margin: 0 0 var(--space-sm);
}
.segments-block__lede {
  max-width: 62ch;
  margin: 0 0 var(--space-xl);
  color: var(--text-300);
}
.segments-block__grid {
  margin-top: var(--space-lg);
}
.segments-block__more {
  margin-top: var(--space-xl);
}

/* Placeholder provenance chip — the client's own bracket strings,
   rendered exactly, never expanded into an invented name. */
.provenance-chip {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  border: 1px dashed var(--border);
  border-radius: 999px;
  font-family: var(--font-mono, monospace);
  font-size: var(--step--1);
  color: var(--text-500);
  white-space: pre-wrap;
}

.pending-note {
  color: var(--text-500);
  font-style: italic;
}

/* ---------- 11.4 · RESPECT — approved treatment ----------
   Imported from the bundle's own overrides.css §5, which is the record of
   what Gate 2 approved: treatment C's ordered stage track over treatment
   A's readable four-part row. Lives here rather than in subpages.css
   because the home teaser and respect-approach.html both need it.

   ⚠️ Ported with one fix. The bundle source (a frozen, read-only file -
   never edit it) closes its own explanatory comment early, at "...both
   need it. */" mid-paragraph, then continues the prose as bare, uncommented
   text for the rest of the argument before re-opening a new comment at
   "Shared: the word RESPECT...". A CSS parser does not know that stray text
   is prose - it reads as an invalid selector prelude that swallows the very
   next rule (.accent-respect) into its block, so the browser drops the
   whole thing and every RESPECT accent styles renders as legend text. That is
   a punctuation slip in the source file, not a design decision, so the
   comment below is closed properly rather than copied broken - every
   selector and declaration past this point is otherwise verbatim.

   Argument: RESPECT is a method with a sequence — Read before Engage,
   Strengthen before Place — and Treatment C's numbered stage track,
   threaded by a connecting spine, is what makes that order legible at
   a glance. That track is kept, full width, above the rows.

   Treatment C's own seven-narrow-column row layout is discarded: at
   1440px it forces heavy hyphenation ("as-sessment", "sim-ply") and
   this page's job is to be read. In its place, Treatment A's row —
   full width, four parts (letter · title · blurb · In action:) held
   with a hairline rule and an amber label — carries the seven rows,
   stacked, at a normal reading measure.

   The word RESPECT gets one accent idea, not two: amber, matching
   Treatments A and C. Treatment B's per-letter gradient is not
   borrowed here — layering a second accent technique on top of the
   amber emphasis would fight it rather than support it.

   Only new selectors are defined here. components.css, base.css and
   tokens.css are read-only (DOM-CONTRACT). */

/* ---------- Shared: the word RESPECT, visually emphasised ---------- */
.accent-respect {
  color: var(--amber-400);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--amber-400);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.14em;
}

/* ============================================================
   1 · HOME TEASER (#approaches) — Treatment C's teaser, essentially
   as-is. Zero rows, three client lines, one CTA, 3 reveal steps.
   ============================================================ */
.respect-teaser__body {
  margin-top: var(--space-lg);
}
.respect-teaser__body p {
  margin-inline: auto;
}
.respect-teaser__verbs {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--step-1);
  color: var(--text-100);
  letter-spacing: 0.01em;
  margin-block: var(--space-lg);
}
.respect-teaser__cta {
  margin-top: var(--space-xl);
}

/* ============================================================
   2 · INSIDE PAGE (respect-approach.html)
   ============================================================ */
.respect-approach__head {
  max-width: 68ch;
  margin-bottom: var(--space-2xl);
}
.respect-approach__head #respect-approach-title {
  margin-bottom: var(--space-md);
}
.respect-approach__eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--jade-400);
  margin-bottom: 0.5em;
}
.respect-approach__title {
  display: block;
}
.respect-approach__head .lede {
  max-width: none;
  margin-bottom: var(--space-sm);
}
.respect-approach__opening {
  max-width: 65ch;
  color: var(--text-300);
  margin: 0;
}

/* ---------- 2a · Stage track — the order device (from Treatment C) ----------
   Seven real in-page links on a connecting spine, running full width
   above the rows. At the widths where all seven fit on one line the
   spine draws across their centers; below that the track wraps into a
   compact numbered strip — nodes reflow, never scroll, and the spine
   (which can only mean something when every node shares one line) is
   dropped rather than faked. */
.stage-track {
  margin-bottom: var(--space-2xl);
}
.stage-track__list {
  position: relative;
  list-style: none;
  margin: 0;
  padding: var(--space-sm) 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-lg) var(--space-md);
}
.stage-track__item {
  position: relative;
  z-index: 1;
  flex: none;
}
.stage-track__node {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15em;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--ink-850);
  border: 1px solid var(--jade-700);
  box-shadow: 0 0 0 4px var(--bg);
  text-decoration: none;
  transition: border-color var(--dur-mid) var(--ease-out),
              box-shadow var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out);
}
.stage-track__node:hover,
.stage-track__node:focus-visible {
  border-color: var(--jade-400);
  box-shadow: 0 0 0 4px var(--bg), var(--shadow-glow);
  transform: translateY(-2px);
}
/* Supplementary only — every row is already self-identifying via its own
   visible number, letter and title, so this is never the sole cue. */
.stage-track__node.is-active {
  border-color: var(--amber-400);
}
.stage-track__node.is-active .stage-track__letter {
  color: var(--amber-400);
}
.stage-track__num {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.05em;
  color: var(--text-500);
  line-height: 1;
}
.stage-track__letter {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--step-0);
  color: var(--jade-400);
  line-height: 1;
  transition: color var(--dur-mid) var(--ease-out);
}

/* One-line track: all seven nodes share a row, so the spine can cross
   every node's center and mean something. */
@media (min-width: 780px) {
  .stage-track__list {
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: var(--space-md);
  }
  .stage-track__list::before {
    content: "";
    position: absolute;
    top: calc(var(--space-sm) + 1.5rem);
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(
      90deg,
      transparent,
      var(--jade-700) 4%,
      var(--jade-400) 50%,
      var(--jade-700) 96%,
      transparent
    );
    opacity: 0.6;
    z-index: 0;
  }
}

@media (max-width: 480px) {
  .stage-track__node { width: 2.5rem; height: 2.5rem; }
  .stage-track__letter { font-size: var(--step--1); }
}

/* ---------- 2b · The seven rows — Treatment A's four-part geometry ----------
   .mindset / .mindset__row / .mindset__letter / .mindset__body are the
   read-only DOM-CONTRACT (components.css:458-501). Extended here, not
   overridden, to carry a fourth line (In action:) at full row width. */
.mindset--respect {
  gap: var(--space-lg);
}

/* Base .mindset__row centers a single-line-tall letter against a
   2-line body (components.css:462-471) — wrong once the body grows to
   title + blurb + In-action, so the letter is pinned to the top of the
   row instead, at eye level with the title. */
.mindset__row--respect {
  grid-template-columns: 96px 1fr;
  align-items: start;
  padding: var(--space-lg) var(--space-lg) var(--space-xl);
}
.mindset__row--respect .mindset__letter {
  padding-top: 0.15em;
}

/* Row title: a real <h2> (h1 page title -> h2 per row, no skipped
   levels) restyled back down from components.css's <h4> proportions —
   the semantic level changes, the look does not. */
.mindset__row--respect .mindset__body h2 {
  font-family: var(--font-sans);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: normal;
  color: var(--text-100);
  margin: 0 0 0.4em;
}

/* Blurb: capped to a comfortable reading measure so a full-width row
   at 1440px does not turn into an uncomfortably long line — this is
   what keeps the row "full width" without the text itself running
   wall to wall. No hyphens anywhere in this component. */
.mindset__row--respect .mindset__blurb {
  color: var(--text-300);
  max-width: 68ch;
  overflow-wrap: break-word;
}

/* The fourth line: In action:. Set apart from the blurb with a
   hairline rule, a smaller size and an amber label — the row's actual
   answer to "must not collapse into a wall of text": a clear stop
   between "what we believe" (blurb) and "what we did" (In action)
   instead of one long paragraph. */
.mindset__row--respect .mindset__inaction {
  margin-top: var(--space-md);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border-soft);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--text-500);
  max-width: 62ch;
  overflow-wrap: break-word;
}
.mindset__row--respect .mindset__inaction-label {
  font-family: var(--font-mono);
  font-style: italic;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--amber-400);
  margin-right: 0.35em;
}

/* ============================================================
   Responsive — desktop-first, must not overflow at 375px. The rows
   collapse the same way Treatment A's did (proven pattern); the track
   already reflows via flex-wrap above, no separate breakpoint needed.
   ============================================================ */
@media (max-width: 720px) {
  .mindset__row--respect {
    grid-template-columns: 56px 1fr;
    gap: var(--space-md);
    padding: var(--space-md);
  }
  .respect-teaser__verbs { font-size: var(--step-0); }
  .lab-divider { margin-inline: clamp(1.15rem, 5vw, 2.5rem); }
}
@media (max-width: 420px) {
  .mindset__row--respect {
    grid-template-columns: 1fr;
  }
  .mindset__row--respect .mindset__letter {
    text-align: left;
    font-size: var(--step-2);
    padding-top: 0;
  }
  .lab-divider__label { font-size: 0.65rem; }
}

/* ============================================================
   Reduced motion — full static fallback, explicit for this file's
   own additions. base.css already forces every [data-reveal] to
   opacity:1/transform:none and neutralizes .mindset__letter's hover
   transform/glow globally (base.css:162-183); this block only covers
   what this RESPECT block itself adds — the stage track has no
   draw-in animation of its own, so it is already fully drawn from the
   first frame; this only strips the hover/focus lift and the JS
   is-active color transition down to instant.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .respect-approach__head,
  .stage-track__node,
  .stage-track__letter,
  .mindset__row--respect {
    transition: none !important;
  }
  .stage-track__node:hover,
  .stage-track__node:focus-visible {
    transform: none !important;
  }
}

/* ---------- 11.5 · Footer column titles ----------
   components.css:684 styles `.footer-col h4` — small, mono, uppercase,
   jade. The review pass moved those headings to h2 so the page outline
   stopped skipping a level, which is correct semantically but dropped them
   out of that selector and left them rendering at full h2 display size.
   This restores the intended appearance without touching the outline;
   components.css stays read-only. footer.php emits `<h2 class="footer-col__title">`
   to match. */
.footer-col__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--jade-400);
  margin: 0 0 var(--space-md);
  line-height: 1.3;
}

/* ---------- 11.6 · Paired calls to action ----------
   Where a quiet read-more sits beside a solid button, the two need a real
   gap and a shared centre line. .read-more carries its own margin-top for
   the case where it follows a paragraph; in a pair that margin is what
   knocks the two off each other's baseline, so it is dropped here. */
.schools-actions,
.proof-more,
.segments-block__more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md) var(--space-lg);
  margin-top: var(--space-lg);
}
.schools-actions .read-more,
.proof-more .read-more,
.segments-block__more .read-more {
  margin-top: 0;
}

/* ---------- 11.7 · Read-more alignment inside a card row ----------
   Blurbs differ in length, so a read-more that simply follows the
   paragraph lands at a different height in every card and the row reads
   as ragged. Making the card a column and pushing the link down with
   margin-top:auto pins every affordance in a row to one line. */
.preview-journey__card {
  display: flex;
  flex-direction: column;
}
.preview-journey__card .read-more {
  margin-top: auto;
  padding-top: var(--space-md);
  align-self: flex-start;
}
