@import url("../assets/css/core/fonts.css");
@import url("../assets/css/core/tokens.css");
@import url("../assets/css/core/themes.css");
@import url("../assets/css/core/base.css");
@import url("../assets/css/core/typography.css");

/* Brand token mapping */
:root {
  --site-header-height: 4.75rem;
  --site-radius: 8px;
  --site-radius-sm: 6px;
  --site-measure-wide: 82rem;
  --site-measure: 66rem;
  --site-bg: var(--ec-neutral-100);
  --site-bg-muted: var(--ec-neutral-050);
  --site-surface: var(--ec-neutral-100);
  --site-surface-strong: var(--ec-neutral-100);
  --site-border: var(--ec-neutral-200);
  --site-border-strong: var(--ec-neutral-300);
  --site-heading: var(--ec-navy-900);
  --site-text: var(--ec-neutral-700);
  --site-muted: var(--ec-neutral-500);
  --site-header-bg: var(--ec-neutral-100);
  --site-art-bg: var(--ec-neutral-050);
  --site-art-surface: var(--ec-neutral-100);
  --site-focus-bg: var(--ec-neutral-050);
  --site-inverse-bg: var(--ec-neutral-950);
  --site-inverse-surface: var(--ec-neutral-900);
  --site-inverse-border: var(--ec-neutral-800);

  /* EC mark tokens (consumed by the inline header logo SVG; identical
     model to the brand style guide). The mark file fallbacks already
     hold these exact values, so the logo renders correctly even if a
     custom property is unavailable. */
  --ec-mark-ink:          var(--ec-navy-900);   /* logo letters (e bars, c) */
  --ec-mark-accent:       var(--ec-teal-500);   /* cursor base / e bottom bar */
  --ec-mark-accent-shade: var(--ec-green-700);  /* cursor top */
  --ec-mark-accent-deep:  var(--ec-green-800);  /* cursor wedge / shadow */

  /* Icon palette tokens (consumed by /assets/icons/*.svg via CSS variables
     referenced inside each file with brand fallbacks). One token swap
     replaces the previous "-dark" file pair across the site. */
  --ec-icon-ink:    var(--ec-neutral-700);   /* default icon ink (#323E48) */
  --ec-icon-accent: var(--ec-green-700);     /* primary icon accent (#007167) */
}

/* Theme overrides */
:root[data-color-scheme="dark"] {
  --color-bg: var(--ec-neutral-950);
  --color-heading: var(--ec-neutral-100);
  --color-body: var(--ec-neutral-200);
  --color-link: var(--ec-teal-450);
  --color-link-hover: var(--ec-teal-500);
  --color-link-visited: var(--ec-teal-450);
  --color-surface: var(--ec-neutral-900);
  --color-border: var(--ec-neutral-800);
  --site-bg: var(--ec-neutral-950);
  --site-bg-muted: var(--ec-neutral-900);
  --site-surface: var(--ec-neutral-900);
  --site-surface-strong: var(--ec-neutral-950);
  --site-border: var(--ec-neutral-800);
  --site-border-strong: var(--ec-neutral-500);
  --site-heading: var(--ec-neutral-100);
  --site-text: var(--ec-neutral-200);
  --site-muted: var(--ec-neutral-300);
  --site-header-bg: var(--ec-neutral-950);
  --site-art-bg: var(--ec-neutral-950);
  --site-art-surface: var(--ec-neutral-900);
  --site-focus-bg: var(--ec-neutral-900);

  /* Mark + icon palette flips for dark mode. The accent shades stay
     constant for the logo (per brand spec), only the ink flips white.
     For content icons, both the default ink and the primary accent
     shift to maintain the contrast and warmth the previous "-dark"
     SVG variants used to encode in their files. */
  --ec-mark-ink:    var(--ec-neutral-100);   /* logo ink flips to white */
  --ec-icon-ink:    var(--ec-neutral-200);   /* icon ink flips to bright gray (#E8ECEE) */
  --ec-icon-accent: var(--ec-teal-450);      /* icon accent shifts to teal-450 (#12B4A6) */

  background: var(--site-bg);
  color: var(--site-text);
}

/* Base layout */
html {
  scroll-padding-top: calc(var(--site-header-height) + var(--space-4));
  /* Match the html canvas to the page bg so overscroll, scrollbar gutters,
     and the area behind the UA overlay scrollbar never reveal a different
     shade. This was the cause of a perceived "subtle bg change" in dark
     mode: the UA overlay scrollbar fading in on mouse movement revealed
     the still-white html canvas underneath. */
  background: var(--ec-neutral-100);
  /* Pin scrollbar colors to brand tokens to suppress the UA overlay-scrollbar
     fade-in/out animation that tints the right edge on mouse movement. */
  scrollbar-color: var(--ec-neutral-300) var(--ec-neutral-100);
}

:root[data-color-scheme="dark"] {
  background: var(--ec-neutral-950);
  scrollbar-color: var(--ec-neutral-800) var(--ec-neutral-950);
}

body {
  min-height: 100%;
}

body.nav-open {
  overflow: hidden;
}

body.intro-playing {
  overflow: hidden;
}

main {
  min-height: 60vh;
}

a {
  text-underline-offset: 0.18em;
}

/* Brand intro */
.brand-intro[hidden] {
  display: none;
}

.brand-intro {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-overlay) + 1);
  display: grid;
  place-items: center;
  padding: clamp(var(--space-4), 4vw, var(--space-6));
  background: var(--site-bg);
  pointer-events: none;
  opacity: 0;
}

.brand-intro.is-active {
  animation: intro-shell 17200ms var(--ease-standard) both;
}

.brand-intro.is-reduced {
  opacity: 1;
}

.brand-intro.is-reduced .brand-intro__fill,
.brand-intro.is-reduced .brand-intro__fill use,
.brand-intro.is-reduced .brand-intro__back-glow,
.brand-intro.is-reduced .brand-intro__sweep,
.brand-intro.is-reduced .brand-intro__c-reveal-stroke,
.brand-intro.is-reduced .brand-tagline {
  opacity: 1;
  transform: none;
}

.brand-intro.is-reduced .brand-intro__back-glow,
.brand-intro.is-reduced .brand-intro__sweep {
  opacity: 0;
}

.brand-intro.is-reduced .brand-lockup--intro::after {
  display: none;
}

.brand-intro__panel {
  display: grid;
  place-items: center;
  width: min(100%, 46rem);
}

.brand-lockup {
  display: grid;
  gap: var(--space-3);
  align-items: start;
}

.brand-tagline {
  display: block;
  margin: 0;
  color: var(--site-heading);
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
}

.brand-tagline text {
  fill: currentColor;
  font-family: var(--font-display);
  font-size: 38px;
  font-weight: var(--weight-regular);
}

.brand-lockup--intro {
  --intro-logo-width: min(44rem, 82vw, calc(100vw - (clamp(var(--space-4), 4vw, var(--space-6)) * 2)));
  --intro-logo-height: calc(var(--intro-logo-width) * 0.40569);
  position: relative;
  width: var(--intro-logo-width);
  gap: calc(var(--intro-logo-height) * 0.037);
  justify-items: end;
  text-align: right;
}

.brand-lockup--intro::after {
  content: none;
}

.brand-lockup--intro .brand-tagline {
  width: calc(var(--intro-logo-width) * 0.435);
  height: calc(var(--intro-logo-height) * 0.117);
  opacity: 0;
  overflow: visible;
}

.brand-intro__logo {
  display: block;
  width: var(--intro-logo-width);
  overflow: visible;
  transform-origin: center;
}

.brand-intro__fill {
  opacity: 1;
  transform-box: view-box;
  transform-origin: center;
}

.brand-intro__fill use {
  transform-box: fill-box;
  opacity: 0;
  transform-origin: center;
  transform: translateY(0.1rem) scale(0.992);
}

.brand-intro__fill .brand-intro__cursor-piece,
.brand-intro__fill .brand-intro__prompt {
  opacity: 1;
  transform: none;
}

.brand-intro.is-active .brand-intro__prompt {
  animation:
    intro-prompt-blink 940ms steps(1, end) 0ms 7 both,
    intro-prompt-settle 260ms steps(1, end) 6580ms forwards;
}

.brand-intro.is-active .brand-intro__typed-e--middle {
  animation: intro-logo-wipe 980ms cubic-bezier(0.16, 1, 0.3, 1) 7800ms both;
}

.brand-intro.is-active .brand-intro__typed-e--top {
  animation: intro-logo-wipe 980ms cubic-bezier(0.16, 1, 0.3, 1) 8040ms both;
}

.brand-intro.is-active .brand-intro__typed-c {
  animation: intro-circular-reveal 1560ms cubic-bezier(0.16, 1, 0.3, 1) 8760ms both;
}

.brand-intro.is-active .brand-intro__fill {
  animation: intro-logo-glow 1180ms ease-out 10320ms both;
}

.brand-intro__c-reveal-stroke {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.brand-intro.is-active .brand-intro__c-reveal-stroke {
  animation: intro-c-mask-reveal 1560ms cubic-bezier(0.16, 1, 0.3, 1) 8760ms both;
}

.brand-intro.is-active .brand-intro__tm {
  animation: intro-tm 520ms ease 13040ms both;
}

.brand-intro.is-active .brand-tagline {
  animation: intro-tagline 520ms ease 13620ms both;
}

:root[data-color-scheme="dark"] .brand-intro__typed-e,
:root[data-color-scheme="dark"] .brand-intro__typed-c,
:root[data-color-scheme="dark"] .brand-intro__tm {
  fill: var(--ec-neutral-100);
}

/* Back-glow halo: the typed-E shapes are rectangles, so a white halo on dark
   reads as chunky soft rectangles. Use teal — subtler against near-black and
   brand-aligned. The cursor/prompt pieces stay on their own teal/green fills. */
:root[data-color-scheme="dark"] .brand-intro__back-glow use[href="#intro-e-middle"],
:root[data-color-scheme="dark"] .brand-intro__back-glow use[href="#intro-e-top"],
:root[data-color-scheme="dark"] .brand-intro__back-glow use[href="#intro-c-glyph"] {
  fill: var(--ec-teal-500);
}

/* Soften the overall halo intensity in dark mode (peak 0.9 → 0.5). */
:root[data-color-scheme="dark"] .brand-intro.is-active .brand-intro__back-glow {
  animation-name: intro-back-glow-dark;
}

/* Shine sweep is masked by the logo shapes. In dark mode the typed letters are
   white, so a white shine is invisible. Switch the gradient to charcoal — the
   documented brand neutral that pairs with white surfaces — for a soft
   graphite shimmer across the white logo. */
:root[data-color-scheme="dark"] #intro-logo-shine-gradient stop {
  stop-color: var(--ec-neutral-700);
}
:root[data-color-scheme="dark"] #intro-logo-shine-gradient stop:first-child {
  stop-opacity: 0.55;
}

/* intro-logo-glow drop-shadow is navy; swap to teal+white in dark mode. */
:root[data-color-scheme="dark"] .brand-intro.is-active .brand-intro__fill {
  animation-name: intro-logo-glow-dark;
}

.brand-intro.is-active .brand-intro__logo {
  animation: intro-terminal-position 19000ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.brand-intro__back-glow {
  opacity: 0;
  pointer-events: none;
  filter: blur(16px) saturate(1.06);
  transform-box: view-box;
  transform-origin: center;
}

.brand-intro.is-active .brand-intro__back-glow {
  animation: intro-back-glow 19000ms linear both;
}

.brand-intro__sweep {
  opacity: 0;
  pointer-events: none;
}

.brand-intro__shine-light {
  transform-box: view-box;
  transform-origin: center;
  filter: blur(18px);
  will-change: transform;
}

.brand-intro.is-active .brand-intro__sweep {
  animation: intro-sweep-visibility 19000ms linear both;
}

.brand-intro.is-active .brand-intro__shine-light {
  animation: intro-logo-shine 1540ms linear 11480ms both;
}

.replay-intro {
  min-height: 2.75rem;
  border: 0;
  background: transparent;
  color: var(--ec-neutral-500);
  font: inherit;
  font-family: var(--font-sans-tight);
  font-weight: var(--weight-semibold);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  cursor: pointer;
}

.replay-intro:hover,
.replay-intro:focus-visible {
  color: var(--ec-neutral-900);
}

@keyframes intro-shell {
  /* The intro sequence ends with the tagline landing at ~14.14s (82.2%).
     Hold the finished composition until ~15.48s (90%), then fade the whole
     shell out over the final ~1.72s (10%) so the handoff to the page reads
     as a deliberate dissolve rather than the abrupt cut that the previous
     97→100% (~516ms) curve produced. Total animation length (17200ms) is
     unchanged and stays in lock-step with the JS dismiss timer in
     scripts/main.js (playBrandIntro → setTimeout(..., 17200)). */
  0%, 90% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes intro-terminal-position {
  0%, 34% { transform: translateX(calc(var(--intro-logo-width) * 0.09)); }
  43%, 100% { transform: translateX(0); }
}

@keyframes intro-prompt-blink {
  0%, 46% { opacity: 1; transform: translateY(0); }
  47%, 92% { opacity: 0; transform: translateY(0); }
  93%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes intro-prompt-settle {
  0%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes intro-logo-wipe {
  0% { opacity: 0; clip-path: inset(0 100% 0 0); transform: translateY(0); }
  12% { opacity: 1; }
  100% { opacity: 1; clip-path: inset(0 0 0 0); transform: translateY(0); }
}

@keyframes intro-circular-reveal {
  0% { opacity: 0; transform: translateY(0); }
  10%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes intro-c-mask-reveal {
  0% { stroke-dashoffset: 1; }
  100% { stroke-dashoffset: 0; }
}

@keyframes intro-logo-glow {
  0% { filter: drop-shadow(0 0 0 rgb(0 46 109 / 0)); }
  46% { filter: drop-shadow(0 0 12px rgb(0 46 109 / 0.48)) drop-shadow(0 0 14px rgb(0 196 179 / 0.2)) drop-shadow(0 0 10px rgb(0 0 0 / 0.12)); }
  100% { filter: drop-shadow(0 0 0 rgb(0 46 109 / 0)); }
}

@keyframes intro-logo-glow-dark {
  0% { filter: drop-shadow(0 0 0 rgb(0 196 179 / 0)); }
  46% { filter: drop-shadow(0 0 14px rgb(0 196 179 / 0.55)) drop-shadow(0 0 18px rgb(255 255 255 / 0.22)) drop-shadow(0 0 10px rgb(0 196 179 / 0.18)); }
  100% { filter: drop-shadow(0 0 0 rgb(0 196 179 / 0)); }
}

@keyframes intro-tm {
  0% { opacity: 0; transform: translateY(-6px) scale(0.98); }
  100% { opacity: 1; transform: translateY(0); }
}

@keyframes intro-tagline {
  0% { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

@keyframes intro-sweep-visibility {
  0%, 60.4% { opacity: 0; }
  61.5% { opacity: 1; }
  66.7% { opacity: 1; }
  68.5%, 100% { opacity: 0; }
}

@keyframes intro-back-glow {
  0%, 54.1% { opacity: 0; transform: scale(1); }
  56.6% { opacity: 0.9; transform: scale(1.008); }
  60.2% { opacity: 0.34; transform: scale(1.018); }
  61.2%, 100% { opacity: 0; transform: scale(1.026); }
}

@keyframes intro-back-glow-dark {
  0%, 54.1% { opacity: 0; transform: scale(1); }
  56.6% { opacity: 0.5; transform: scale(1.008); }
  60.2% { opacity: 0.18; transform: scale(1.018); }
  61.2%, 100% { opacity: 0; transform: scale(1.026); }
}

@keyframes intro-logo-shine {
  0% { transform: translate(-900px, 160px) rotate(-4deg) scale(0.96); }
  100% { transform: translate(5000px, 1320px) rotate(-4deg) scale(1.04); }
}

/* Header and navigation */
.site-main a:not(.button):not(.brand-link):not(.nav-link):not(.icon-button) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  min-height: var(--site-header-height);
  background: var(--site-header-bg);
  border-bottom: var(--border-width) solid var(--site-border);
}

.site-header__inner {
  width: min(100% - 2rem, var(--site-measure-wide));
  min-height: var(--site-header-height);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}

.brand-link {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}

.brand-link__mark {
  width: 6.75rem;
  max-width: 46vw;
  height: auto;
  display: block;
}

/* UI sprite icons (formerly Font Awesome). Each <svg class="ui-icon"> is a
   1em-square glyph that inherits the surrounding text color via
   fill="currentColor" set as a presentation attribute (CSS does not cross
   the cross-document <use> shadow boundary; presentation attributes do).
   Per-context size lives on the parent rule (.icon-button .ui-icon, etc.). */
.ui-icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  display: inline-block;
  vertical-align: -0.125em;
  flex: 0 0 auto;
}

/* Theme toggle: render both moon and sun symbols and let CSS switch which is
   visible based on :root[data-color-scheme]. The inline IIFE in <head> sets
   data-color-scheme pre-paint, so the correct glyph is up on first paint —
   no JS class flip, no flash. */
.theme-toggle-icons {
  display: inline-grid;
  place-items: center;
  pointer-events: none;
}

.theme-toggle-icons .ui-icon--sun {
  display: none;
}

:root[data-color-scheme="dark"] .theme-toggle-icons .ui-icon--moon {
  display: none;
}

:root[data-color-scheme="dark"] .theme-toggle-icons .ui-icon--sun {
  display: inline-block;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.site-nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.nav-link {
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  color: var(--site-text);
  font-family: var(--font-sans-tight);
  font-weight: var(--weight-semibold);
}

.nav-link:hover,
.nav-link:focus-visible,
.nav-link[aria-current="page"] {
  color: var(--site-heading);
}

.nav-link[aria-current="page"] {
  border-bottom: 2px solid var(--ec-green-700);
}

.nav-toggle {
  display: none;
  min-width: 2.75rem;
  min-height: 2.75rem;
  border: var(--border-width) solid currentColor;
  border-radius: var(--site-radius-sm);
  background: var(--site-surface);
  color: var(--site-text);
  font: inherit;
}

.nav-toggle__icon,
.nav-toggle__icon::before,
.nav-toggle__icon::after {
  display: block;
  width: 1.25rem;
  height: 2px;
  margin-inline: auto;
  background: currentColor;
}

.nav-toggle__icon {
  position: relative;
}

.nav-toggle__icon::before,
.nav-toggle__icon::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle__icon::before { top: -0.4rem; }
.nav-toggle__icon::after { top: 0.4rem; }

/* Header utility controls — language + theme preferences.
   These reuse the footer icon-button verbatim (.icon-button--footer:
   same 2.5rem square, hairline, radius, teal hover, and dark-mode active
   pill) plus the same .lang-toggle / .theme-toggle primitives and data-*
   JS hooks, so the header and footer controls are the same component.
   The footer values target the always-dark footer surface, so on the
   dark header they are inherited unchanged (identical to the footer). On
   the light header the resting ink + hairline are the only things that
   must change — the footer's near-white ink would be invisible there —
   so they are remapped to the light surface; the teal hover is re-stated
   so it survives that remap. The group sits to the right of the primary
   nav on desktop and moves to the tail of the expanded menu on mobile. */
.site-utilities {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: var(--space-3);
}

:root[data-color-scheme="light"] .site-utilities .icon-button--footer {
  color: var(--site-text);
  border-color: var(--site-border-strong);
}

:root[data-color-scheme="light"] .site-utilities .icon-button--footer:hover,
:root[data-color-scheme="light"] .site-utilities .icon-button--footer:focus-visible {
  color: var(--ec-neutral-950);
  border-color: var(--ec-teal-500);
}

/* Components */
.button {
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.72rem 1rem;
  border: var(--border-width) solid var(--ec-green-700);
  border-radius: var(--site-radius-sm);
  background: var(--ec-green-700);
  color: var(--ec-neutral-100);
  font-family: var(--font-sans-tight);
  font-weight: var(--weight-semibold);
  line-height: 1.1;
  text-align: center;
}

.button__icon {
  width: 1.05rem;
  height: 1.05rem;
  flex: 0 0 auto;
  object-fit: contain;
}

.button__icon.ui-icon {
  width: 1rem;
  height: 1rem;
}

.icon-button {
  width: 3rem;
  height: 3rem;
  display: inline-grid;
  place-items: center;
  border: var(--border-width) solid var(--ec-green-700);
  border-radius: var(--site-radius-sm);
  background: var(--ec-green-700);
  color: var(--ec-neutral-100);
  cursor: pointer;
  transition: transform 160ms var(--ease-standard), background-color 160ms var(--ease-standard), border-color 160ms var(--ease-standard);
}

.icon-button svg,
.icon-button img {
  width: 1.6rem;
  height: 1.6rem;
  object-fit: contain;
}

.icon-button .ui-icon {
  width: 1.5rem;
  height: 1.5rem;
  pointer-events: none;
}

.icon-button--secondary {
  background: var(--site-surface);
  color: var(--ec-green-800);
  border-color: var(--ec-green-700);
}

.icon-button--nav {
  width: 2.75rem;
  height: 2.75rem;
  box-shadow: none;
}

.icon-button--nav .ui-icon {
  width: 1.35rem;
  height: 1.35rem;
}

.icon-button--footer {
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  border-color: var(--ec-neutral-500);
  background: transparent;
  color: var(--ec-neutral-100);
  box-shadow: none;
}

.icon-button--footer .ui-icon {
  width: 1.25rem;
  height: 1.25rem;
}

.icon-button:hover,
.icon-button:focus-visible {
  transform: translateY(1px);
  background: var(--ec-green-800);
  border-color: var(--ec-green-800);
  color: var(--ec-neutral-100);
}

/* Footer icon-button hover keeps boundary contrast on the near-black footer
   (green-800 on #121820 fails WCAG 1.4.11 at ~2.1:1; teal-500 on #121820 ~8.6:1). */
.icon-button--footer:hover,
.icon-button--footer:focus-visible {
  background: var(--ec-teal-500);
  border-color: var(--ec-teal-500);
  color: var(--ec-neutral-950);
}

.button:visited {
  color: var(--ec-neutral-100);
}

.button:hover,
.button:focus-visible {
  background: var(--ec-green-800);
  border-color: var(--ec-green-800);
  color: var(--ec-neutral-100);
}

.button--secondary {
  background: var(--site-surface);
  color: var(--ec-green-800);
  border-color: var(--site-border-strong);
}

.button--secondary:visited {
  color: var(--ec-green-800);
}

.button--secondary:hover,
.button--secondary:focus-visible {
  background: var(--site-bg-muted);
  color: var(--site-heading);
  border-color: var(--site-muted);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.button-row[data-archive-cta] {
  margin-top: var(--space-6);
  justify-content: center;
}

.cluster-articles__cta {
  margin-top: var(--space-6);
  justify-content: center;
}

/* Page sections */
.page-hero,
.home-hero {
  padding-block: clamp(4rem, 8vw, 7rem);
}

.home-hero {
  background: var(--site-bg);
}

.home-hero__grid,
.page-hero__grid,
.split-grid {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(18rem, 0.85fr);
  gap: clamp(var(--space-6), 5vw, var(--space-8));
  align-items: center;
}

.hero-kicker,
.section-kicker,
.card-kicker,
.meta {
  font-family: var(--font-mono);
  font-size: var(--text-small-size);
  line-height: 1.4;
  color: var(--site-muted);
}

.hero-kicker,
.section-kicker {
  text-transform: uppercase;
}

.home-hero h1,
.page-hero h1 {
  max-width: 12ch;
  color: var(--site-heading);
}

.home-hero .lead,
.page-hero .lead {
  max-width: 42rem;
  color: var(--site-text);
}

.hero-actions {
  margin-top: var(--space-6);
}

.text-link {
  color: var(--site-muted);
  font-weight: var(--weight-semibold);
}

.icon-link {
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--site-text);
  font-family: var(--font-sans-tight);
  font-weight: var(--weight-semibold);
}

.icon-link svg {
  width: 1.2rem;
  height: 1.2rem;
}

.icon-link:hover,
.icon-link:focus-visible {
  color: var(--site-heading);
}

.portrait-frame {
  margin: 0;
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius);
  background: var(--ec-neutral-950);
  overflow: hidden;
}

.portrait-frame picture {
  display: block;
}

.portrait-frame img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.portrait-frame--wide img {
  aspect-ratio: 3 / 2;
}

.portrait-frame--home img {
  aspect-ratio: 5 / 4;
  object-position: center top;
}

.hero-art,
.section-art {
  margin: 0;
  display: grid;
  place-items: center;
  min-height: clamp(20rem, 36vw, 32rem);
}

.hero-art img,
.section-art img,
.hero-art .icon-art,
.section-art .icon-art {
  width: min(100%, 32rem);
  height: auto;
  display: block;
}

.section-art {
  min-height: clamp(16rem, 28vw, 24rem);
}

.system-visual {
  display: grid;
  gap: var(--space-4);
  padding: clamp(var(--space-5), 4vw, var(--space-6));
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius);
  background: var(--site-art-bg);
  color: var(--ec-green-700);
}

.system-visual--hero {
  background: var(--site-art-surface);
}

.system-visual svg {
  width: 100%;
  max-width: 24rem;
  margin-inline: auto;
}

.system-visual__labels {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: center;
}

.system-visual__labels span {
  display: inline-flex;
  min-height: 1.75rem;
  align-items: center;
  padding-inline: var(--space-2);
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius-sm);
  background: var(--site-surface);
  color: var(--site-text);
  font-family: var(--font-mono);
  font-size: var(--text-small-size);
}

.credibility-strip {
  border-block: var(--border-width) solid var(--site-border);
  background: var(--site-bg-muted);
}

.credibility-strip__inner {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-3);
  padding-block: var(--space-4);
}

.credibility-item {
  display: grid;
  gap: 0.15rem;
  padding: var(--space-3);
  border-left: 2px solid var(--ec-teal-450);
  font-family: var(--font-sans-tight);
  color: var(--site-text);
}

.credibility-item strong {
  color: var(--site-heading);
  font-size: 1rem;
  line-height: 1.2;
}

.credibility-item span {
  font-size: var(--text-small-size);
  line-height: 1.35;
}

.section-shell {
  padding-block: clamp(var(--space-7), 7vw, 6rem);
}

.section-shell--compact-end {
  padding-bottom: clamp(var(--space-5), 4vw, var(--space-7));
}

.section-shell--compact-start {
  padding-top: clamp(var(--space-5), 4vw, var(--space-7));
}

.section-shell[data-theme="interface-light"] {
  background: var(--site-bg-muted);
}

.section-shell[data-theme="terminal"],
.section-shell[data-theme="operations-console"] {
  background: var(--color-bg);
  color: var(--color-body);
}

.section-inner {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin-inline: auto;
}

.section-header {
  max-width: 46rem;
  margin-bottom: var(--space-6);
}

.section-header h2 {
  margin-top: var(--space-2);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
}

.card-grid--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.card-grid--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.card,
.topic-card,
.insight-card,
.contact-card {
  min-height: 100%;
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius);
  background: var(--site-surface);
  padding: var(--space-5);
}

.media-card {
  gap: var(--space-2);
}

.card-media {
  margin: calc(var(--space-2) * -1) 0 var(--space-1);
  height: 8.5rem;
  display: grid;
  place-items: center;
  padding: var(--space-3);
  border-radius: var(--site-radius-sm);
  overflow: hidden;
}

.card-media img,
.card-media .icon-art {
  width: min(100%, 10.5rem);
  max-height: 8rem;
  height: auto;
}

.card-grid--three .card-media img,
.card-grid--three .card-media .icon-art {
  width: min(100%, 9.75rem);
}

.icon-card {
  display: flex;
  flex-direction: column;
}

.icon-card__icon {
  display: inline-grid;
  place-items: center;
  width: 3.75rem;
  height: 3.75rem;
  margin-bottom: var(--space-3);
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius-sm);
  background: var(--site-art-bg);
  color: var(--ec-green-800);
}

.icon-card__icon svg {
  width: 1.65rem;
  height: 1.65rem;
}

.icon-card__icon img {
  width: 2.75rem;
  height: 2.75rem;
  object-fit: contain;
}

.icon-card__icon .ui-icon {
  width: 1.85rem;
  height: 1.85rem;
}

[data-theme="terminal"] .icon-card__icon,
[data-theme="operations-console"] .icon-card__icon {
  border-color: var(--ec-neutral-500);
  background: var(--ec-neutral-950);
  color: var(--ec-teal-500);
}

.proof-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.proof-card {
  min-height: 100%;
  padding: var(--space-5);
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius);
  background: var(--site-surface);
}

.proof-card h3 {
  margin-top: 0;
}

.proof-card p {
  margin-top: var(--space-2);
}

.card h3,
.topic-card h3,
.insight-card h3,
.contact-card h3 {
  margin-top: var(--space-2);
}

.card ul,
.topic-card ul,
.contact-card ul {
  margin-block: var(--space-4) 0;
}

.proof-list {
  display: grid;
  gap: var(--space-3);
  padding: 0;
  margin: 0;
  list-style: none;
}

.proof-list li {
  padding: var(--space-4);
  border-left: 3px solid var(--ec-teal-450);
  background: var(--site-surface);
}

.console-panel {
  border: var(--border-width) solid var(--ec-neutral-800);
  border-radius: var(--site-radius);
  background: var(--ec-neutral-950);
  color: var(--ec-neutral-100);
  padding: var(--space-5);
}

.console-panel h2,
.console-panel h3,
.console-panel p,
.console-panel li {
  color: var(--ec-neutral-100);
}

.console-panel .meta,
.console-panel .card-kicker {
  color: var(--ec-teal-450);
}

.principle-list,
.clean-list {
  display: grid;
  gap: var(--space-3);
  padding: 0;
  margin: 0;
  list-style: none;
}

.principle-list li,
.clean-list li {
  padding-block: var(--space-3);
  border-bottom: var(--border-width) solid var(--site-border);
}

.timeline {
  display: grid;
  gap: var(--space-4);
}

.timeline-item {
  display: grid;
  grid-template-columns: 11rem minmax(0, 1fr);
  gap: var(--space-5);
  padding-block: var(--space-4);
  border-top: var(--border-width) solid var(--site-border);
}

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

.tag-list li,
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  min-height: 2rem;
  padding: 0.25rem 0.55rem;
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius-sm);
  background: var(--site-bg-muted);
  color: var(--site-text);
  font-family: var(--font-mono);
  font-size: var(--text-small-size);
}

.insight-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.insight-card__footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-3);
}

.insight-card h3 {
  /* Reserve two lines of headline space so the description below
     starts at the same vertical position across every card in a row,
     regardless of title length. Longer titles still expand
     naturally; the footer remains pinned to the bottom of the card
     via the flex `margin-top: auto` rule above. */
  min-height: calc(2 * 1lh);
}

.insight-card h3 a {
  color: inherit;
  text-decoration: none;
}

.insight-card h3 a:hover,
.insight-card h3 a:focus-visible {
  color: var(--site-link-hover);
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

/* Article and Insights patterns */
.article-hero {
  padding-block: clamp(4rem, 8vw, 7rem) clamp(var(--space-5), 5vw, var(--space-7));
  background: var(--site-bg);
}

.article-shell {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin-inline: auto;
}

.breadcrumb-nav,
.article-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  align-items: center;
  color: var(--site-muted);
  font-family: var(--font-mono);
  font-size: var(--text-small-size);
}

.breadcrumb-nav a {
  color: inherit;
}

.article-meta span + span::before {
  content: "/";
  margin-right: var(--space-3);
  color: var(--site-border-strong);
}

.article-shell {
  padding-block: clamp(var(--space-4), 3vw, var(--space-6)) clamp(var(--space-7), 7vw, 6rem);
}

.article-content {
  max-width: 48rem;
}

.article-content h2 {
  margin-top: var(--space-7);
}

.article-dek {
  color: var(--site-heading);
  font-size: var(--text-step-1);
  line-height: 1.55;
}

.article-framework {
  margin-block: var(--space-7);
  padding: var(--space-5);
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius);
  background: var(--site-bg-muted);
}

/* Feature (longform) article layout — Medium-style stacked hero with a
   wide media band and a centered reading column. Scoped to the
   .article-page--feature / .article-hero--feature modifiers so the
   classic side-by-side hero used by other articles is untouched.

   Consistency rules baked in here:
   - Intro block and reading column share the same measure (--feature-measure).
   - Hero media stays "promoted" (wider than the column) for visual lift,
     but uses a shared max so every feature article reads the same. */
.article-page--feature {
  --feature-measure: 56rem;
  --feature-media-max: 76rem;
}

.article-hero--feature {
  padding-block: clamp(3rem, 6vw, 5rem) clamp(var(--space-5), 4vw, var(--space-6));
}

.article-hero--feature .article-hero__intro {
  width: min(100% - 2rem, var(--feature-measure));
  margin-inline: auto;
  text-align: left;
}

.article-hero--feature .article-hero__intro h1 {
  font-size: clamp(2.25rem, 1.4rem + 3vw, 3.5rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-block: var(--space-3) var(--space-4);
}

.article-hero--feature .article-hero__intro .lead {
  font-size: clamp(1.125rem, 0.95rem + 0.6vw, 1.35rem);
  line-height: 1.5;
  color: var(--site-muted);
}

.article-hero--feature .article-meta time {
  color: inherit;
}

.article-hero--feature .article-hero__media {
  width: min(100% - 2rem, var(--feature-media-max));
  margin: clamp(var(--space-5), 4vw, var(--space-7)) auto 0;
  border-radius: var(--site-radius);
  overflow: hidden;
  background: var(--site-bg-muted);
  aspect-ratio: 16 / 9;
}

.article-hero--feature .article-hero__media picture,
.article-hero--feature .article-hero__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.article-page--feature .article-shell {
  padding-block: clamp(var(--space-5), 4vw, var(--space-7)) clamp(var(--space-7), 7vw, 6rem);
}

.article-page--feature .article-content {
  width: min(100% - 2rem, var(--feature-measure));
  max-width: none;
  margin-inline: auto;
  font-size: clamp(1.05rem, 0.95rem + 0.3vw, 1.18rem);
  line-height: 1.7;
}

.article-page--feature .article-content > p {
  margin-block: var(--space-4);
}

.article-page--feature .article-content h2 {
  font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin-top: var(--space-7);
}

.article-page--feature .article-dek {
  font-size: clamp(1.2rem, 1rem + 0.6vw, 1.45rem);
  line-height: 1.55;
  color: var(--site-heading);
  font-weight: 500;
  margin-bottom: var(--space-6);
}

.article-page--feature .article-framework {
  margin-block: var(--space-7);
}

.framework-list {
  display: grid;
  gap: var(--space-3);
  padding-left: 1.4rem;
}

.related-insights {
  border-top: var(--border-width) solid var(--site-border);
}

.notice {
  border: var(--border-width) solid var(--site-border);
  border-radius: var(--site-radius);
  background: var(--site-bg-muted);
  padding: var(--space-5);
}

.notice strong {
  color: var(--site-heading);
}

/* Contact and privacy patterns */
.contact-methods {
  align-items: stretch;
}

.contact-method {
  display: flex;
  flex-direction: column;
}

.contact-method .icon-card__icon {
  margin-bottom: var(--space-3);
}

.contact-method__body {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
  margin-bottom: var(--space-5);
}

.contact-method__body h3,
.contact-method__body p {
  margin: 0;
}

.contact-method .button {
  margin-top: auto;
  justify-self: start;
  align-self: flex-start;
}

.privacy-section {
  max-width: var(--site-measure);
}

.privacy-section + .privacy-section {
  margin-top: var(--space-6);
}

.cta-band {
  background: var(--ec-navy-900);
  color: var(--ec-neutral-100);
  padding-block: clamp(var(--space-7), 7vw, 6rem);
}

.cta-band h2,
.cta-band p {
  color: var(--ec-neutral-100);
}

.cta-band .button--secondary {
  border-color: var(--ec-neutral-100);
}

/* Footer */
.site-footer {
  background: var(--ec-neutral-950);
  color: var(--ec-neutral-100);
  padding-block: var(--space-7) var(--space-5);
}

.site-footer a {
  color: var(--ec-teal-450);
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--ec-teal-500);
}

.site-footer h2,
.site-footer .text-small {
  color: var(--ec-neutral-300);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.site-footer__inner {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(16rem, 1fr) minmax(0, 2fr);
  gap: var(--space-7);
}

.site-footer__brand img {
  width: 10rem;
}

.site-footer__note {
  margin-top: var(--space-4);
  max-width: 48rem;
  color: var(--ec-neutral-100);
}

.site-footer__nav {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
}

.site-footer__nav ul {
  padding: 0;
  margin: var(--space-3) 0 0;
  list-style: none;
}

.site-footer__nav li + li {
  margin-top: var(--space-2);
}

.site-footer__fineprint {
  margin: 0;
  color: var(--ec-neutral-100);
  font-size: var(--text-small-size);
}

.site-footer__bottom {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin: var(--space-6) auto 0;
  padding-top: var(--space-4);
  border-top: var(--border-width) solid var(--ec-neutral-800);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.site-footer__actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.theme-toggle[aria-pressed="true"] {
  background: var(--ec-neutral-100);
  border-color: var(--ec-neutral-100);
  color: var(--ec-green-800);
}

.icon-button--footer.theme-toggle[aria-pressed="true"] {
  background: var(--ec-neutral-100);
  border-color: var(--ec-neutral-100);
  color: var(--ec-green-800);
}

:root[data-color-scheme="dark"] [data-theme="launchpad"],
:root[data-color-scheme="dark"] [data-theme="interface-light"] {
  --color-bg: var(--ec-neutral-950);
  --color-heading: var(--ec-neutral-100);
  --color-body: var(--ec-neutral-200);
  --color-surface: var(--ec-neutral-900);
  --color-border: var(--ec-neutral-800);
}

/* Dark-mode component refinements */
:root[data-color-scheme="dark"] .site-header,
:root[data-color-scheme="dark"] .home-hero,
:root[data-color-scheme="dark"] .page-hero,
:root[data-color-scheme="dark"] .section-shell,
:root[data-color-scheme="dark"] .credibility-strip {
  background: var(--ec-neutral-950);
  color: var(--ec-neutral-200);
}

:root[data-color-scheme="dark"] .site-header,
:root[data-color-scheme="dark"] .site-nav__links,
:root[data-color-scheme="dark"] .credibility-strip,
:root[data-color-scheme="dark"] .site-footer__bottom {
  border-color: var(--ec-neutral-800);
}

:root[data-color-scheme="dark"] .section-shell[data-theme="interface-light"] {
  background: var(--ec-neutral-900);
}

:root[data-color-scheme="dark"] .nav-link,
:root[data-color-scheme="dark"] .home-hero .lead,
:root[data-color-scheme="dark"] .page-hero .lead,
:root[data-color-scheme="dark"] .credibility-item,
:root[data-color-scheme="dark"] .text-link,
:root[data-color-scheme="dark"] .icon-link,
:root[data-color-scheme="dark"] .hero-kicker,
:root[data-color-scheme="dark"] .section-kicker,
:root[data-color-scheme="dark"] .card-kicker,
:root[data-color-scheme="dark"] .meta {
  color: var(--ec-neutral-300);
}

:root[data-color-scheme="dark"] .nav-link:hover,
:root[data-color-scheme="dark"] .nav-link:focus-visible,
:root[data-color-scheme="dark"] .home-hero h1,
:root[data-color-scheme="dark"] .page-hero h1,
:root[data-color-scheme="dark"] h2,
:root[data-color-scheme="dark"] h3,
:root[data-color-scheme="dark"] .credibility-item strong,
:root[data-color-scheme="dark"] .notice strong {
  color: var(--ec-neutral-100);
}

:root[data-color-scheme="dark"] .card,
:root[data-color-scheme="dark"] .topic-card,
:root[data-color-scheme="dark"] .insight-card,
:root[data-color-scheme="dark"] .contact-card,
:root[data-color-scheme="dark"] .proof-card,
:root[data-color-scheme="dark"] .article-framework,
:root[data-color-scheme="dark"] .notice,
:root[data-color-scheme="dark"] .portrait-frame,
:root[data-color-scheme="dark"] .system-visual,
:root[data-color-scheme="dark"] .tag-list li,
:root[data-color-scheme="dark"] .status-pill {
  border-color: var(--ec-neutral-800);
  background: var(--ec-neutral-900);
  color: var(--ec-neutral-200);
}

:root[data-color-scheme="dark"] .card-media,
:root[data-color-scheme="dark"] .icon-card__icon,
:root[data-color-scheme="dark"] .system-visual__labels span {
  border-color: var(--ec-neutral-800);
  background: var(--ec-neutral-950);
  color: var(--ec-teal-500);
}

:root[data-color-scheme="dark"] .button--secondary {
  background: var(--ec-neutral-950);
  border-color: var(--ec-neutral-500);
  color: var(--ec-neutral-100);
}

:root[data-color-scheme="dark"] .button--secondary:visited {
  color: var(--ec-neutral-100);
}

:root[data-color-scheme="dark"] .button--secondary:hover,
:root[data-color-scheme="dark"] .button--secondary:focus-visible {
  background: var(--ec-neutral-900);
  border-color: var(--ec-teal-450);
  color: var(--ec-teal-500);
}

/* On dark backgrounds, green-800 hover collapses the button boundary
   to ~2:1 vs the page bg (WCAG 1.4.11 needs 3:1). Use teal accent. */
:root[data-color-scheme="dark"] .icon-button:hover,
:root[data-color-scheme="dark"] .icon-button:focus-visible {
  background: var(--ec-teal-500);
  border-color: var(--ec-teal-500);
  color: var(--ec-neutral-950);
}

:root[data-color-scheme="dark"] .icon-button--secondary {
  background: var(--ec-neutral-950);
  border-color: var(--ec-neutral-500);
  color: var(--ec-neutral-100);
}

:root[data-color-scheme="dark"] .site-main a:not(.button):not(.brand-link):not(.nav-link):not(.icon-button) {
  color: var(--ec-teal-450);
}

/* Responsive rules */
@media (max-width: 72rem) {
  .card-grid,
  .card-grid--three,
  .card-grid--two,
  .proof-grid,
  .credibility-strip__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 54rem) {
  .site-header__inner {
    align-items: center;
  }

  .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .site-nav {
    gap: var(--space-3);
  }

  .site-nav__links {
    position: fixed;
    inset: var(--site-header-height) 0 auto 0;
    display: none;
    grid-template-columns: 1fr;
    gap: 0;
    padding: var(--space-4);
    background: var(--ec-neutral-100);
    border-bottom: var(--border-width) solid var(--ec-neutral-200);
  }

  :root[data-color-scheme="dark"] .site-nav__links {
    background: var(--ec-neutral-950);
    border-bottom-color: var(--ec-neutral-800);
  }

  body.nav-open .site-nav__links {
    display: grid;
  }

  .site-nav__links .nav-link,
  .site-nav__links .button,
  .site-nav__links .icon-button {
    justify-content: flex-start;
  }

  .site-nav__links .icon-button--nav {
    display: none;
  }

  /* In the expanded mobile menu the utilities sit below the nav links:
     drop the desktop separator margin and add a small break. Keep the
     reused footer buttons' icons centered — the generic
     .site-nav__links .icon-button flex-start rule targets the full-width
     nav-variant buttons, not these fixed 2.5rem squares. */
  .site-utilities {
    margin-inline-start: 0;
    margin-top: var(--space-3);
  }

  .site-nav__links .site-utilities .icon-button {
    justify-content: center;
  }

  .home-hero__grid,
  .page-hero__grid,
  .split-grid,
  .site-footer__inner,
  .site-footer__bottom {
    grid-template-columns: 1fr;
  }

  .site-footer__bottom {
    align-items: flex-start;
    display: grid;
  }

  .home-hero h1,
  .page-hero h1 {
    max-width: 12ch;
  }

  .portrait-frame {
    max-width: 28rem;
  }

  .timeline-item {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

@media (max-width: 38rem) {
  :root {
    --step-4: 2.35rem;
    --step-3: 1.65rem;
    --step-2: 1.25rem;
  }

  .site-header__inner,
  .section-inner,
  .home-hero__grid,
  .page-hero__grid,
  .credibility-strip__inner,
  .site-footer__inner,
  .site-footer__fineprint {
    width: min(100% - 1.25rem, var(--site-measure-wide));
  }

  .brand-link__mark {
    width: 6rem;
  }

  .brand-tagline:not(.brand-lockup--intro .brand-tagline) {
    font-size: 1.55rem;
    line-height: 1.95rem;
  }

@media (max-width: 22rem) {
  .brand-lockup--intro {
    gap: 0;
  }

  .brand-lockup--intro .brand-tagline {
    display: none;
  }
}

  .card-grid,
  .card-grid--three,
  .card-grid--two,
  .proof-grid,
  .credibility-strip__inner,
  .site-footer__nav {
    grid-template-columns: 1fr;
  }

  .button-row {
    align-items: stretch;
  }

  .button-row .button {
    width: 100%;
  }

  .icon-button {
    width: 2.75rem;
    height: 2.75rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .brand-intro.is-active,
  .brand-intro.is-active .brand-intro__logo,
  .brand-intro.is-active .brand-intro__fill,
  .brand-intro.is-active .brand-intro__fill use,
  .brand-intro.is-active .brand-intro__back-glow,
  .brand-intro.is-active .brand-intro__sweep,
  .brand-intro.is-active .brand-intro__shine-light,
  .brand-intro.is-active .brand-intro__c-reveal-stroke,
  .brand-intro.is-active .brand-lockup--intro::after,
  .brand-intro.is-active .brand-tagline {
    animation: none;
  }

  .brand-intro__fill {
    opacity: 1;
  }

  .brand-intro__fill use {
    opacity: 1;
    transform: none;
  }

  .brand-intro__c-reveal-stroke {
    stroke-dashoffset: 0;
  }

  .brand-intro__back-glow,
  .brand-intro__sweep {
    opacity: 0;
  }

}

/* Language toggle (i18n switcher).
   Lives in .site-footer__actions next to the theme toggle. Renders a
   short text label ("ES" / "EN") instead of an icon; inherits sizing,
   border, and hover from .icon-button--footer. */
.lang-toggle {
  text-decoration: none;
  letter-spacing: 0.04em;
}

.lang-toggle .lang-toggle__label {
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.75rem;
  font-weight: var(--weight-semibold, 600);
  line-height: 1;
  pointer-events: none;
}

/* Language suggestion banner (i18n soft nudge).
   Injected by main.js when navigator.language disagrees with the page's
   <html lang>. Sits above .site-header in normal flow so it scrolls away;
   we deliberately avoid sticky/fixed to keep it unobtrusive. Surface treatment
   matches the header so the strip reads as part of the site chrome. */
.lang-suggestion {
  background: var(--site-header-bg);
  border-bottom: var(--border-width) solid var(--site-border);
  color: var(--color-body);
  font-family: var(--font-sans);
  font-size: var(--text-small-size);
  line-height: var(--lh-body);
}

.lang-suggestion__inner {
  width: min(100% - 2rem, var(--site-measure-wide));
  margin-inline: auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding-block: var(--space-3);
}

.lang-suggestion__text {
  margin: 0;
  color: var(--color-body);
}

.lang-suggestion__link {
  color: var(--color-body);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  font-weight: var(--weight-medium);
}

.lang-suggestion__link:hover,
.lang-suggestion__link:focus-visible {
  color: var(--color-accent-hover);
}

.lang-suggestion__dismiss {
  margin-inline-start: auto;
  background: transparent;
  border: 0;
  color: var(--color-body);
  font-size: 1.125rem;
  line-height: 1;
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.lang-suggestion__dismiss:hover,
.lang-suggestion__dismiss:focus-visible {
  color: var(--color-accent-hover);
}

.lang-suggestion.is-leaving {
  opacity: 0;
  transition: opacity var(--dur-200) var(--ease-standard);
}

@media (prefers-reduced-motion: reduce) {
  .lang-suggestion.is-leaving {
    transition: none;
  }
}

/* Print styles */
@media print {
  .site-header,
  .site-footer,
  .button-row,
  .nav-toggle,
  .lang-suggestion {
    display: none;
  }

  body {
    color: var(--ec-neutral-700);
    background: var(--ec-neutral-100);
  }

  a {
    color: var(--ec-neutral-700);
    text-decoration: underline;
  }
}

/* Article body tables.
   - Visual language mirrors the brand-guide `.typography-table` shape:
     2px top rule in heading color, uppercase thead, 1px row separators,
     row labels (first column) lifted in heading color.
   - Sits inside the reading column (no bleed) so it shares the editorial
     rhythm with paragraphs. Scrolls horizontally when the table content
     exceeds the column. The brand convention is native scrollbars only;
     the small bottom padding leaves a gutter for the scrollbar so it does
     not collide with the table's bottom border. */
.article-page--feature .article-content .article-table {
  margin-block: var(--space-6);
  overflow-x: auto;
  padding-bottom: 0.65rem;
}

.article-page--feature .article-content .article-table > table {
  width: 100%;
  min-width: 76rem;
  border-collapse: collapse;
  border-top: 2px solid var(--site-heading);
  font-size: clamp(0.875rem, 0.82rem + 0.18vw, 0.9375rem);
  line-height: 1.5;
  color: var(--site-text);
}

.article-page--feature .article-content .article-table th,
.article-page--feature .article-content .article-table td {
  padding: 0.65rem 0.75rem;
  border-bottom: var(--border-width) solid var(--site-border);
  vertical-align: top;
  text-align: left;
  min-width: 8rem;
}

/* The first column carries the long row labels (e.g. pattern names),
   so it gets the most breathing room. */
.article-page--feature .article-content .article-table th:first-child,
.article-page--feature .article-content .article-table td:first-child {
  min-width: 14rem;
}

/* Trailing columns in comparison tables tend to hold short rating
   labels like "Low–Medium" or "Medium–High" \u2014 the en-dash is a wrap
   point in CSS, which fragments those into two lines unnecessarily.
   Since the wrap div already provides horizontal scroll, keep these
   labels on a single line and let the user pan if needed. */
.article-page--feature .article-content .article-table tbody td:not(:first-child) {
  white-space: nowrap;
}

.article-page--feature .article-content .article-table thead th {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--site-heading);
}

/* Lift the first column as a row label — mirrors the brand guide's
   `tbody th[scope="row"]` treatment without requiring authors to mark
   row-header cells in markdown. The `<strong>` that python-markdown
   emits for bold leading cells loses its visual weight here, so we
   neutralize it to avoid double-bolding. */
.article-page--feature .article-content .article-table tbody td:first-child {
  font-weight: 600;
  color: var(--site-heading);
}

.article-page--feature .article-content .article-table tbody td:first-child strong {
  font-weight: inherit;
}

/* Article body diagrams.
   - The figure is just a layout container. The inner
     `.article-diagram__media` div is the white card that hosts the SVG.
     The figcaption sits OUTSIDE the card, on the page background, so it
     picks up the site's typography rhythm and adapts to light/dark via
     --site-text.
   - The SVG itself is pinned to its light variant via
     `color-scheme: only light` in the SVG root, so the diagram looks
     identical in both themes regardless of OS preference.
   - Sits inside the reading column (no bleed) to share the editorial
     rhythm with paragraphs; the white card supplies all the visual lift
     the figure needs.
   - The `figure.article-diagram` selector is the canonical shape
     (produced by the wrapDiagrams filter when a frontmatter caption
     exists). The `p:has(> img)` selector is the fallback for diagrams
     shipped without a caption entry — it has no inner wrapper, so the
     paragraph itself acts as the card. */
.article-page--feature .article-content figure.article-diagram,
.article-page--feature .article-content p:has(> img[src$=".svg"]:only-child) {
  margin-block: var(--space-6);
}

.article-page--feature .article-content figure.article-diagram > .article-diagram__media,
.article-page--feature .article-content p:has(> img[src$=".svg"]:only-child) {
  padding: clamp(var(--space-3), 2vw, var(--space-5));
  background: #ffffff;
  border-radius: var(--site-radius);
  border: var(--border-width) solid var(--ec-neutral-200, #e5e7eb);
}

.article-page--feature .article-content figure.article-diagram > .article-diagram__media > img,
.article-page--feature .article-content p > img[src$=".svg"]:only-child {
  display: block;
  width: 100%;
  height: auto;
}

.article-page--feature .article-content figure.article-diagram > figcaption {
  margin-top: var(--space-3);
  padding-inline: clamp(var(--space-2), 1vw, var(--space-3));
  color: var(--site-text);
  font-size: clamp(0.9rem, 0.85rem + 0.15vw, 1rem);
  line-height: 1.5;
  text-align: center;
}

.article-page--feature .article-content figure.article-diagram .article-diagram__num {
  font-weight: 600;
  color: var(--site-heading, var(--ec-neutral-900, #111827));
  letter-spacing: 0.01em;
}

/* Dark theme: lift the white card slightly so it reads as a deliberate
   surface rather than a stark hole in the page. The figcaption inherits
   --site-text which auto-switches to a light value in dark mode, so it
   stays readable on the dark page background outside the card. */
:root[data-color-scheme="dark"] .article-page--feature .article-content figure.article-diagram > .article-diagram__media,
:root[data-color-scheme="dark"] .article-page--feature .article-content p:has(> img[src$=".svg"]:only-child) {
  border-color: transparent;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04), 0 12px 32px rgba(0, 0, 0, 0.35);
}

/* Structured-advice list — mirrors the brand guide's `.dos-standard`
   pattern (Do's & Don'ts) applied to longform article checklists. Each
   `<li>` becomes a two-column row: the bold lead (`<strong>`) sits in
   the left column as a heading-style label, and the rest of the text
   flows as the explanation on the right. A small mono leading-zero
   counter prefixes each label so the list reads as a deliberate
   numbered sequence without competing with the heading weight. */
.article-page--feature .article-content .article-guidance {
  margin-block: var(--space-6);
  padding: 0;
  list-style: none;
  border-top: 0.2rem solid var(--site-heading);
  counter-reset: article-guidance;
}

.article-page--feature .article-content .article-guidance > li {
  counter-increment: article-guidance;
  display: grid;
  grid-template-columns: minmax(11rem, 14rem) minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2rem);
  padding-block: var(--space-4);
  border-bottom: var(--border-width) solid var(--site-border);
}

.article-page--feature .article-content .article-guidance > li > strong {
  font-weight: 600;
  color: var(--site-heading);
  line-height: 1.3;
}

.article-page--feature .article-content .article-guidance > li > strong::before {
  content: counter(article-guidance, decimal-leading-zero);
  display: block;
  margin-bottom: 0.35rem;
  color: var(--site-muted, var(--ec-neutral-600, #6b7280));
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  font-weight: 500;
}

@media (max-width: 48rem) {
  .article-page--feature .article-content .article-guidance > li {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* Definition-style lists — lighter sibling of `.article-guidance` used
   for term/explanation `<ul>` lists scattered through longform articles
   (e.g. zone glossaries, symptom catalogs, capability inventories). The
   two-column grid unifies them visually with the Practical Guidance
   pattern, but the lighter treatment (no top navy rule, no mono
   counter, narrower label column, tighter row padding) keeps the
   numbered checklist as the clear hierarchical peak of the page.
   Authors apply this by classing the `<ul>` with `article-definitions`
   only when every `<li>` starts with `<strong>Term.</strong> explanation`. */
.article-page--feature .article-content .article-definitions {
  margin-block: var(--space-5);
  padding: 0;
  list-style: none;
}

.article-page--feature .article-content .article-definitions > li {
  display: grid;
  grid-template-columns: minmax(9rem, 12rem) minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2rem);
  padding-block: var(--space-3);
  border-bottom: var(--border-width) solid var(--site-border);
}

.article-page--feature .article-content .article-definitions > li:first-child {
  border-top: var(--border-width) solid var(--site-border);
}

.article-page--feature .article-content .article-definitions > li > strong {
  font-weight: 600;
  color: var(--site-heading);
  line-height: 1.4;
}

@media (max-width: 48rem) {
  .article-page--feature .article-content .article-definitions > li {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* Bulleted questions list — mirrors the brand guide's `.logo-rule-list`
   pattern. Used for short, scannable question-form items where each
   line is one self-contained idea. The dot is positioned absolutely
   rather than placed in a grid column, because list items often
   contain inline children (e.g. `<em>`) and CSS Grid would split each
   text run into a separate grid item, breaking the layout. */
.article-page--feature .article-content .article-questions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-block: var(--space-5);
  padding: 0;
  list-style: none;
}

.article-page--feature .article-content .article-questions > li {
  position: relative;
  padding-left: 1.25rem;
}

.article-page--feature .article-content .article-questions > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6rem;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--site-heading);
}

/* Numbered editorial sequences — an ordered list whose items are short
   sub-sections (an `<h3>` plus its explanatory prose) prefixed with a
   two-digit leading-zero counter in the brand mono face. A deliberately
   light, narrative alternative to `.article-framework`: no card, panel,
   background, shadow, or icon — just a hanging number in a narrow left
   column with hairline rules between items, so a diagnostic or conduct
   sequence reads as a considered list without interrupting the essay.
   Works for any list length; `decimal-leading-zero` keeps producing two
   digits past 09 and the `auto` number column prevents clipping if a
   sequence ever runs to three digits. The native `<ol>`/`<li>` carry the
   ordered semantics for assistive technology; the rendered number is
   generated content (`::before`) and is not separately announced. */
.article-page--feature .article-content .article-numbered-sections {
  margin-block: var(--space-6);
  padding: 0;
  list-style: none;
  counter-reset: article-seq;
  border-top: var(--border-width) solid var(--site-border);
}

.article-page--feature .article-content .article-numbered-sections > li {
  counter-increment: article-seq;
  display: grid;
  grid-template-columns: [num] minmax(2.25rem, auto) [body] minmax(0, 1fr);
  column-gap: clamp(1rem, 3vw, 1.75rem);
  padding-block: var(--space-5);
  border-bottom: var(--border-width) solid var(--site-border);
}

.article-page--feature .article-content .article-numbered-sections > li::before {
  content: counter(article-seq, decimal-leading-zero);
  grid-column: num;
  grid-row: 1;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.06em;
  color: var(--site-muted);
  font-variant-numeric: tabular-nums;
}

/* Heading and paragraphs flow down the body column. */
.article-page--feature .article-content .article-numbered-sections > li > * {
  grid-column: body;
  margin-block: 0;
}

.article-page--feature .article-content .article-numbered-sections > li > * + * {
  margin-top: var(--space-3);
}

.article-page--feature .article-content .article-numbered-sections > li > h3 {
  color: var(--site-heading);
  line-height: 1.3;
}

/* Mobile: the number stacks above the heading in a single column. */
@media (max-width: 48rem) {
  .article-page--feature .article-content .article-numbered-sections > li {
    grid-template-columns: 1fr;
  }
  .article-page--feature .article-content .article-numbered-sections > li::before {
    grid-row: auto;
    margin-bottom: var(--space-2);
  }
}

/* Footnote backrefs — python-markdown emits one `↩` per body reference,
   so a footnote cited twice in the article gets two backrefs. When that
   happens, number them (`↩¹ ↩²`) so readers can tell at a glance
   which reference each one returns to. Singletons stay as plain `↩`. */
.article-page--feature .article-content .footnote ol > li:has(.footnote-backref + .footnote-backref) {
  counter-reset: ec-backref;
}
.article-page--feature .article-content .footnote ol > li:has(.footnote-backref + .footnote-backref) .footnote-backref {
  counter-increment: ec-backref;
}
.article-page--feature .article-content .footnote ol > li:has(.footnote-backref + .footnote-backref) .footnote-backref::after {
  content: counter(ec-backref);
  font-size: 0.7em;
  vertical-align: super;
  margin-left: 0.1em;
}
.article-page--feature .article-content .footnote-backref + .footnote-backref {
  margin-left: 0.4rem;
}

/* Article comments (Giscus). Renders only on article pages that opt
   in via `comments: true` in the manifest front-matter. Backed by the
   separate public discussions repo — see `docs/comments.md`.

   Design intent: quiet, professional discussion space. Reuses the
   existing `.section-shell` cadence so vertical rhythm matches the
   related-insights and CTA blocks above it. Constrained to the
   article reading measure so it does not visually outweigh the
   article body. */
.article-comments {
  border-top: var(--border-width) solid var(--site-border);
  background: var(--site-bg);
  padding-block: clamp(var(--space-6), 6vw, 5rem);
}

.article-comments__inner {
  max-width: 48rem;
}

.article-comments__header {
  margin-bottom: var(--space-4);
}

.article-comments h2 {
  margin: 0 0 var(--space-2) 0;
  color: var(--site-heading);
}

.article-comments__intro {
  margin: 0;
  color: var(--site-text);
}

.article-comments__policy {
  margin-block: var(--space-3) var(--space-5);
  color: var(--site-muted);
  font-size: var(--text-small-size);
  line-height: 1.55;
}

.article-comments__giscus {
  margin-top: var(--space-4);
}

.article-comments .giscus,
.article-comments .giscus-frame {
  width: 100%;
  max-width: 100%;
}

.article-comments .giscus-frame {
  border: 0;
  color-scheme: normal;
}
