/* Built from assets/css/src — edit the sources, then run: php bin/build-assets.php */

/* ==== 00-tokens.css ==== */
/* Design tokens. Light is the default; html[data-theme="dark"] remaps surfaces only. Brand reds never change. */
:root {
  --brand: #E30220;
  --brand-dark: #BF0000;
  /* --brand at small/normal text sizes on --dark-panel-2 (#141214) is 3.81:1,
     under WCAG AA's 4.5:1 -- fails for the nav's current-page indicator and
     the blog card date. This is --brand lightened toward white until it
     clears 4.5:1 with headroom (5.15:1 measured), for text-on-dark-panel use
     only; buttons/accents keep plain --brand. */
  --brand-on-dark: #EB4E63;
  --ink: #242024;
  --grey: #DDDDDD;
  --paper: #F3F4F5;
  --white: #ffffff;

  --bg: #F3F4F5;
  --surface: #ffffff;
  --surface-2: #F3F4F5;
  --text: #242024;
  --text-muted: #5d585d;
  --border: #DDDDDD;
  --on-dark: #F3F4F5;
  --on-dark-muted: #c9c4c9;
  --dark-panel: #242024;
  --dark-panel-2: #141214;
  --shadow: 0 12px 32px rgba(0, 0, 0, .16);
  --shadow-sm: 0 4px 14px rgba(0, 0, 0, .12);
  --overlay: linear-gradient(90deg, rgba(36, 32, 36, .9) 0%, rgba(36, 32, 36, .55) 60%, rgba(191, 0, 0, .45) 100%);
  --overlay-red: linear-gradient(180deg, rgba(191, 0, 0, .85) 0%, rgba(36, 32, 36, .9) 100%);
  --overlay-dark: linear-gradient(180deg, rgba(20, 18, 20, .85), rgba(20, 18, 20, .92));

  --font: "Source Sans 3", "Segoe UI", Arial, sans-serif;
  --container: 1200px;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --section: clamp(3rem, 7vw, 5.5rem);
  --radius: 8px;
  --radius-lg: 20px;
  --pill: 999px;
  --ease: cubic-bezier(.2, .7, .2, 1);
}

html[data-theme="dark"] {
  --bg: #141214;
  --surface: #242024;
  --surface-2: #1b191b;
  --text: #F3F4F5;
  --text-muted: #bdb8bd;
  --border: #3A363A;
  --shadow: 0 12px 32px rgba(0, 0, 0, .55);
  --shadow-sm: 0 4px 14px rgba(0, 0, 0, .45);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ==== 01-fonts.css ==== */
@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/source-sans-3-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/source-sans-3-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/source-sans-3-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 900; font-display: swap; src: url("../fonts/source-sans-3-latin-900-normal.woff2") format("woff2"); }

/* ==== 02-base.css ==== */
/* Reset + typography + layout primitives + buttons */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; font-family: var(--font); font-size: 1.0625rem; line-height: 1.6; color: var(--text); background: var(--bg); -webkit-font-smoothing: antialiased; }
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-dark); }
h1, h2, h3, h4 { margin: 0 0 .5em; line-height: 1.15; font-weight: 700; color: inherit; }
h1 { font-size: clamp(2.25rem, 5vw, 3.5rem); font-weight: 900; }
h2 { font-size: clamp(1.75rem, 3.5vw, 2.5rem); }
h3 { font-size: clamp(1.25rem, 2.2vw, 1.625rem); }
h4 { font-size: 1.125rem; }
p { margin: 0 0 1em; }
ul, ol { margin: 0 0 1em; padding-left: 1.25em; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }

.container { width: min(100% - 2 * var(--gutter), var(--container)); margin-inline: auto; }
.container--narrow { max-width: 900px; }
.section { padding-block: var(--section); }
.section--tight { padding-block: calc(var(--section) * .6); }
.section--dark { background: var(--dark-panel); color: var(--on-dark); }
.section--black { background: var(--dark-panel-2); color: var(--on-dark); }
.section--paper { background: var(--surface-2); }
.text-center { text-align: center; }
.lead { font-size: 1.25rem; }
.muted { color: var(--text-muted); }
.eyebrow { display: block; font-size: 1.125rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; margin-bottom: .25em; }
.section-title { font-size: clamp(1.9rem, 4vw, 2.75rem); font-weight: 900; text-transform: uppercase; letter-spacing: .02em; margin-bottom: .25em; }
.section-title small { display: block; font-size: .5em; font-weight: 400; letter-spacing: .04em; }
/* A sub that is a whole sentence rather than a two-word kicker. .section-title is uppercase and
   small inherits text-transform, which makes a sentence shouty and hard to read; this opts out and
   holds it to a comfortable measure. */
.section-title__lede { text-transform: none; letter-spacing: 0; font-size: .34em; line-height: 1.5; max-width: 62ch; margin: .5em auto 0; }
.section-sub { font-size: 1.25rem; font-weight: 400; text-transform: none; letter-spacing: 0; margin-bottom: 1.5rem; }
.grid { display: grid; gap: 2rem; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 992px) { .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; } }

.screen-reader-text { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: -999px; top: 0; z-index: 1000; background: var(--brand); color: #fff; padding: .5rem 1rem; }
.skip-link:focus { left: 1rem; top: 1rem; color: #fff; }

/* Buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .5rem; min-height: 2.5rem; padding: .5rem 1.5rem; border-radius: 4px; font-size: .8125rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; line-height: 1.2; transition: background .2s var(--ease), color .2s var(--ease), transform .2s var(--ease); }
.btn:hover { transform: translateY(-1px); }
.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-dark); color: #fff; }
.btn--outline { border: 1.5px solid currentColor; color: var(--text); background: transparent; }
.btn--outline:hover { background: var(--text); color: var(--bg); }
.section--dark .btn--outline, .section--black .btn--outline { color: var(--on-dark); }
.section--dark .btn--outline:hover, .section--black .btn--outline:hover { background: var(--on-dark); color: var(--ink); }
.btn--light { background: #fff; color: var(--ink); }
.btn--light:hover { background: var(--paper); color: var(--ink); }
.btn--dojo { background: #fff; color: var(--ink); border-radius: var(--pill); padding: .55rem 1.25rem; font-size: .75rem; }
.btn--dojo svg { width: 1.1em; height: 1.1em; color: var(--brand); }
.btn--dojo:hover { background: var(--brand); color: #fff; }
.btn--dojo:hover svg { color: #fff; }
.btn--lg { min-height: 3rem; padding: .75rem 2rem; font-size: .9375rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; }

/* Inline SVG icons */
.icon { width: 1em; height: 1em; fill: currentColor; flex: none; }
.icon--lg { width: 2.25rem; height: 2.25rem; }
.icon--xl { width: 3rem; height: 3rem; }

/* Curved section edges used throughout the mockups. The pseudo-elements
   bleed 10% past each side of the section on purpose -- that's what makes
   the border-radius ellipse read as a flat, wide arc -- but that 10% was
   never meant to be visible (nothing past the section's own edge is), so
   overflow-x: clip crops it at the section boundary with no visual change.
   overflow-x only (not overflow/overflow-y) so vertical overlap patterns
   like .callout and .why-start, which intentionally escape these sections
   above/below, are completely unaffected; see docs/VISUAL-QA.md. */
.curve-bottom { position: relative; overflow-x: clip; }
.curve-bottom::after { content: ""; position: absolute; left: -10%; right: -10%; bottom: -1px; height: clamp(40px, 8vw, 120px); background: var(--bg); border-radius: 50% 50% 0 0 / 100% 100% 0 0; }
.section--paper.curve-bottom::after { background: var(--surface-2); }
.curve-top { position: relative; overflow-x: clip; }
.curve-top::before { content: ""; position: absolute; left: -10%; right: -10%; top: -1px; height: clamp(40px, 8vw, 120px); background: var(--bg); border-radius: 0 0 50% 50% / 0 0 100% 100%; z-index: 1; }

/* Load more */
.load-more { display: flex; justify-content: center; margin-top: 2.5rem; }
.load-more .btn[aria-busy="true"] { opacity: .6; pointer-events: none; }

/* ==== 03-header.css ==== */
/* Utility bar */
.utility-bar { background: var(--brand-dark); color: #fff; font-size: .8125rem; }
.utility-bar__inner { display: flex; align-items: center; justify-content: space-between; min-height: 34px; gap: 1rem; }
.utility-bar__text { margin: 0; }
.utility-bar__text a { color: #fff; font-weight: 700; }
.utility-bar__right { display: flex; align-items: center; gap: .75rem; }
.social { display: flex; gap: .4rem; list-style: none; margin: 0; padding: 0; }
.social a { display: inline-flex; width: 1.5rem; height: 1.5rem; border-radius: 50%; align-items: center; justify-content: center; background: #fff; color: var(--ink); transition: transform .2s var(--ease); }
.social a:hover { transform: scale(1.1); color: var(--brand); }
.social .icon { width: .9rem; height: .9rem; }
.social--lg a { width: 2rem; height: 2rem; }
.social--lg .icon { width: 1.15rem; height: 1.15rem; }
/* Site-owner request: brand-coloured circles instead of uniform white ones.
   The glyph is an inline SVG using fill: currentColor (see .icon in
   02-base.css), so setting the link's own `color` to white recolors the
   glyph for free; only the circle's `background` needs the per-network
   brand colour. Selectors repeat `.social a` (specificity 0,0,1,1) ahead of
   the class -- `.social__facebook` alone (0,0,1,0) loses the cascade to the
   base `.social a { background: #fff }` rule above it despite coming later
   in the file, since a lower-specificity selector never overrides a
   higher-specificity one regardless of source order (confirmed: without
   this, the circles measured as unchanged #fff). Colour stays fixed on
   hover (overriding the generic .social a:hover rule above, which would
   otherwise turn every glyph the site's red brand colour) since
   white-on-brand-colour is legible in both the dark footer and the red
   utility bar, which a hover-red glyph is not guaranteed to be against every
   one of these backgrounds. */
.social a.social__facebook, .social a.social__x, .social a.social__youtube, .social a.social__linkedin, .social a.social__instagram, .social a.social__meetup { color: #fff; }
.social a.social__facebook { background: #1877F2; }
.social a.social__x { background: #000000; }
.social a.social__youtube { background: #FF0000; }
.social a.social__linkedin { background: #0A66C2; }
.social a.social__instagram { background: #E4405F; }
.social a.social__meetup { background: #F13A59; }
.social a.social__facebook:hover, .social a.social__x:hover, .social a.social__youtube:hover, .social a.social__linkedin:hover, .social a.social__instagram:hover, .social a.social__meetup:hover { color: #fff; }
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; border: 1px solid rgba(255,255,255,.5); color: #fff; }
.theme-toggle .icon { width: 1rem; height: 1rem; }
.theme-toggle__moon { display: none; }
html[data-theme="dark"] .theme-toggle__sun { display: none; }
html[data-theme="dark"] .theme-toggle__moon { display: block; }

/* Nav bar */
.nav-bar { background: var(--dark-panel-2); color: #fff; position: relative; z-index: 50; }
.nav-bar__inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; min-height: 84px; }
.site-logo { display: block; flex: none; }
.site-logo__img { width: 150px; height: auto; }
.primary-nav { display: flex; align-items: center; gap: 1.5rem; flex: 1; justify-content: flex-end; }
.primary-menu { display: flex; list-style: none; margin: 0; padding: 0; gap: .25rem; }
.primary-menu > li { position: relative; }
.primary-menu > li > a { display: flex; flex-direction: column; align-items: center; gap: .3rem; padding: .75rem .9rem; color: #fff; font-size: .6875rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.primary-menu > li > a:hover, .primary-menu > li.current-menu-item > a, .primary-menu > li.current-menu-ancestor > a { color: var(--brand-on-dark); }
.menu-icon { width: 1.5rem; height: 1.5rem; }
.menu-label { display: inline-flex; align-items: center; gap: .15rem; white-space: nowrap; }
.menu-chevron { width: .9rem; height: .9rem; }
.submenu-toggle { display: none; }
.sub-menu { position: absolute; top: 100%; left: 50%; transform: translate(-50%, 8px); min-width: 220px; background: var(--dark-panel-2); border-top: 3px solid var(--brand); box-shadow: var(--shadow); list-style: none; margin: 0; padding: .5rem 0; opacity: 0; visibility: hidden; transition: opacity .2s var(--ease), transform .2s var(--ease); }
.sub-menu a { display: block; padding: .6rem 1.25rem; color: #fff; font-size: .875rem; font-weight: 600; }
.sub-menu a:hover { background: var(--brand); color: #fff; }
.primary-menu > li:hover > .sub-menu, .primary-menu > li:focus-within > .sub-menu, .primary-menu > li.is-open > .sub-menu { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
/* Escape hatch: Escape adds this to force-close a :hover/:focus-within-revealed dropdown without
   blurring focus off the page. Same specificity as the reveal rule above but declared after it, so
   it wins the cascade while is-force-closed is present. Scoped to desktop width so it can never
   interact with the mobile accordion block below, which uses display instead of opacity/visibility. */
@media (min-width: 993px) {
  .primary-menu > li.is-force-closed > .sub-menu { opacity: 0; visibility: hidden; }
}
.nav-toggle { display: none; color: #fff; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; }
.nav-toggle .icon { width: 1.75rem; height: 1.75rem; }
.nav-toggle__close { display: none; }

@media (max-width: 1100px) {
  .primary-menu > li > a { padding: .75rem .6rem; }
  .primary-nav { gap: 1rem; }
}
@media (max-width: 992px) {
  .nav-bar__inner { min-height: 70px; }
  .site-logo__img { width: 120px; }
  .nav-toggle { display: inline-flex; }
  .primary-nav { position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 0; background: var(--dark-panel-2); padding: .5rem var(--gutter) 1.5rem; box-shadow: var(--shadow); display: none; max-height: calc(100vh - 110px); overflow-y: auto; }
  .primary-nav.is-open { display: flex; }
  body.nav-open .nav-toggle__open { display: none; }
  body.nav-open .nav-toggle__close { display: block; }
  .primary-menu { flex-direction: column; gap: 0; }
  .primary-menu > li { display: grid; grid-template-columns: 1fr auto; align-items: center; border-bottom: 1px solid rgba(255,255,255,.08); }
  .primary-menu > li > a { flex-direction: row; justify-content: flex-start; gap: .75rem; padding: .9rem 0; font-size: .875rem; }
  .menu-chevron { display: none; }
  .submenu-toggle { display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; color: #fff; }
  .submenu-toggle .icon { transition: transform .2s var(--ease); }
  .submenu-toggle[aria-expanded="true"] .icon { transform: rotate(180deg); }
  .sub-menu { position: static; transform: none; opacity: 1; visibility: visible; box-shadow: none; border-top: 0; min-width: 0; padding: 0 0 .5rem 2.25rem; grid-column: 1 / -1; display: none; }
  .primary-menu > li.is-open > .sub-menu { display: block; }
  .sub-menu a { padding: .5rem 0; }
  .btn--dojo { margin-top: 1rem; align-self: flex-start; }
}
@media (max-width: 640px) {
  .utility-bar__text { font-size: .75rem; }
  .social--utility { display: none; }
}

/* ==== 04-footer.css ==== */
/* Newsletter band */
.newsletter { position: relative; padding-block: clamp(2.5rem, 6vw, 4.5rem); background: var(--dark-panel-2) var(--newsletter-bg) center / cover no-repeat; isolation: isolate; }
.newsletter::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(20,18,20,.35), rgba(191,0,0,.55)); z-index: -1; }
.newsletter__card { max-width: 700px; margin-inline: auto; background: var(--dark-panel-2); color: #fff; padding: clamp(1.5rem, 4vw, 2.5rem); border-radius: var(--radius); box-shadow: var(--shadow); }
.newsletter__title { font-size: clamp(1.25rem, 2.5vw, 1.625rem); margin-bottom: .5rem; }
.newsletter__text { font-size: .9375rem; color: var(--on-dark-muted); margin-bottom: 1.25rem; }
.bb-form--inline .bb-form__grid { display: flex; gap: 0; }
.bb-form--inline .bb-field--email { flex: 1; margin: 0; }
.bb-form--inline .bb-field--email input { height: 2.75rem; border-radius: 3px 0 0 3px; border: 0; }
.bb-form--inline .bb-field--submit { margin: 0; }
.bb-form--inline .bb-field--submit .btn { height: 2.75rem; border-radius: 0 3px 3px 0; white-space: nowrap; }
@media (max-width: 480px) {
  .bb-form--inline .bb-form__grid { flex-direction: column; gap: .5rem; }
  .bb-form--inline .bb-field--email input, .bb-form--inline .bb-field--submit .btn { border-radius: 3px; width: 100%; }
}

/* Newsletter band via CF7 (bb_newsletter_embed override): reproduce the same
   flush white-input/red-button bar as .bb-form--inline above. CF7's own
   `wpcf7_autop_or_not` filter (in inc/bridge.php) keeps the Newsletter Signup
   form's markup to just the field + button, no wrapping <p>/<br>. */
.bb-newsletter-embed .wpcf7-form { display: flex; flex-wrap: wrap; gap: 0; }
.bb-newsletter-embed .wpcf7-form-control-wrap { flex: 1; min-width: 0; }
.bb-newsletter-embed input.wpcf7-email { display: block; width: 100%; height: 2.75rem; margin: 0; padding: .55rem .75rem; background: #fff; color: var(--ink); border: 0; border-radius: 3px 0 0 3px; font-family: var(--font); font-size: .9375rem; appearance: none; -webkit-appearance: none; }
.bb-newsletter-embed input.wpcf7-email::placeholder { color: #777; font-style: italic; }
.bb-newsletter-embed input.wpcf7-submit { flex: none; display: inline-flex; align-items: center; justify-content: center; gap: .5rem; height: 2.75rem; margin: 0; padding: .5rem 1.5rem; border: 0; border-radius: 0 3px 3px 0; background: var(--brand); color: #fff; font-family: var(--font); font-size: .8125rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; line-height: 1.2; white-space: nowrap; cursor: pointer; appearance: none; -webkit-appearance: none; transition: background .2s var(--ease); }
.bb-newsletter-embed input.wpcf7-submit:hover { background: var(--brand-dark); }
.bb-newsletter-embed .wpcf7-spinner { flex: none; margin: 0 0 0 .5rem; }
.bb-newsletter-embed .wpcf7-response-output { flex-basis: 100%; margin: .75rem 0 0; padding: .4rem .75rem; border-radius: 3px; font-size: .8125rem; background: rgba(255,255,255,.12); color: #fff; border: 1px solid rgba(255,255,255,.3); }
@media (max-width: 480px) {
  .bb-newsletter-embed .wpcf7-form { flex-direction: column; gap: .5rem; }
  .bb-newsletter-embed input.wpcf7-email, .bb-newsletter-embed input.wpcf7-submit { border-radius: 3px; width: 100%; }
}

/* Footer */
.site-footer { background: var(--dark-panel-2); color: #fff; }
.site-footer a { color: var(--on-dark-muted); }
.site-footer a:hover { color: #fff; }
.site-footer__inner { display: grid; grid-template-columns: 300px 1fr; gap: 3rem; padding-block: clamp(2.5rem, 6vw, 4rem); }
.site-footer__logo { width: 150px; margin-bottom: 1rem; }
.site-footer__tag { font-size: 1.125rem; line-height: 1.4; margin-bottom: 2rem; }
.site-footer__call { font-size: 1.375rem; font-weight: 600; }
.site-footer__phone { font-size: 1.5rem; font-weight: 600; color: #fff; }
.site-footer__legal { display: flex; gap: 1.25rem; list-style: none; margin: 0; padding: 0; font-size: .8125rem; }
.site-footer__cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2rem 1.5rem; }
.footer-col__title { font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin-bottom: .75rem; color: #fff; }
.footer-menu { list-style: none; margin: 0; padding: 0; font-size: .875rem; }
.footer-menu li { margin-bottom: .35rem; }
.footer-col--hours { grid-column: 1 / span 2; }
.footer-col--social { grid-column: 3 / span 2; }
.hours { margin: 0; font-size: .875rem; color: var(--on-dark-muted); }
.hours__row { display: grid; grid-template-columns: 130px 1fr; gap: .5rem; margin-bottom: .35rem; }
.hours dt, .hours dd { margin: 0; }
.site-footer__wide { margin-top: 2rem; padding-top: 2rem; border-top: 1px solid rgba(255, 255, 255, .1); }
.footer-col--wide + .footer-col--wide { margin-top: 1.5rem; }
.site-footer__bar { background: var(--brand-dark); font-size: .75rem; }
.site-footer__bar a { color: #fff; text-decoration: underline; }
.site-footer__bar-inner { display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem 1.5rem; min-height: 40px; align-items: center; }
.site-footer__bar p { margin: 0; }
@media (max-width: 992px) {
  .site-footer__inner { grid-template-columns: 1fr; gap: 2rem; }
  .site-footer__cols { grid-template-columns: repeat(2, 1fr); }
  .footer-col--hours, .footer-col--social { grid-column: auto; }
}
@media (max-width: 480px) {
  .site-footer__cols { grid-template-columns: 1fr; }
  .site-footer__bar-inner { justify-content: center; text-align: center; }
}

/* ==== 05-widgets.css ==== */
/* Slider */
.slider { position: relative; }
.slider__track { display: flex; gap: 1.5rem; transition: transform .45s var(--ease); will-change: transform; }
/* padding-block + matching negative margin-block (not plain overflow:hidden):
   the home-cards slider scales its active slide via transform (see
   .slider__slide:nth-child(3n+2) .home-card in 07-pages.css), which paints ~6px
   outside the slide's untransformed layout box on each of the top/bottom
   edges (4% of the 300px card height). overflow-x/y split doesn't fix this --
   per spec, overflow-y:visible with overflow-x:hidden computes to auto, and
   auto still clips paint to the box (it only skips the clip for scrollable
   content, and CSS transforms never contribute scrollable overflow, so no
   scrollbar ever appears either way). The actual fix is to give the clip box
   itself 8px of headroom above and below via padding, then cancel that
   padding's layout impact with an equal negative margin so nothing else on
   the page shifts. Horizontal clipping (needed to hide the off-screen slides
   during the translateX() transition) is unaffected. */
.slider__viewport { overflow: hidden; padding-block: 8px; margin-block: -8px; }
.slider__slide { min-width: 0; }
.slider__prev, .slider__next { position: absolute; top: 50%; transform: translateY(-50%); width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--ink); color: #fff; display: inline-flex; align-items: center; justify-content: center; z-index: 2; box-shadow: var(--shadow-sm); }
.slider__prev { left: -2.5rem; } .slider__next { right: -2.5rem; } /* matches --gutter's cap (2.5rem) so the round arrows never reach past the .container's own gutter and clip it (measured: was 48px vs a 40px gutter cap at >=1320px) */
.slider__prev:disabled, .slider__next:disabled { opacity: .3; cursor: default; }
.slider__prev .icon, .slider__next .icon { width: 1.1rem; height: 1.1rem; }
.slider__dots { display: flex; justify-content: center; gap: .5rem; margin-top: 1.5rem; }
.slider__dots button { width: .6rem; height: .6rem; border-radius: 50%; background: var(--grey); }
.slider__dots button[aria-current="true"] { background: var(--brand); }
.section--dark .slider__dots button, .section--black .slider__dots button { background: rgba(255,255,255,.5); }
.section--dark .slider__dots button[aria-current="true"], .section--black .slider__dots button[aria-current="true"] { background: var(--brand); }
@media (max-width: 1320px) { .slider__prev { left: -.5rem; } .slider__next { right: -.5rem; } }

/* Lightbox */
.lightbox { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 1rem; }
.lightbox[hidden] { display: none; }
.lightbox__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.85); }
.lightbox__body { position: relative; width: min(100%, 1000px); }
.lightbox__frame { position: relative; aspect-ratio: 16 / 9; background: #000; box-shadow: var(--shadow); }
.lightbox__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.lightbox__close { position: absolute; top: -2.5rem; right: 0; color: #fff; font-size: 2rem; line-height: 1; }
body.lightbox-open { overflow: hidden; }

/* Audio player */
.player { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: .75rem; background: #000; color: #fff; padding: .5rem .75rem; border-radius: 4px; }
.player__play { width: 2.25rem; height: 2.25rem; display: inline-flex; align-items: center; justify-content: center; color: #fff; }
.player__play .icon { width: 1.5rem; height: 1.5rem; }
.player__pause { display: none; }
.player.is-playing .player__play-icon { display: none; }
.player.is-playing .player__pause { display: block; }
.player__time { font-size: .75rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.player__seek { width: 100%; accent-color: var(--brand); grid-column: 1 / -1; margin: 0; }
.player__speed, .player__mute { font-size: .75rem; color: #fff; }
.player__mute .icon { width: 1.1rem; height: 1.1rem; }
.player--compact { grid-template-columns: auto 1fr auto; }
.player--compact .player__speed { display: none; }

/* Forms */
.bb-form__grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: .75rem; }
.bb-field { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.bb-field--full { grid-column: span 8; }
.bb-field--three-quarter { grid-column: span 6; }
.bb-field--half { grid-column: span 4; }
.bb-field--quarter { grid-column: span 2; }
.bb-field--eighth { grid-column: span 1; }
.bb-field--submit { grid-column: span 8; display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 1rem; flex-wrap: wrap; }
/* :not([type=submit]) too: the built-in forms' own submit control is always a <button> (never
   matched by this input selector to begin with), but a CF7-embedded form reusing these .bb-field
   classes (see 07-pages.css's .bb-contact-embed) renders [submit] as <input type="submit">, which
   :not([type=checkbox]) alone still matched -- overriding that button's .btn--primary background/
   color with this rule's higher-specificity white-input styling. */
.bb-field input:not([type=checkbox]):not([type=submit]), .bb-field select, .bb-field textarea { width: 100%; padding: .55rem .75rem; background: #fff; color: var(--ink); border: 1px solid var(--border); border-radius: 3px; font-size: .9375rem; }
.bb-field input::placeholder, .bb-field textarea::placeholder { color: #777; font-style: italic; }
.bb-field__label { font-size: .75rem; font-weight: 600; }
.bb-field--text .bb-field__label, .bb-field--email .bb-field__label, .bb-field--tel .bb-field__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.bb-field--checkbox { justify-content: center; }
.bb-field__check { display: flex; gap: .5rem; align-items: flex-start; font-size: .8125rem; line-height: 1.35; cursor: pointer; }
.bb-field__check input { margin-top: .2em; accent-color: var(--brand); }
.bb-field--error input, .bb-field--error select, .bb-field--error textarea { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(227,2,32,.25); }
.bb-field__error { font-size: .75rem; color: #ffd5d9; }
.bb-form__notice { padding: .75rem 1rem; border-radius: 3px; font-weight: 600; }
.bb-form__notice--success { background: #e8f7ec; color: #1f6b3a; }
.bb-form__notice--error { background: #fde8ea; color: var(--brand-dark); }
.bb-form__footnote { font-size: .75rem; margin: 0; flex: 1; }
.bb-form__hp { position: absolute; left: -9999px; }
.bb-form__form { position: relative; }
.bb-form__form.is-submitting { opacity: .7; }
@media (max-width: 992px) {
  .bb-field--quarter { grid-column: span 4; }
  .bb-field--eighth { grid-column: span 2; }
  .bb-field--three-quarter { grid-column: span 8; }
}
@media (max-width: 640px) {
  .bb-field--half, .bb-field--quarter, .bb-field--eighth { grid-column: span 8; }
  .bb-field--submit { justify-content: stretch; }
  .bb-field--submit .btn { width: 100%; }
}

/* ==== 06-components.css ==== */
/* Hero */
.hero { position: relative; color: #fff; background: var(--dark-panel-2) var(--hero-bg) center / cover no-repeat; isolation: isolate; padding-block: clamp(3rem, 8vw, 6rem) clamp(4rem, 10vw, 8rem); }
.hero::before { content: ""; position: absolute; inset: 0; z-index: -1; }
.hero--overlay-mixed::before { background: var(--overlay); }
.hero--overlay-dark::before { background: var(--overlay-dark); }
.hero--overlay-red::before { background: var(--overlay-red); }
.hero__inner { position: relative; }
.hero--center .hero__content { text-align: center; margin-inline: auto; max-width: 900px; }
.hero--left .hero__content { max-width: 640px; }
.hero__eyebrow { display: block; font-size: clamp(1.125rem, 2vw, 1.5rem); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.hero__title { margin-bottom: .35em; text-shadow: 0 2px 12px rgba(0,0,0,.35); }
.hero__sub { font-size: clamp(1.125rem, 2vw, 1.375rem); font-weight: 600; margin-bottom: .5em; }
.hero__text { font-size: .9375rem; max-width: 560px; color: var(--on-dark-muted); }
.hero--center .hero__text { margin-inline: auto; }
.hero__buttons { margin-top: 1.25rem; }
.hero--center .hero__buttons { justify-content: center; }
.hero--tall { min-height: 560px; display: flex; align-items: center; }
.hero.curve-bottom::after { z-index: 1; }

/* Red callout card (overlaps hero bottom). */
.callout { position: relative; z-index: 2; max-width: 900px; margin: calc(-1 * clamp(6rem, 14vw, 10rem)) auto 0; background: linear-gradient(180deg, var(--brand-dark) 0%, var(--ink) 100%); color: #fff; text-align: center; padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1.25rem, 5vw, 3rem); border-radius: var(--radius); box-shadow: var(--shadow); }
/* .hero--with-callout (About page) also stacks a two-line hero__title +
   hero__sub above the callout in the same flow column. The generic pull-up
   above assumes nothing but empty hero padding sits above the callout
   (true for the landing/success-stories heroes it was designed for); here
   it dragged the callout up into the title text itself -- measured with
   getBoundingClientRect() at every matrix viewport, the callout's top
   landed above hero__title/hero__sub's own bottom edge every time, by as
   much as 93px at 1920. Tuning the pull-up/padding numbers to dodge that
   empirically chased a moving target (they interact non-linearly with
   hero__content's height, which itself changes with viewport-driven line
   wrapping). Anchoring the card to the SECTION's own bottom edge instead
   removes the dependency on hero__content's height entirely: it can never
   collide with the title above it, and it straddles the hero/next-section
   boundary the way the mockup shows (half the card in the dark hero
   padding, half poking into the page background below), matching the
   generic .callout's job (a card overlapping the hero bottom) without the
   generic rule's assumption.

   One more trap: .hero__inner itself has `position: relative` (a base rule
   other hero layouts rely on), and it sits INSIDE .hero--with-callout --
   so it, not the section, is the callout's actual containing block once
   the callout is taken out of flow. Once out of flow the callout no longer
   contributes to hero__inner's height either, so hero__inner shrinks to
   just hero__content's height. `bottom` has to reach past BOTH
   hero__inner's now-collapsed box AND back out through the section's own
   padding-bottom to land at the section's true bottom edge -- hence the
   shared --callout-reserve custom property below instead of two numbers
   that would silently drift apart.

   Below ~1150px the straddle is dropped in favour of plain static flow.
   hero__title wraps onto more lines as the column narrows (measured: the
   title+sub block grows from ~184px tall at 1024px wide to ~254px at
   375px, non-monotonically, since the exact wrap points depend on the
   actual copy) while --callout-reserve, being viewport-width-driven, can
   only shrink over that same range -- there's no single clamp() that
   tracks text-wrap height, so trying to keep the absolute/straddle
   positioning down to 375px means either picking a reserve generous
   enough for the worst-case wrap (leaving a large dead gap at the viewport
   widths that wrap less) or accepting the collision this whole rule exists
   to avoid. Static flow with a small fixed gap has no such failure mode:
   the callout always renders wherever hero__content's box actually ends,
   whatever that height turns out to be, at any width. */
.hero--with-callout { position: relative; --callout-reserve: clamp(10rem, 18vw, 14rem); padding-bottom: var(--callout-reserve); }
.hero--with-callout .callout { position: absolute; left: 50%; right: auto; bottom: calc(-1 * (var(--callout-reserve) + clamp(2.5rem, 5vw, 4rem))); width: min(900px, calc(100% - 2 * var(--gutter))); margin: 0; transform: translateX(-50%); }
@media (max-width: 1150px) {
  .hero--with-callout { padding-bottom: clamp(3rem, 6vw, 4rem); }
  .hero--with-callout .callout { position: static; width: auto; transform: none; margin: 1.5rem auto 0; }
}
.callout__title { font-size: clamp(1.25rem, 2.6vw, 1.75rem); font-weight: 700; margin-bottom: .75rem; }
.callout__text { font-size: .9375rem; margin: 0; color: var(--on-dark-muted); }
.callout--solid { background: var(--brand-dark); border-radius: 4px; }
.callout--solid .callout__title { margin: 0; font-size: clamp(1.125rem, 2.2vw, 1.5rem); }

/* CTA band: photo left, panel right. Same underlap treatment as
   .pill-feature (home page): the mockup's panel is a full stadium whose
   near (left) end is tucked entirely under the photo, not a diagonally
   clipped rectangle merely touching it -- confirmed against
   about-black-belt.png ("The Best Time to Get Started"/"Join Others"/"Let's
   Do This" rows) and success-stories.png ("Get Inspired"). The panel's
   background lives on an oversized ::before reaching back under the media
   column so the panel's own padding/text position stays put; the photo
   (position:relative, z-index:2) always paints on top. */
.cta-band { padding-block: 1.5rem; }
.cta-band__inner { display: grid; grid-template-columns: 50% 1fr; align-items: center; }
.cta-band__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px; box-shadow: var(--shadow); position: relative; z-index: 2; }
.cta-band__panel { position: relative; isolation: isolate; background: none; color: #fff; padding: clamp(2rem, 5vw, 3.5rem) clamp(1.5rem, 5vw, 4rem) clamp(2rem, 5vw, 3.5rem) clamp(4rem, 9vw, 7rem); }
.cta-band__panel::before { content: ""; position: absolute; z-index: -1; inset: 0; left: -38%; background: var(--dark-panel-2) linear-gradient(135deg, rgba(255,255,255,.06), transparent 40%); border-radius: var(--pill); }
.cta-band__title { text-transform: uppercase; font-size: clamp(1.25rem, 2.4vw, 1.75rem); }
.cta-band__text { font-size: .9375rem; color: var(--on-dark-muted); }
@media (max-width: 768px) {
  .cta-band__inner { grid-template-columns: 1fr; }
  .cta-band__panel { margin: -1.5rem 1rem 0; padding: 2.5rem 1.5rem 2rem; }
  .cta-band__panel::before { left: 0; right: 0; border-radius: 6px; }
}

/* Dark centered CTA. .curve-top::before carries a blanket z-index:1 (see
   02-base.css) so it paints above this section's own non-positioned title,
   which sits close enough to the top (normal .section padding) to fall
   within the curve's reach at its deepest (centre) point -- a real, visible
   text-obscuring collision, confirmed via getComputedStyle measurement
   (title 88px from the section top vs. the curve's 120px max reach at
   1920px). isolation: isolate scopes the fix to this section only, and
   z-index: -1 puts the curve behind ALL of this section's own normal-flow
   content (per CSS stacking order, a merely-unset/auto z-index on an
   absolutely positioned pseudo still paints above non-positioned content --
   only a negative z-index, in a locally isolated stacking context, reliably
   sits behind it). */
.dark-cta { background: radial-gradient(ellipse at top, #3a353a, var(--dark-panel-2) 60%); isolation: isolate; }
.dark-cta.curve-top::before { z-index: -1; }
/* The z-index fix above only fixed STACKING order -- it made the curve paint behind the title
   instead of in front of it, but never addressed the actual GEOMETRY collision the comment above
   already measured (title 88px from the section top vs. the curve's up-to-120px reach). With the
   curve now behind the title, the visible symptom changed shape rather than disappearing: the
   curve's fill is var(--bg), the near-white page background (#F3F4F5), so the title's white text
   is still there and still fully painted, but wherever the curve's near-white fill sits directly
   behind a letter, white-on-near-white has almost no contrast -- reading as "top of the letters
   missing", confirmed both by screenshot and by getComputedStyle (curve height 115px at 1440px
   almost exactly matching the title's 88px offset, i.e. genuinely overlapping, not just close).
   Push this section's content down past the curve's own maximum reach so the title never enters
   that region at any viewport, instead of only content that can be scoped, keeps this local to
   .dark-cta (padding-top overrides only the top half of the .section padding-block shorthand;
   bottom spacing is untouched), and stays in lockstep with the curve's own clamp() so neither can
   drift out of sync with the other again. */
.dark-cta.curve-top { padding-top: calc(clamp(40px, 8vw, 120px) + 1.5rem); }
.dark-cta__text { font-size: .9375rem; color: var(--on-dark-muted); margin-bottom: 1.5rem; }

/* Testimonials. Uses --testimonials-bg (not the shared --bg token) for its
   own photo: --bg is reused all over the theme as "this component's own
   background image" (home-card, training-card, breakthrough, podcast-card
   all do the same), which is harmless UNTIL a component also wants the
   *global* --bg page-background-color token for something else in its own
   subtree -- which .testimonials--cards does, for its curve-top dome
   below. A same-named custom property set inline on this element would
   shadow the global one for that pseudo too, silently handing it the
   photo URL instead of a plain color. */
.testimonials { position: relative; padding-block: var(--section); background: var(--dark-panel-2) var(--testimonials-bg) center / cover no-repeat; isolation: isolate; color: #fff; }
.testimonials::before { content: ""; position: absolute; inset: 0; background: rgba(20,18,20,.8); z-index: -1; }
/* Optional lead paragraph between the heading and the slider; only the home page passes one. */
.testimonials__lead { max-width: 62ch; margin: 0 auto 2.5rem; color: var(--on-dark-muted); font-size: .9375rem; }
/* Wholesaling's "Real Words / From Real People" band (wholesale.png,
   landing.php's only .testimonials--cards use). Pixel-scanned against the
   mockup: the TOP edge is a genuine, pronounced dome (~95px deep at a
   ~1400px container width -- center vs. edge columns differ by that much,
   confirmed visually as an obvious arc, not a subtle correction), while
   the BOTTOM edge is flat to within a couple of px, same flat treatment
   as the home page's Why band. This is the opposite of assuming a
   pronounced curve is wrong -- here it measures real, so it stays.
   The shared .curve-top/.curve-bottom (02-base.css) can't be reused
   as-is: .curve-top::before collides with this element's OWN ::before
   above (same pseudo slot -- the tint overlay wins on source order,
   silently killing the dome's geometry AND z-index), and both would
   inherit the shadowed --bg photo url rather than the page-background
   color even once that collision is fixed. Rather than restructure the
   shared component (used correctly elsewhere), .testimonials--cards gets
   its own top-only dome here, built on ::after (free -- curve-bottom is
   deliberately not used, since the mockup's bottom is flat) with the
   *global* --bg now safely un-shadowed. z-index: -1 (not the generic
   curve-top's +1) so the dome paints behind this section's own title/
   slider, in front of the photo -- same reasoning as .dark-cta below.
   No -10%/110% bleed here (unlike the shared .curve-top, which relies on
   that bleed to read as a flat, WIDE arc): with the mask sized to exactly
   the section's own width, the corner ellipse's dip runs from 0 at the
   section's own left/right edges up to the full `height` at its centre,
   which is what a genuine, pronounced dome (not a gentle correction)
   actually measures as here.
   padding-top is bumped past the base .testimonials padding (var(--section),
   max 88px) to clear the dome's own max reach (120px at its centre) --
   left at the base value, the dome's deepest point lands ~30px into the
   title text, and since both are white this doesn't read as an opaque
   curve cutting the title off, it reads as the title's own top third
   silently vanishing (white-on-white). The mockup keeps the title well
   clear of the dome the same way. */
.testimonials--cards { position: relative; overflow-x: clip; padding-top: clamp(6rem, 15vw, 10.5rem); }
.testimonials--cards::after { content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: -1px; height: clamp(45px, 9vw, 120px); background: var(--bg); border-radius: 0 0 50% 50% / 0 0 100% 100%; }
.tcard { position: relative; margin: 1.5rem 0 0; background: var(--surface); color: var(--text); padding: 2.5rem 1.5rem 1.75rem; border-radius: var(--radius); text-align: center; height: 100%; box-shadow: var(--shadow); }
.tcard__mark { position: absolute; top: -1.25rem; left: 1rem; width: 3rem; height: 3rem; color: var(--brand); }
.tcard__name { display: block; font-style: normal; font-weight: 700; font-size: 1.25rem; margin-bottom: .75rem; }
.tcard__text { font-size: .875rem; color: var(--text-muted); margin: 0; }
.tred { margin: 0 auto; max-width: 760px; background: linear-gradient(180deg, var(--brand-dark), #5a0000); padding: clamp(2rem, 5vw, 3rem); border-radius: var(--radius); text-align: center; box-shadow: var(--shadow); }
.tred__headline { font-size: clamp(1.25rem, 2.6vw, 1.75rem); font-weight: 700; margin-bottom: 1rem; }
.tred__avatar { display: inline-flex; width: 3.5rem; height: 3.5rem; border-radius: 50%; background: #fff; color: var(--ink); align-items: center; justify-content: center; overflow: hidden; margin-bottom: .5rem; }
.tred__avatar .icon { width: 1.75rem; height: 1.75rem; }
.tred__avatar img { width: 100%; height: 100%; object-fit: cover; }
.tred__name { display: block; font-style: normal; font-weight: 700; font-size: 1.125rem; margin-bottom: .75rem; }
.tred__text { font-size: .875rem; color: var(--on-dark-muted); margin: 0; }

/* Post card */
.post-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }
.post-card { display: flex; flex-direction: column; border-radius: 6px; overflow: hidden; box-shadow: var(--shadow-sm); background: var(--surface); }
.post-card__head { background: var(--dark-panel-2); color: #fff; padding: 1rem 1.25rem .75rem; }
/* min-height reserves two lines (2 x the 1.15 heading line-height) whether the title needs them or
   not, so the black head is the same height across a row and the image tops line up -- blog.png
   shows them aligned. Without it a one-line title made a shorter head and a taller image, and every
   row of the seeded grid mixes one- and two-line titles. A rare three-line title still grows the
   head rather than being clamped, which would truncate a real headline. */
.post-card__title { font-size: 1.125rem; margin-bottom: .35rem; min-height: 2.3em; }
.post-card--featured .post-card__title { min-height: 0; }
.post-card__title a { color: #fff; }
.post-card__date { display: inline-flex; align-items: center; gap: .35rem; color: var(--brand-on-dark); font-size: .75rem; font-weight: 600; }
/* flex: 1 (not a fixed aspect-ratio) so the photo absorbs whatever leftover height its own card
   picked up from .post-grid's grid row stretch -- e.g. a 1-line title next to a 2-line title in
   the same row previously left a blank gap below the shorter card's photo/button instead of the
   photo growing to fill it (reported live on /blog/: "From Rat Race..." (2-line) vs "Your First 90
   Days..." (1-line)). object-fit: cover already crops any resulting box cleanly, which is the
   whole point of that property, so there's no visual cost to letting the height vary per row.
   min-height keeps the photo from being squeezed away to nothing if a title ever wraps to 3+ lines. */
.post-card__media { position: relative; display: block; flex: 1 1 0; min-height: 160px; }
.post-card__media img { width: 100%; height: 100%; object-fit: cover; }
.post-card__more { position: absolute; right: 1rem; bottom: 1rem; }
.post-card--featured { display: grid; grid-template-columns: 45% 1fr; box-shadow: var(--shadow); }
.post-card--featured .post-card__media { aspect-ratio: auto; min-height: 320px; order: -1; }
.post-card--featured .post-card__head { padding: clamp(1.5rem, 4vw, 2.5rem); display: flex; flex-direction: column; justify-content: center; gap: .5rem; }
.post-card--featured .post-card__title { font-size: clamp(1.25rem, 2.4vw, 1.625rem); }
.post-card--featured .post-card__date { font-size: 1rem; order: -1; }
.post-card--featured .post-card__more { position: static; align-self: flex-start; margin-top: 1rem; }
@media (max-width: 992px) { .post-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .post-grid, .post-card--featured { grid-template-columns: 1fr; } }

/* Event row. Mockup: every row (not just the featured one) is its own
   "pill" card -- a light surface with a big rounded RIGHT edge, photo flush
   at the sharp-cornered left, spanning the row's full width. The build
   used to give only .event-row--featured that treatment and render plain
   rows underneath as a divider-line list with a small pill badge on just
   the date column -- a coherent alternative, but a clear structural
   deviation from the mockup. Brought regular rows in line with the
   featured row's card treatment (own surface + border-radius, no divider),
   just scaled to the 3-column media/body/date layout. */
.event-list { display: flex; flex-direction: column; gap: 1.25rem; }
/* --surface-2 (#F3F4F5) is IDENTICAL to --bg in light mode -- a card using
   it renders with zero contrast against the page, so the pill shape (or
   even that it's a card at all) is invisible however correct the
   border-radius is. --surface (white) is the one that actually contrasts
   against the light-mode page background, matching the mockup's visibly
   lighter card; dark mode already had the right token (--surface, which
   DOES differ from dark mode's --bg). */
/* event.png: the photo UNDERLAPS the pill -- it overlaps the pill's left
   end rather than sitting flush beside it, the same relationship used by
   the home page's .pill-feature and by .cta-band. The row used to put its
   own background + border-radius directly on .event-row with
   overflow:hidden clipping the photo flush against the pill (a seam, not
   an underlap). Moved the pill's background onto .event-row::before
   instead: since that pseudo is a child of the whole row (not just the
   body column), inset:0 already spans the full row -- including behind
   the media column -- with no left-offset trick needed (unlike
   .pill-feature__body::before, which is scoped to just the body column
   and has to reach back under the media track explicitly). The media
   column then only needs a small negative right margin (into the grid
   gap) plus z-index:2 to paint on top of the now-full-width pill. The
   body needs matching left padding, otherwise its text starts under the
   part of the pill the photo now overlaps -- the plain rows' body had no
   left padding at all (it relied on the grid gap alone), which is exactly
   the space the overlap just ate into. */
.event-row { display: grid; grid-template-columns: 220px 1fr 240px; gap: 1.5rem; align-items: center; padding: 0; position: relative; isolation: isolate; }
.event-row::before { content: ""; position: absolute; z-index: -1; inset: 0; background: var(--surface); border-radius: var(--pill); box-shadow: var(--shadow-sm); }
.event-row__media { position: relative; z-index: 2; margin-right: -1.75rem; }
.event-row__media img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px; box-shadow: var(--shadow); display: block; }
.event-row__body { padding: 1.25rem 0 1.25rem 1.75rem; }
.event-row__title { font-size: 1.25rem; }
.event-row__title a { color: var(--text); }
.event-row__excerpt { font-size: .9375rem; color: var(--text-muted); }
/* event.png rules a vertical divider between the body and the date column. It was the one piece of
   the mockup's row still missing after the card treatment landed. Inset from the pill's top and
   bottom edges (via the shorter padding) rather than running the full height, as in the mockup.
   Reset on the featured row, whose date block sits inline above the title, and below 768px, where
   the date is no longer a third column beside the body. */
.event-row__date { background: none; border: 0; border-left: 1px solid var(--border); padding: 1.25rem 1.5rem 1.25rem 1.5rem; display: flex; flex-direction: column; gap: .15rem; }
.event-row__year { font-size: .875rem; font-weight: 600; }
.event-row__day { font-size: 1.75rem; font-weight: 900; line-height: 1.1; margin-bottom: .25rem; }
.event-row__meta { display: flex; align-items: center; gap: .35rem; font-size: .75rem; color: var(--text-muted); }
.event-row__meta .icon { color: var(--brand); }
.event-row--featured { grid-template-columns: 1fr 1fr; border: 0; padding: 0; }
.event-row--featured .event-row__media { margin-right: -2.5rem; }
.event-row--featured .event-row__media img { aspect-ratio: 16 / 11; border-radius: 6px; }
.event-row--featured .event-row__body { padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1.5rem, 4vw, 2.5rem) clamp(1.5rem, 4vw, 2.5rem) clamp(2.75rem, 6vw, 4rem); }
.event-row--featured .event-row__title { font-size: clamp(1.25rem, 2.4vw, 1.625rem); }
.event-row--featured .event-row__date { background: none; border: 0; border-left: 0; padding: 0 0 .75rem; flex-direction: row; flex-wrap: wrap; gap: .25rem 1.25rem; align-items: baseline; }
/* The 999px "pill" radius reads as a big, elegant curve on a wide, short
   row (desktop 3-column). Once the row gets narrower/taller than it is
   wide -- the 2-column layout below 992px, and especially the fully
   stacked single column below 640px -- that same radius swallows a large
   fraction of the box and reads as a jarring, near-circular blob instead
   of a curve, not a graceful shrink of the desktop shape. A fixed, modest
   radius (matching the site's normal card radius) at both of those
   breakpoints keeps the "rounded card" language without the blob. The
   underlap is dropped too (margin-right reset to 0) -- per this task's
   own constraints, overlaps should be dropped rather than carried into a
   stacked/narrow layout where the photo's own shape and the row's 2-row
   span would fight each other. */
@media (max-width: 992px) {
  .event-row, .event-row--featured { grid-template-columns: 1fr 1fr; }
  .event-row::before { border-radius: var(--radius); }
  .event-row__media, .event-row--featured .event-row__media { grid-row: span 2; margin-right: 0; }
  /* The date stops being a third column beside the body here, so the divider would rule against
     nothing -- it would sit under the body rather than between body and date. */
  .event-row__date { border-left: 0; padding-left: 0; }
}
@media (max-width: 640px) {
  .event-row, .event-row--featured { grid-template-columns: 1fr; }
  .event-row::before { border-radius: var(--radius); }
  .event-row__media { grid-row: auto; }
  .event-row__date { border-radius: 6px; }
}

/* Video card */
.video-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.video-card { background: var(--dark-panel-2); color: #fff; border-radius: 10px; overflow: hidden; box-shadow: var(--shadow-sm); }
.video-card__link { display: block; color: #fff; }
.video-card__media { position: relative; display: block; aspect-ratio: 16 / 9; background: #000; }
.video-card__media img { width: 100%; height: 100%; object-fit: cover; }
.video-card__play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; }
.video-card__play .icon { width: 3.5rem; height: 3.5rem; filter: drop-shadow(0 2px 8px rgba(0,0,0,.6)); transition: transform .2s var(--ease); }
.video-card__link:hover .video-card__play .icon { transform: scale(1.12); }
.video-card__duration { position: absolute; right: .5rem; bottom: .5rem; background: rgba(0,0,0,.8); font-size: .75rem; padding: .1rem .4rem; border-radius: 3px; }
.video-card__title { display: block; padding: .75rem 1rem 1rem; font-size: 1rem; font-weight: 600; }
@media (max-width: 992px) { .video-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .video-grid { grid-template-columns: 1fr; } }

/* Podcast card */
.podcast-card { border-radius: 8px; overflow: hidden; color: #fff; background: var(--dark-panel-2); box-shadow: var(--shadow-sm); }
.podcast-card__head { display: grid; grid-template-columns: 1fr auto; align-items: center; background: var(--brand-dark); padding: 1rem 1.25rem; gap: .25rem 1rem; }
.podcast-card__num { font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; grid-column: 1; }
.podcast-card__title { margin: 0; font-size: 1.125rem; grid-column: 1; }
.podcast-card__title a { color: #fff; }
.podcast-card__icon { grid-column: 2; grid-row: 1 / span 2; width: 2.25rem; height: 2.25rem; }
.podcast-card__body { position: relative; padding: 1.25rem; background: linear-gradient(rgba(20,18,20,.85), rgba(20,18,20,.85)), var(--bg) center / cover; }
.podcast-card__text { font-size: .8125rem; color: var(--on-dark-muted); }
.podcast-card--featured .podcast-card__head { padding: 1.5rem 1.75rem; }
.podcast-card--featured .podcast-card__title { font-size: 1.5rem; }
.podcast-card--featured .podcast-card__body { padding: 1.75rem; min-height: 280px; display: flex; flex-direction: column; justify-content: space-between; gap: 1rem; }
.podcast-card--featured .podcast-card__text { font-size: .9375rem; }

/* Press logos */
.press { display: flex; flex-wrap: wrap; gap: 1rem 2rem; list-style: none; margin: 2.5rem 0 0; padding: 0; align-items: center; opacity: .85; }
.press__img { max-height: 28px; width: auto; filter: brightness(0) invert(1); }
.press__text { font-weight: 900; font-size: .9375rem; letter-spacing: .02em; text-transform: uppercase; color: #fff; }

/* Filter bar (events + blog) */
.filter-bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem 2rem; margin-bottom: 2rem; }
.filter-bar__group { display: flex; flex-direction: column; gap: .25rem; }
.filter-bar__label { font-size: .8125rem; font-weight: 700; }
.filter-bar select { font-size: .75rem; padding: .25rem 1.5rem .25rem .5rem; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); color: var(--text); }
.filter-bar__search { margin-left: auto; display: flex; border: 1px solid var(--border); border-radius: 3px; background: var(--surface); min-width: 280px; }
.filter-bar__search input { flex: 1; border: 0; background: none; padding: .4rem .75rem; font-size: .8125rem; font-style: italic; color: var(--text); }
.filter-bar__search button { padding: 0 .75rem; color: var(--text); }
@media (max-width: 640px) { .filter-bar__search { margin-left: 0; width: 100%; min-width: 0; } }

/* Icon tiles + feature columns (home). Mockup: a narrower centred group
   (not edge-to-edge), larger corner radius, uppercase labels, larger icon
   centred against the two text lines. The row also straddles the dark
   band's own bottom edge (confirmed against home.png -- the tiles sit
   mostly inside the band but their own bottom ~25% renders on the page
   background below it). A negative margin-bottom on .tiles pulls the row
   down past .why's own padding box; since .why has no overflow: hidden,
   the tile row's true rendered position (unaffected by the negative
   margin -- only the parent's height calculation shrinks) shows through
   on the light page background, in normal paint order above the band's
   background. Reset to a plain in-flow row once the layout stacks. */
.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; max-width: 940px; margin-inline: auto; margin-bottom: -2.25rem; }
.tile { display: flex; align-items: center; gap: 1rem; background: var(--brand-dark); color: #fff; padding: 2.25rem 1.75rem; min-height: 132px; border-radius: 12px; font-weight: 700; line-height: 1.3; text-transform: uppercase; box-shadow: var(--shadow); }
.tile .icon { width: 3rem; height: 3rem; flex: none; }
@media (max-width: 992px) { .tiles { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .tiles { grid-template-columns: 1fr; } }
@media (max-width: 768px) { .tiles { margin-bottom: 0; } }

/* ==== 07-pages.css ==== */
/* ===== Home ===== */
.hero--home { padding-bottom: clamp(6rem, 12vw, 9rem); }
.home-cards { margin-top: -1rem; }
.home-card { position: relative; min-height: 300px; border-radius: 8px; overflow: hidden; background: var(--dark-panel-2) var(--bg) center / cover; color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem 1.5rem; isolation: isolate; box-shadow: var(--shadow); }
.home-card::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(20,18,20,.35), rgba(20,18,20,.92) 70%); z-index: -1; }
.home-card::after { content: ""; position: absolute; left: 15%; right: 15%; bottom: 0; height: 6px; background: var(--brand); border-radius: 3px 3px 0 0; }
.home-card__title { font-size: 1.375rem; margin-bottom: .5rem; }
.home-card__text { font-size: .9375rem; margin-bottom: 1.25rem; }
/* :nth-child(3n+2) rather than a flat :nth-child(2): with a 3-per-view slider
   the track holds every page's slides at once (see 03-slider.js — it never
   re-renders on go(), it just translateX()s the whole track), so a plain
   nth-child(2) would only ever highlight the 2nd slide overall, i.e. the
   middle card of page 1 and nothing on any later page. 3n+2 hits the middle
   slide of every group of 3 (indices 2, 5, 8, ...) so each page gets its own
   highlighted centre card. */
.slider__slide:nth-child(3n+2) .home-card { transform: scale(1.04); }

.intro-band { padding-block: clamp(2rem, 5vw, 3rem) clamp(5rem, 10vw, 8rem); background: linear-gradient(180deg, #3a353a, var(--dark-panel-2) 70%); }
.intro-band__inner { display: grid; grid-template-columns: 300px 1fr; gap: 3rem; align-items: end; }
/* No radius or frame: this is a transparent cut-out standing on the band's curve, per the mockup.
   The About page keeps the framed, full-background photo (portrait-sensei), which is what its own
   mockup shows -- the two usages deliberately differ. */
.intro-band__portrait img { width: 100%; }
/* Portrait stays bottom-anchored so it stands on the band's curve (as in the mockup); the copy is
   centred against it instead of sharing that bottom edge, which left its optical centre ~83px below
   the portrait's and read as "not centred". */
.intro-band__content { align-self: center; }
.intro-band__text { font-size: .9375rem; color: var(--on-dark-muted); max-width: 750px; padding-bottom: 1rem; border-bottom: 1px solid rgba(255,255,255,.2); }
.intro-band__tagline { font-size: 1.25rem; font-weight: 600; margin: 1rem 0 0; }
/* margin-inline: auto, because the column is now full width while the portrait stays capped at
   240px -- without it the cut-out sits hard against the left edge with the rest of the column empty
   beside it: 103px of gap at 375, 202px at 480 and 467px at 768, where the band is widest before
   the two-column layout takes over. The cap itself is deliberate; only the alignment was missing. */
@media (max-width: 768px) { .intro-band__inner { grid-template-columns: 1fr; } .intro-band__portrait { max-width: 240px; margin-inline: auto; } }

.features { display: grid; gap: 2rem; }
/* Task 37: both ends of the panel are a full stadium (border-radius:
   var(--pill) on all four corners) and the photo overlaps ON TOP of the
   panel's inner end (negative margin on .pill-feature__media, the box
   carrying position:relative + z-index so it paints above the
   unpositioned, z-index:auto panel regardless of DOM order).

   A prior version of this fix got the horizontal half right (photo
   genuinely overlapped the panel's near end by -4rem) but still rendered
   as a hard seam with a dead-straight panel edge, because align-items:
   center made the ROW HEIGHT track whichever of {photo, panel} was
   tallest, and the aspect-ratio-driven photo (308px at this column width)
   was TALLER than the panel's flat 280px min-height. That means the
   panel's own box was a strict vertical subset of the photo's box
   everywhere they overlapped -- there was no y-coordinate left where the
   panel existed but the photo didn't, so 100% of the curve was hidden and
   0% was ever exposed. A stadium cap's own rightmost/leftmost point
   (where it's closest to the OTHER element) sits at the box's vertical
   *centre*; the curve only pulls back toward the flat run as you move
   toward the box's own top/bottom edge. So exposing any of it requires
   the panel to be taller than the photo, not wider underneath it --
   confirmed by pixel-measuring both X:\BlackBelt\Designs\home.png and the
   owner's target crops: the panel is visible as a solid strip above the
   photo, and the photo's own bottom edge runs past the panel's bottom
   edge onto the page background (not the reverse).

   Fixed by decoupling the row height from a single centred track:
   align-items: start seats the panel flush at the row's own top, and
   .pill-feature__media gets a margin-top so the photo starts partway down
   the panel (exposing the panel above it) while its aspect-ratio height
   still carries its bottom edge past the panel's own bottom (the row
   itself grows to fit the taller, offset photo; the panel does not
   stretch to match -- it keeps its own min-height, so the gap between the
   panel's bottom and the row's bottom is just page background, matching
   the mockup's overhang). The horizontal overlap distance didn't need to
   change: the panel's actual near edge (inset 38% of the panel's own
   *width* back of its rounded end) was already tens of px inside the
   photo's span at every viewport -- the seam was 100% a vertical-overlap
   problem, not a horizontal-coverage one. */
.pill-feature { display: grid; grid-template-columns: 32% 1fr; align-items: start; margin-bottom: 2.5rem; }
.pill-feature__media { position: relative; z-index: 2; margin-right: -4rem; margin-top: clamp(3.25rem, 6vw, 4rem); }
.pill-feature__media img { width: 100%; aspect-ratio: 16 / 11; object-fit: cover; border-radius: 6px; box-shadow: var(--shadow); }
/* The panel is a full stadium whose near end is tucked entirely UNDER the
   photo (measured on the mockup: the panel's rounded cap is hidden well
   behind the photo, not merely touching it), so the body element's own
   background moved to an oversized ::before that reaches back under the
   media column while the body's own box (padding, text) stays put -- this
   keeps the title/copy position stable and only moves the decorative panel
   shape. isolation: isolate scopes the z-index: -1 child so it stays behind
   this element instead of escaping to a wider stacking context (same
   pattern as .why::before). The photo (z-index: 2, positioned) always
   paints above it regardless of DOM order. min-height is now a clamp (was
   a flat 280px) so the panel keeps a proportionally similar height/photo-
   height ratio as the fluid photo grows with the viewport, per Task 37. */
.pill-feature__body { position: relative; isolation: isolate; background: none; color: #fff; border-radius: var(--pill); padding: clamp(2rem, 4vw, 3rem) clamp(3rem, 8vw, 6rem) clamp(2rem, 4vw, 3rem) clamp(5rem, 11vw, 8rem); min-height: clamp(17.5rem, 24vw, 21.25rem); display: flex; flex-direction: column; justify-content: center; }
.pill-feature__body::before { content: ""; position: absolute; z-index: -1; inset: 0; left: -38%; background: var(--dark-panel-2) linear-gradient(120deg, rgba(255,255,255,.05), transparent 50%); border-radius: var(--pill); }
.pill-feature__body .btn { align-self: flex-start; }
.pill-feature--reverse { grid-template-columns: 1fr 32%; }
.pill-feature--reverse .pill-feature__media { order: 2; margin-right: 0; margin-left: -4rem; }
.pill-feature--reverse .pill-feature__body { order: 1; text-align: right; padding-left: clamp(3rem, 8vw, 6rem); padding-right: clamp(5rem, 11vw, 8rem); }
.pill-feature--reverse .pill-feature__body::before { left: 0; right: -38%; }
.pill-feature--reverse .pill-feature__body .btn { align-self: flex-end; }
.pill-feature__title { text-transform: uppercase; font-size: clamp(1.25rem, 2.4vw, 1.625rem); }
.pill-feature__text { font-size: .875rem; color: var(--on-dark-muted); }
@media (max-width: 768px) {
  /* Stacked layout: drop the overlap/protrusion entirely (align-items and
     the row-height trick are desktop-only concerns) so the photo can't
     escape its column or cover the panel's text -- margin: 0 zeroes out
     the new margin-top along with the old margin-left/-right overlap. */
  .pill-feature, .pill-feature--reverse { grid-template-columns: 1fr; align-items: stretch; }
  .pill-feature__media, .pill-feature--reverse .pill-feature__media { order: 0; margin: 0; }
  .pill-feature__body, .pill-feature--reverse .pill-feature__body { order: 1; margin: -1.5rem 1rem 0; border-radius: 6px; padding: 2.5rem 1.5rem 2rem; min-height: 0; text-align: left; align-items: stretch; }
  .pill-feature__body::before, .pill-feature--reverse .pill-feature__body::before { left: 0; right: 0; border-radius: 6px; }
  .pill-feature__body .btn, .pill-feature--reverse .pill-feature__body .btn { align-self: flex-start; }
}

/* Task 29B: the band is (nearly) a flat rectangle, not a pronounced arc.
   Re-measured directly against X:\BlackBelt\Designs\home.png with a
   column-by-column pixel scan of the band's top edge across the full
   width: the edge sits at a constant y across the whole centre span and
   only eases down a handful of pixels right at the two far corners -- the
   Task 29C "55px bow" reading was from a misleading cropped reference, not
   the actual mockup export. A small corner radius reproduces that eased
   corner without a dramatic lens/arc.
   No overflow: hidden here -- the mockup's four tiles straddle the band's
   own bottom edge (confirmed against home.png: roughly the tile's bottom
   fifth sits on the page background below the band, not inside it). The
   background above is applied directly to .why (not an oversized child), so
   it's still clipped to the border-radius natively without needing
   overflow; only .tiles' own negative margin-bottom (below, in
   06-components.css) needs the section to allow content past its padding
   box. padding-bottom is cut down from the generic .section value to a
   small fixed amount -- otherwise that padding alone (48-88px) would
   exceed the tiles' negative margin and the band would still fully
   contain them, cancelling the effect. */
.why { position: relative; border-radius: 12px; padding-bottom: 1rem; background: linear-gradient(rgba(20,18,20,.8), rgba(20,18,20,.8)), var(--dark-panel-2) var(--why-photo) center / cover; }
.why__title { font-size: clamp(1.5rem, 3vw, 2rem); }
.why__text { font-size: .875rem; max-width: 700px; margin: 0 auto 2rem; color: var(--on-dark-muted); }

/* Task 29D: the tile row (.tiles/.tile, base rules in 06-components.css)
   was narrowed and given more height, and the two-line labels ("EDUCATION"
   / "(SAMPLE ONLY)") no longer fit their text column -- the longest line,
   "(SAMPLE ONLY)" at the tile's actual 17px/700/uppercase text, measures
   ~115px, well past the base rule's ~100px column (940px row / 4 - padding
   56px - icon 48px - icon-gap 16px). Overridden here, scoped to .why so
   06-components.css (which these overrides must not be edited in, per this
   task's constraints) stays untouched.
   Row widened 940px -> 1060px: calibrated against home.png by pixel-
   scanning one tile's width and height in the mockup image (168px wide x
   ~89px tall) and using the tile's own known, unchanged 132px min-height as
   a ruler to convert image px to real CSS px (89/132 = .674 scale) ->
   168 / .674 ~= 249px, i.e. essentially the 250px a tile now computes to
   here at >=1200px containers (940px row's old 220px tile was well short
   of that). Grid gap and the tile's vertical padding (its "tallness") are
   untouched, so only the row's total width and each tile's *horizontal*
   chrome change.
   Below ~1060px+gutters the row is still capped by the container itself
   rather than by this max-width (same as the old 940px rule already was at
   1024px's ~944px container -- not a new state), so widening the row alone
   doesn't help there; the tile's own horizontal padding/icon/icon-gap are
   also trimmed slightly so the text column clears ~115px even at that
   container-bound width (944px container -> 221px tile -> 125px text
   column). */
.why .tiles { max-width: 1060px; }
.why .tile { padding: 2.25rem 1.25rem; gap: .75rem; }
.why .tile .icon { width: 2.75rem; height: 2.75rem; }

.everything__title { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1.5rem; margin-bottom: 2.5rem; }
/* Grid align-items: center already centers the bar on the *full* two-line
   label box (measured: bar's own centre exactly equals the label box's
   centre), but because the "EVERYTHING" line (40px) so outweighs the
   "You Need to Succeed!" line (18px) within that shared 62.5px box, a
   geometrically-centered 40px bar still dips ~7px into the subtitle's own
   line box. translateY nudges it back up onto the title line's footprint,
   clearing the subtitle instead of overlapping it, matching the mockup. */
.everything__bar { height: 40px; background: var(--ink); border-radius: var(--pill); transform: translateY(-10px); }
.everything__bar:last-child { border-radius: var(--pill); }
.everything__label { text-align: center; font-size: clamp(1.75rem, 3.5vw, 2.5rem); font-weight: 900; text-transform: uppercase; line-height: 1; }
.everything__label small { display: block; font-size: .45em; font-weight: 400; text-transform: none; margin-top: .25em; }
.everything__cols { display: grid; grid-template-columns: repeat(3, 1fr); }
/* Flex column with the button pushed to the bottom: the copy deck's third heading ("See Available
   Investment Properties") wraps to two lines while the other two do not, which left its button
   sitting a line lower than the others. min-height on the paragraph equalises the common case; this
   makes the buttons line up whatever length the headings end up. */
.everything__col { text-align: center; padding: 1rem 2rem; border-right: 1px solid var(--border); display: flex; flex-direction: column; align-items: center; }
.everything__col .btn { margin-top: auto; }
.everything__col:last-child { border-right: 0; }
.everything__col h3 { font-size: 1.5rem; }
.everything__col p { font-size: .875rem; color: var(--text-muted); min-height: 7em; }
.everything__icon { margin: 0 auto 1rem; }
html[data-theme="dark"] .everything__bar { background: var(--surface); }
@media (max-width: 768px) {
  .everything__title { grid-template-columns: 1fr; }
  .everything__bar { display: none; }
  .everything__cols { grid-template-columns: 1fr; }
  .everything__col { border-right: 0; border-bottom: 1px solid var(--border); padding: 1.5rem 0; }
  .everything__col p { min-height: 0; }
}

/* ===== About ===== */
/* Mockup (about-black-belt.png): the portrait runs the full height of the
   text column, not a small floating box -- measured, the photo's own top
   and bottom edges land almost exactly level with the "Creating Financial
   Breakthroughs" heading and the last link-list item respectively. Our
   lorem copy is longer than the mockup's, so chasing an exact px height
   would be wrong; align-items: stretch + a 100%-height, object-fit: cover
   image instead makes the portrait always match whatever height the text
   column actually needs, at any copy length. Reset to a plain intrinsic-
   ratio image once the columns stack (992px) -- stretch only makes sense
   while the two are grid siblings sharing one row height. */
.bio__inner { display: grid; grid-template-columns: 1fr 440px; gap: 3rem; align-items: stretch; }
.bio__content p { font-size: .875rem; }
.bio__content h2 { font-size: 1.5rem; margin-top: 1.5rem; }
.bio__list-title { font-weight: 700; margin-bottom: .5rem; }
.link-list { list-style: none; padding: 0; margin: 0; }
.link-list__item { display: flex; align-items: center; gap: .5rem; margin-bottom: .4rem; font-size: .9375rem; }
.link-list__item .icon { color: var(--brand); width: 1.25rem; height: 1.25rem; }
.link-list__item a { color: var(--text); text-decoration: underline; }
.link-list__item:first-child a { color: var(--brand); }
.bio__portrait img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; box-shadow: var(--shadow); display: block; }
.bio__closing { margin-top: 2.5rem; font-size: .9375rem; }
@media (max-width: 992px) { .bio__inner { grid-template-columns: 1fr; } .bio__portrait { max-width: 420px; margin-inline: auto; } .bio__portrait img { height: auto; } }

.challenges { background: linear-gradient(180deg, var(--dark-panel-2), #2d292d 60%, var(--dark-panel-2)); }
.challenges__sub { font-size: .8125rem; color: var(--on-dark-muted); margin-bottom: 2.5rem; }
.challenges__slider { max-width: 920px; margin-inline: auto; }
.challenges__label { position: relative; z-index: 2; margin: 0 auto -1.5rem; width: fit-content; background: var(--brand-dark); padding: .75rem 2.5rem; border-radius: 6px; font-size: 1.5rem; font-weight: 700; }
.challenge { margin: 0; position: relative; }
.challenge__img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 6px; filter: brightness(.55); }
.challenge__text { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 3rem; font-size: clamp(1.25rem, 2.8vw, 1.875rem); font-weight: 600; text-shadow: 0 2px 10px rgba(0,0,0,.6); }
.challenges__footer { font-size: .8125rem; color: var(--on-dark-muted); margin: 2rem auto 0; max-width: 900px; }
.cta-stack { display: grid; gap: 1.5rem; }

/* ===== Get Started ===== */
.hero--start .hero__inner { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; }
.hero--start .hero__content { text-align: right; border-right: 1px solid rgba(255,255,255,.35); padding-right: 3rem; }
.hero--start .hero__eyebrow { text-transform: none; font-size: clamp(1.25rem, 2.4vw, 1.75rem); font-weight: 600; }
.hero--start .hero__title { text-transform: uppercase; }
.hero__aside { font-size: .8125rem; max-width: 360px; }
.hero__aside p { margin-bottom: 1rem; }
@media (max-width: 768px) { .hero--start .hero__inner { grid-template-columns: 1fr; } .hero--start .hero__content { text-align: left; border: 0; padding: 0; } }

.why-start { background: var(--dark-panel-2) linear-gradient(120deg, rgba(255,255,255,.06), transparent 50%); color: #fff; border-radius: var(--pill); padding: 2rem clamp(1.5rem, 5vw, 4rem); margin-top: -4rem; position: relative; z-index: 2; box-shadow: var(--shadow); text-align: center; }
.why-start__title { font-size: clamp(1.25rem, 2.6vw, 1.75rem); margin-bottom: 1.5rem; }
.why-start__cols { display: grid; grid-template-columns: repeat(3, 1fr); }
.why-start__col { padding: 0 1.5rem; border-right: 1px solid rgba(255,255,255,.2); }
.why-start__col:last-child { border-right: 0; }
.why-start__col .icon { margin: 0 auto .5rem; }
.why-start__col p { margin: 0; font-size: 1.125rem; }
@media (max-width: 768px) { .why-start { border-radius: 16px; margin-top: 0; } .why-start__cols { grid-template-columns: 1fr; gap: 1.5rem; } .why-start__col { border: 0; } }

.path__title { text-align: center; font-size: clamp(1.75rem, 3.5vw, 2.5rem); font-weight: 900; text-transform: uppercase; margin-bottom: 2rem; }
.path__eyebrow { display: block; font-size: .55em; font-weight: 400; text-transform: uppercase; letter-spacing: .04em; }
.path__inner { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; }
.path__portrait img { width: 100%; border-radius: 6px; box-shadow: var(--shadow); }
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; }
.step { position: relative; display: flex; align-items: center; gap: 1rem; background: var(--dark-panel-2) linear-gradient(90deg, var(--dark-panel-2), #3a353a); color: #fff; border-radius: 8px; padding: 1.25rem 1.5rem 1.25rem 4.5rem; min-height: 90px; }
.step__num { position: absolute; left: -1rem; top: 50%; transform: translateY(-50%); width: 3.25rem; height: 3.25rem; border-radius: 50%; background: var(--brand); display: flex; align-items: center; justify-content: center; font-size: 1.5rem; font-weight: 900; box-shadow: var(--shadow-sm); }
.step p { margin: 0; font-size: .9375rem; }
@media (max-width: 768px) { .path__inner { grid-template-columns: 1fr; } .path__portrait { max-width: 360px; margin-inline: auto; } }

.breakthrough { position: relative; background: var(--dark-panel-2) var(--bg) center / cover; isolation: isolate; padding: var(--section) 0 0; }
.breakthrough::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(20,18,20,.85), rgba(20,18,20,.6)); z-index: -1; }
.breakthrough__copy { max-width: 560px; margin-left: auto; padding-bottom: 2rem; }
.breakthrough__copy p { font-size: .875rem; color: var(--on-dark-muted); }
.breakthrough__form { max-width: 1000px; margin: 0 auto; transform: translateY(3rem); margin-top: -1.5rem; }
.bb-form--red { background: linear-gradient(180deg, var(--brand-dark), #4d0000); color: #fff; padding: clamp(1.5rem, 4vw, 2.5rem); border-radius: 8px; box-shadow: var(--shadow); }
.bb-form--red .bb-form__title { text-align: center; font-size: 1.375rem; margin-bottom: 1.25rem; }
.bb-form--red .bb-field__label { color: #fff; }
.breakthrough + .newsletter { padding-top: calc(3rem + clamp(2.5rem, 6vw, 4.5rem)); }
@media (max-width: 768px) { .breakthrough__copy { margin-left: 0; } }

/* ===== Contact ===== */
.hero--contact { padding-bottom: 2rem; overflow-x: clip; } /* Belt-and-suspenders only (see task-35-report.md): .contact-grid__info's bleed below is now an exact calc, not a 100vw overshoot, so there's nothing left for this to actually catch outside of sub-pixel calc rounding -- kept as a cheap safety net, not load-bearing. */
.hero--contact.curve-bottom::after { display: none; }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: end; margin-top: 2rem; }
.contact-grid__form { margin-bottom: -9rem; position: relative; z-index: 2; } /* above .contact-grid__info's background bleed (z-index: 1), which otherwise paints over this column's overhang since it's a positioned sibling and this column would default to a static (unpositioned, lower) stacking order. */
.bb-form--contact-card { max-width: 520px; }
.bb-form--contact-card .bb-form__title { text-align: left; }
/* .contact-grid__info's light background needs to bleed out to the true
   viewport edge on both sides regardless of container width (see
   .contact-grid__form's comment above for why it must stay behind the form
   card). The previous version did `margin: 0 -100vw -2rem; padding: 3rem
   100vw 0`, i.e. a same-value, viewport-relative overshoot on both left and
   right sized to the FULL viewport width -- at 1920px wide that put its
   real getBoundingClientRect().right ~1560px past the viewport (only
   invisible because .hero--contact's `overflow-x: clip` above ate the
   difference, which is also exactly what hid it from
   document.documentElement.scrollWidth-based overflow checks -- see
   task-35-report.md). It was also needlessly symmetric: this is the RIGHT
   column of a 2-col grid, so the right edge only ever needs to travel the
   container's own side gutter to reach the viewport edge, while the left
   edge -- starting from the grid's horizontal midpoint -- needs roughly
   that plus half the container back. --info-edge and --info-col replicate
   .container's own `width: min(100% - 2 * var(--gutter), var(--container))`
   sizing math so each side's bleed is calc'd to land exactly on the
   viewport edge, not a viewport-width guess trimmed after the fact. */
.contact-grid__info {
  --info-edge: max(var(--gutter), calc((100vw - var(--container)) / 2));
  --info-col: min(calc(100vw - var(--gutter) * 2), var(--container));
  --info-left-bleed: calc(var(--info-edge) + (var(--info-col) + 2rem) / 2);
  color: var(--text);
  background: var(--bg);
  margin: 0 calc(-1 * var(--info-edge)) -2rem calc(-1 * var(--info-left-bleed));
  padding: 3rem var(--info-edge) 0 var(--info-left-bleed);
  position: relative;
  z-index: 1;
}
.contact-info__title { font-size: clamp(1.25rem, 2.4vw, 1.625rem); text-transform: uppercase; padding-bottom: .75rem; border-bottom: 1px solid var(--border); }
.contact-info__text { font-size: .8125rem; color: var(--text-muted); }
.contact-info__numbers { display: flex; gap: 2rem; margin: 1rem 0 0; }
.contact-info__numbers div + div { padding-left: 2rem; border-left: 1px solid var(--border); }
.contact-info__numbers dt { font-size: 1.125rem; font-weight: 600; }
.contact-info__numbers dd { margin: 0; font-size: 1.5rem; font-weight: 600; color: var(--brand); }
.contact-info__numbers a { color: var(--brand); }
/* Contact/schedule forms via CF7 (bb_contact_override / bb_schedule_override): the "Get in
   Touch" and "Free Strategy Session" forms' Form tabs both supply the same
   .bb-form__grid/.bb-field/.bb-field--half etc markup the built-in forms render (see
   blackbelt-core/inc/form-render.php + inc/forms.php), so every layout/field rule above (03
   .bb-form--red, .bb-form--contact-card, .bb-field--half/quarter/full, .bb-field input/select/
   textarea, .bb-field__label) already applies unchanged -- CF7 just nests the actual control one
   level deeper inside its own .wpcf7-form-control-wrap span, which doesn't affect descendant
   selectors. These rules only patch the handful of spots where CF7's own markup (that wrap span,
   its checkbox/response-output/validation-tip elements, and the <input type=submit> in place of
   a <button>) needs reshaping to match the built-in forms' look on the red card. Shared by both
   embeds (.bb-contact-embed on /get-in-touch/, .bb-schedule-embed on /start-here/) rather than
   duplicated per page. */
.bb-contact-embed .wpcf7-form-control-wrap, .bb-schedule-embed .wpcf7-form-control-wrap { display: block; }
.bb-contact-embed input[type="submit"].btn, .bb-schedule-embed input[type="submit"].btn { border: 0; appearance: none; -webkit-appearance: none; }
.bb-contact-embed .bb-field--checkbox .wpcf7-list-item, .bb-schedule-embed .bb-field--checkbox .wpcf7-list-item { display: flex; align-items: flex-start; gap: .5rem; margin: 0; font-size: .8125rem; line-height: 1.35; }
.bb-contact-embed .bb-field--checkbox .wpcf7-list-item label, .bb-schedule-embed .bb-field--checkbox .wpcf7-list-item label { display: flex; align-items: flex-start; gap: .5rem; cursor: pointer; }
.bb-contact-embed .bb-field--checkbox input[type="checkbox"], .bb-schedule-embed .bb-field--checkbox input[type="checkbox"] { margin-top: .2em; accent-color: var(--brand); }
.bb-contact-embed .wpcf7-not-valid-tip, .bb-schedule-embed .wpcf7-not-valid-tip { color: #ffd5d9; }
.bb-contact-embed .wpcf7-form-control.wpcf7-not-valid, .bb-schedule-embed .wpcf7-form-control.wpcf7-not-valid { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(227,2,32,.35); }
.bb-contact-embed .wpcf7-response-output, .bb-schedule-embed .wpcf7-response-output { margin: 1rem 0 0; padding: .5rem .9rem; border-radius: 3px; font-size: .8125rem; background: rgba(255,255,255,.12); color: #fff; border: 1px solid rgba(255,255,255,.3); }
/* CF7's own includes/css/styles.css gives .wpcf7-spinner a 24px box plus `margin: 0 24px`
   (visibility:hidden until submitting, but still laid out) -- as a flex sibling of the footnote/
   button inside .bb-field--submit (flex, justify-content:flex-end, gap:1rem), that reserved
   72px-plus-two-gaps eats into the footnote's flex-basis and can force its text to wrap where it
   fit on one line before CF7 (measured on /start-here/: 88px of encroachment at 1920px, still
   enough left over at 1024px to wrap even after trimming just the margins -- the built-in form's
   own <button> has no such sibling at all, so full removal from the flex row, not just a smaller
   footprint, is what actually matches its layout at every width). display:none also disables the
   spinner animation CF7 shows during an in-flight submission; the built-in form has no loading
   indicator either, so this keeps both forms' behaviour matched, not just their idle look. */
.bb-contact-embed .wpcf7-spinner, .bb-schedule-embed .wpcf7-spinner { display: none; }
.map-section { padding-top: 11rem; }
.map-section__head { display: flex; align-items: flex-start; gap: 2rem; flex-wrap: wrap; margin-bottom: -1.5rem; position: relative; z-index: 2; }
.tagline-pill { background: var(--dark-panel-2); color: #fff; font-weight: 600; font-size: .875rem; padding: 1.25rem 2rem; border-radius: 8px; margin: 0; text-align: center; }
/* The social icons keep their own heading from the copy deck; the wrapper stops the <h2> from
   becoming a third flex item and breaking the pill/icons row alignment. */
.map-section__social { display: flex; flex-direction: column; gap: .75rem; }
.social__title { font-size: 1rem; font-weight: 700; margin: 0; }

/* ===== Offices and meetup groups (contact) ===== */
/* align-items: center, because the two blocks are very different heights -- "Offices In" is a
   heading and one line against a heading, seven pills and a button, and top-aligning left the
   offices column stranded above ~150px of nothing. */
.locations__inner { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 2.5rem; align-items: center; }
.locations__block { text-align: center; }
.locations__title { font-size: 1.375rem; margin-bottom: 1rem; }
/* word-spacing carries the gap either side of the "|" that the copy deck draws with double spaces --
   sanitize_text_field() collapses those on save, so it cannot live in the content. */
.locations__offices { font-size: 1.125rem; font-weight: 700; color: var(--brand); margin: 0; letter-spacing: .04em; word-spacing: .5em; }
.locations__list { list-style: none; margin: 0 0 1.5rem; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }
.locations__city { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--pill); padding: .4rem 1rem; font-size: .875rem; font-weight: 600; }
.social--contact { margin-top: .5rem; }
.social--contact a { background: var(--brand); color: #fff; }
.map { margin-left: 2rem; border-radius: 6px; overflow: hidden; box-shadow: var(--shadow-sm); }
.training__text { font-size: .875rem; color: var(--text-muted); margin-bottom: 2rem; }
.training-card { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .75rem; aspect-ratio: 4 / 3; border-radius: 8px; overflow: hidden; color: #fff; background: var(--dark-panel-2) var(--bg) center / cover; isolation: isolate; box-shadow: var(--shadow-sm); }
.training-card::before { content: ""; position: absolute; inset: 0; background: rgba(20,18,20,.55); z-index: -1; transition: background .2s var(--ease); }
.training-card:hover::before { background: rgba(191,0,0,.6); }
.training-card__title { font-size: 1.5rem; font-weight: 700; text-shadow: 0 2px 8px rgba(0,0,0,.5); }
.training-card__text { font-size: .8125rem; text-align: center; max-width: 85%; color: var(--on-dark-muted); text-shadow: 0 2px 8px rgba(0,0,0,.5); margin-top: -.25rem; }
@media (max-width: 992px) {
  .contact-grid { grid-template-columns: 1fr; }
  .contact-grid__form { margin-bottom: 0; }
  .contact-grid__info { margin: 0; padding: 0; background: none; color: #fff; }
  .contact-info__numbers dd { color: #fff; }
  .map-section { padding-top: var(--section); }
  .map { margin-left: 0; }
}

/* ===== Landing (wholesaling layout) ===== */
.hero--landing { padding-bottom: clamp(5rem, 10vw, 7rem); }
.callout--landing { margin-top: calc(-1 * clamp(3rem, 7vw, 5rem)); max-width: 820px; }
.landing-intro__text { font-size: .875rem; max-width: 900px; margin: 1.5rem auto 2.5rem; color: var(--text-muted); }
.bullets { display: grid; grid-template-columns: 40% 1fr; gap: 2rem; background: var(--dark-panel-2) linear-gradient(120deg, rgba(255,255,255,.05), transparent 50%); color: #fff; border-radius: 8px; padding: 1.5rem; box-shadow: var(--shadow); }
.bullets__media img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; }
.bullets__title { font-size: 1.5rem; margin: .5rem 0 .5rem; }
.bullets__list { list-style: none; margin: 0 0 1.25rem; padding: 0; font-size: .875rem; }
.bullets__item { position: relative; padding-left: 1rem; margin-bottom: .3rem; }
.bullets__item::before { content: ""; position: absolute; left: 0; top: .55em; width: .4rem; height: .4rem; border-radius: 50%; background: #fff; }
@media (max-width: 768px) { .bullets { grid-template-columns: 1fr; } }
.topics__panel { background: linear-gradient(135deg, var(--dark-panel-2) 0%, var(--dark-panel-2) 60%, var(--brand-dark) 140%); color: #fff; border-radius: 8px; padding: clamp(1.5rem, 4vw, 3rem) clamp(1.5rem, 4vw, 3rem) clamp(1.5rem, 4vw, 3rem) 0; margin-left: 4rem; }
/* Mockup's alternating-list images (wholesaling/fix-and-flip/on-site-
   mentoring/market-insights/properties all share this landing.php template)
   read noticeably larger than a fixed 300px column -- at the standard
   1200px container that's ~26% of the available row width after the
   panel's own padding, whereas the mockup's rows give the photo close to a
   third of the row. A fixed px column also can't grow on wider viewports.
   minmax() keeps a sane floor at narrow widths (where it stacks to one
   column below 768px anyway) while scaling up on wide ones. */
.topic { display: grid; grid-template-columns: minmax(260px, 36%) 1fr; gap: 2rem; align-items: center; margin-bottom: 2rem; }
.topic:last-child { margin-bottom: 0; }
.topic__media { margin-left: -4rem; }
.topic__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px; box-shadow: var(--shadow); }
.topic__title { font-size: 1.5rem; }
.topic__text { font-size: .8125rem; color: var(--on-dark-muted); }
@media (max-width: 768px) {
  .topics__panel { margin-left: 0; padding: 1.5rem; }
  .topic { grid-template-columns: 1fr; }
  .topic__media { margin-left: 0; }
}

/* ===== "Take Action Now" band (landing pages) =====
   Two next steps side by side. Deliberately not .everything__cols, which is a hard repeat(3, 1fr);
   a column whose button URL is blank shows .action-now__status instead of a link, which is how the
   copy deck's "Coming Soon" course is rendered without an anchor that goes nowhere. */
.action-now__cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2rem; margin-top: 2.5rem; }
.action-now__col { padding: 2rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 1.25rem; }
.action-now__title { font-size: 1.25rem; margin: 0; }
.action-now__status { margin: 0; font-weight: 700; color: var(--brand); text-transform: uppercase; letter-spacing: .08em; font-size: .875rem; }

@media (max-width: 768px) {
  .action-now__cols { grid-template-columns: 1fr; gap: 1.25rem; }
  .action-now__col { padding: 1.5rem; }
}

/* ===== Success stories ===== */
.videos__title { font-size: clamp(1.25rem, 2.4vw, 1.625rem); margin-bottom: 2rem; }
.cta-band--wide .cta-band__inner { grid-template-columns: 54% 1fr; }
.cta-band--wide .cta-band__panel { margin-right: calc(-1 * var(--gutter)); }

/* ===== Podcast ===== */
.hero--listen { padding-bottom: 1rem; }
/* Pixel-measured against the mockup (listen.png): the headphones image is
   ~30% of the pill's own width, not the ~24% a flat 220px gives inside the
   900px max-width. minmax() keeps a sane floor while scaling with the pill
   (which itself has a fixed max-width, so this settles at a fixed px value
   past 900px-equivalent viewports same as before -- just a larger one). */
.listen-pill { display: grid; grid-template-columns: minmax(220px, 30%) 1fr; gap: 1.5rem; align-items: center; background: var(--dark-panel-2); border-radius: var(--pill); padding: 1rem 3rem 1rem 1rem; margin: 2.5rem auto -4rem; max-width: 900px; box-shadow: var(--shadow); position: relative; z-index: 2; }
.listen-pill__img img { width: 100%; }
.listen-pill__text { margin: 0; font-size: 1.125rem; font-weight: 600; }
.episodes { padding-top: 6rem; }
/* align-items: stretch (not start) so the single featured card grows to
   match the height of the two stacked side cards next to it instead of
   leaving a fixed gap under it -- the featured card's own body is already
   a flex column with justify-content: space-between (06-components.css),
   so the extra height just spaces its text/player further apart rather
   than warping the card. */
.episodes__grid { display: grid; grid-template-columns: 2fr 1fr; gap: 1.25rem; align-items: stretch; }
.episodes__featured { display: flex; }
.episodes__featured .podcast-card { display: flex; flex-direction: column; width: 100%; }
.episodes__featured .podcast-card__body { flex: 1; }
.episodes__side { display: grid; gap: 1.25rem; align-content: start; }
/* Load-more's target: a separate full-width grid below .episodes__grid, not
   the narrow .episodes__side column (that column growing taller than the
   single-card featured column beside it left an ever-larger blank void
   under the featured card). Empty when there's nothing loaded yet, so it
   contributes no extra gap on its own. */
.episodes__more { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.episodes__more:not(:empty) { margin-top: 1.25rem; }
@media (max-width: 992px) { .episodes__more { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .episodes__more { grid-template-columns: 1fr; } }
.testimonials--highlights { padding-top: clamp(8rem, 16vw, 12rem); }
.testimonials--highlights .section-title { position: absolute; left: 0; right: 0; top: clamp(2.5rem, 6vw, 4rem); }
.voice__inner { display: grid; grid-template-columns: 360px 1fr; gap: 3rem; align-items: end; }
.voice__portrait img { width: 100%; border-radius: 8px 8px 0 0; }
.voice__text { font-size: .875rem; color: var(--text-muted); }
/* The host bio is multi-paragraph, so .voice__text is a wrapper, not the paragraph itself. */
.voice__text p { margin: 0 0 .75rem; }
.voice__text p:last-child { margin-bottom: 0; }
.voice__rows { list-style: none; margin: 1.5rem 0 0; padding: 0; }
.voice__row { display: flex; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid var(--border); }
.voice__row h3 { font-size: 1.125rem; margin-bottom: .25rem; }
.voice__row p { margin: 0; font-size: .8125rem; color: var(--text-muted); }
.voice__icon { flex: none; width: 3rem; height: 3rem; border-radius: 50%; background: var(--surface-2); display: inline-flex; align-items: center; justify-content: center; color: var(--text-muted); }
.voice__icon .icon { width: 1.5rem; height: 1.5rem; }
.single-episode .player { margin-bottom: 2rem; }
@media (max-width: 768px) {
  .listen-pill { grid-template-columns: 1fr; text-align: center; border-radius: 16px; padding: 1.5rem; margin-bottom: -3rem; }
  .listen-pill__img { max-width: 160px; margin-inline: auto; }
  .episodes__grid, .voice__inner { grid-template-columns: 1fr; }
  .voice__portrait { max-width: 300px; margin-inline: auto; }
}

/* ===== Events ===== */
.hero--events { padding-block: clamp(2.5rem, 6vw, 4rem); }
.featured-event { margin-bottom: 2rem; }
.event-row__kicker { font-size: .8em; font-weight: 600; }
/* .muted p > a inherits the base a{color:var(--brand)} (02-base.css), which
   measures 4.44:1 on the page's light background -- just under WCAG AA's
   4.5:1 for normal text (confirmed by Lighthouse on the events archive).
   --brand-dark clears it at 5.93:1. Scoped to these two inline text links
   rather than the global `a` rule, which would need a full sitewide pass to
   confirm it never lands on a dark panel elsewhere. */
.events__toggle a, .events__empty a { color: var(--brand-dark); }
.events__toggle { margin-top: 2rem; font-size: .875rem; }
.single-event__grid { display: grid; grid-template-columns: 1fr 320px; gap: 3rem; align-items: start; }
.event-box { border-radius: 8px; border: 1px solid var(--border); position: sticky; top: 1rem; }
.event-box__actions { margin-top: 1rem; }
.event-box__actions .btn { width: 100%; }
.entry-content { font-size: 1.0625rem; }
.entry-content > * + * { margin-top: 1.25em; }
.entry-content img { border-radius: 6px; }
@media (max-width: 768px) { .single-event__grid { grid-template-columns: 1fr; } .event-box { position: static; } }

/* ===== Blog / single / misc ===== */
.hero--blog { padding-bottom: 0; }
.hero--blog.curve-bottom::after { display: none; }
.hero--blog .post-card--featured { margin-top: 2rem; margin-bottom: -4rem; position: relative; z-index: 2; }
.hero--blog .post-card--featured .post-card__head { background: var(--dark-panel-2); }
.blog { padding-top: 6rem; }
.single-post__tags { font-size: .875rem; color: var(--text-muted); margin-top: 2rem; }
.post-nav { display: flex; justify-content: space-between; gap: 1rem; margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border); font-weight: 600; }
.post-nav a { display: inline-flex; align-items: center; gap: .35rem; color: var(--text); }
.post-nav div:last-child { text-align: right; }
.search-results { list-style: none; padding: 0; margin: 0; }
.search-results li { padding: 1rem 0; border-bottom: 1px solid var(--border); }
.search-results li a { font-weight: 700; font-size: 1.125rem; color: var(--text); }
.search-results p { margin: .25rem 0 0; font-size: .9375rem; color: var(--text-muted); }
.pagination { margin-top: 2rem; }
.pagination .nav-links { display: flex; gap: .5rem; justify-content: center; }
.pagination .page-numbers { padding: .4rem .8rem; border: 1px solid var(--border); border-radius: 4px; color: var(--text); }
.pagination .page-numbers.current { background: var(--brand); color: #fff; border-color: var(--brand); }
