/* ============================================================
   home-blocks.css — Shared styles for homepage conversion blocks.

   Container / infra shipped by #15450. Contents populated by
   #15452 (widget), #15453 (journey), #15454 (screens), #15456
   (parents). All colors use --color-* tokens; both dark and
   light theme resolve without extra rules.

   Reveal animation is opt-in via [data-reveal] + .is-revealed.
   scroll-reveal.js adds .is-revealed. Under
   prefers-reduced-motion or JS-off, blocks render fully visible.
   ============================================================ */

/* Slot host — inner container populated by follow-up commits.
   Empty slot renders as a spacer so the section rhythm holds even
   before the block issues ship. */
.home-block-slot {
  min-height: 1.5rem;
  width: 100%;
}

/* Empty slot must not read as a broken block — hide until content lands. */
.home-block-slot:empty {
  min-height: 0;
}

/* ---- Reveal transition ---- */
[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity, transform;
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: translateY(0);
}

/* Reduced-motion + JS-off: no motion, always visible.
   scroll-reveal.js also handles reduced-motion by force-revealing;
   this rule is the belt-and-braces for JS-off. */
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.no-js [data-reveal],
html:not(.js) [data-reveal] {
  opacity: 1;
  transform: none;
  transition: none;
}

/* ---- Block-common spacing / layout ---- */
.home-block {
  padding-block: clamp(2.5rem, 5vw, 4.5rem);
}

.home-block .section-header {
  max-width: 48rem;
  margin-inline: auto;
  text-align: center;
}

.home-block .section-header h2 {
  /* #15706 — was --color-primary. In DARK theme that token is #6B8BD6,
     which measures 4.38:1 against the --color-neutral-50 (#1E293B)
     surface these blocks sit on — below WCAG AA 4.5:1. --color-primary-700
     is the theme-aware pair (#162658 light / #93B4FD dark → 7.10:1), so
     this stays token-driven with no [data-theme] override. */
  color: var(--color-primary-700);
  margin-block: 0.5rem 0.75rem;
}

/* Dark theme picks up token change automatically for headings that
   use --color-primary tokens. Sections that override colors should
   scope inside .home-block-<name> for isolation.

   NOTE (#15706): prefer --color-primary-700 over --color-primary for
   TEXT on these blocks. --color-primary is tuned for fills/borders and
   is too dark in the dark palette to clear AA as body/heading copy. */

/* ---- Responsive breakpoints (aligned with site tokens) ---- */
@media (max-width: 640px) {
  .home-block .section-header p {
    font-size: 0.95rem;
  }
}

/* ============================================================
   Block 1 — Home AI widget (#15452)
   ============================================================ */
.home-block-widget .home-block-slot {
  max-width: 44rem;
  margin-inline: auto;
}

.home-ai-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  border-radius: 0.75rem;
  padding: 1.25rem;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}

.home-ai-label {
  font-weight: 600;
  color: var(--color-primary-700);
}

.home-ai-input {
  width: 100%;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.15));
  border-radius: 0.5rem;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.4;
  resize: vertical;
  min-height: 3rem;
  background: var(--color-surface, #fff);
  color: var(--color-text-primary, #111);
  box-sizing: border-box;
}

.home-ai-input:focus {
  outline: 2px solid var(--color-accent, #D4AF37);
  outline-offset: 1px;
  border-color: var(--color-accent, #D4AF37);
}

.home-ai-examples {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
}

.home-ai-examples-label {
  color: var(--color-text-muted, #666);
  margin-right: 0.25rem;
}

.home-ai-example-chip {
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.15));
  background: transparent;
  color: var(--color-primary-700);
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  cursor: pointer;
  font-family: inherit;
  transition: background-color 120ms ease, color 120ms ease;
}

.home-ai-example-chip:hover,
.home-ai-example-chip:focus-visible {
  background: var(--color-primary);
  color: #fff;
  outline: none;
}

.home-ai-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.home-ai-submit {
  min-width: 8rem;
}

.home-ai-counter {
  font-size: 0.9rem;
  color: var(--color-text-muted, #666);
}

.home-ai-status {
  min-height: 1.25rem;
  font-size: 0.9rem;
  color: var(--color-text-muted, #666);
}

.home-ai-answer {
  border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  padding-top: 0.9rem;
  margin-top: 0.25rem;
}

.home-ai-answer-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.home-ai-answer-label {
  font-weight: 600;
  color: var(--color-primary-700);
}

.home-ai-answer-source {
  font-size: 0.8rem;
  color: var(--color-text-muted, #666);
  font-style: italic;
}

.home-ai-answer-body {
  white-space: pre-wrap;
  line-height: 1.55;
  color: var(--color-text-primary, #111);
}

/* ── #15673: the three beats under every answer ──────────────────────────
 *
 * Every token below is declared in variables.css for BOTH themes. Always use
 * the SUFFIXED text tokens (-primary / -secondary / -muted); the unsuffixed
 * bare text token is declared nowhere, so its `var()` fallback silently wins
 * in light theme and loses in dark — the root cause of #15616 (near-black on
 * a dark surface, 1.29:1, WCAG AA fail, ~1 month live) and of #9317 / #14368
 * before it. Pre-commit Check 92 now guards this. (Its detector scans
 * comments too, which is why the bare token is described here rather than
 * written out.)
 *
 * Visual hierarchy is deliberate: the answer is the hero. The locator and the
 * depth line are subordinate chrome ABOUT the answer, and the CTA is a next
 * step beneath it — not an interruption.
 */

/* The syllabus locator — quiet and specific. It earns trust by naming the
 * exact syllabus cell, not by boasting; per FE upsell governance it is
 * informational and is NOT counted as an upsell surface. */
.home-ai-answer-locator {
  margin: 0.6rem 0 0;
  font-size: 0.85rem;
  font-style: italic;
  color: var(--color-text-muted, #64748B);
}

/* Replaces the source stamp when the answer is not honestly grounded. Same
 * weight as the locator: it states a limit without apologising for one. */
.home-ai-answer-note {
  margin: 0.6rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted, #64748B);
}

/* ── #16560 — the answer-check prompt ──────────────────────────────────────
 *
 * Sits BETWEEN the answer it is about and the conversion beats below it, so
 * the DOM order is the pedagogy: judge the answer first, decide about an
 * account second.
 *
 * Deliberately quieter than `.home-ai-answer-cta`, which is itself already
 * quieter than the wall CTA (`btn-primary`, no `btn-lg`). The JS gives these
 * buttons NO `.btn` class for exactly this reason — a filled primary pair
 * here would read as the real ask and pull taps away from signup. They are
 * outlined, on the alt surface, and they recede once answered.
 *
 * The left rule is the whole visual idea: it ties the prompt to the answer
 * above it rather than presenting it as a new section, so a visitor reads it
 * as a note ABOUT what they just read.
 */
.home-ai-answer-check {
  margin: 0.9rem 0 0;
  padding: 0.75rem 0.9rem;
  border-left: 3px solid var(--color-primary-200, #C7D7F5);
  border-radius: 0 0.5rem 0.5rem 0;
  background: var(--color-surface-alt, #F8FAFC);
}

.home-ai-answer-check-q {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.45;
  color: var(--color-text-primary, #111);
}

.home-ai-answer-check-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.7rem;
}

/* 48px min height is the accessibility floor for a touch target, not a
 * styling preference — this is a phone-first acquisition surface. */
.home-ai-answer-check-btn {
  min-height: 48px;
  padding: 0.55rem 1.1rem;
  font-size: 0.9rem;
  font-weight: 600;
  font-family: inherit;
  line-height: 1.2;
  color: var(--color-primary-700, #1D4ED8);
  background: var(--color-surface, #fff);
  border: 1.5px solid var(--color-primary-300, #93B4F0);
  border-radius: 0.5rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.home-ai-answer-check-btn:hover {
  background: var(--color-primary-50, #EFF5FE);
  border-color: var(--color-primary-500, #3B76E8);
}

/* Keyboard users must see the same affordance a mouse user gets on hover;
 * the buttons carry no `.btn` class, so they inherit no focus ring. */
.home-ai-answer-check-btn:focus-visible {
  outline: 2px solid var(--color-primary-600, #2563EB);
  outline-offset: 2px;
}

/* The reply to their choice. Affirming, never a verdict on the answer. */
.home-ai-answer-check-result {
  margin: 0.7rem 0 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--color-text-secondary, #475569);
}

/* The transferable part — the sentence worth checking, or the general rule.
 * Carries the emphasis because it is the only line the visitor should still
 * remember tomorrow. */
.home-ai-answer-check-how {
  margin: 0.45rem 0 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--color-text-primary, #111);
}

.home-ai-answer-depth {
  margin: 0.75rem 0 0.9rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--color-text-secondary, #475569);
}

.home-ai-answer-cta {
  display: inline-block;
}

/* Language-neutral affordance: the arrow lives in CSS so no translator has to
 * carry it and no locale can lose it. */
.home-ai-answer-cta::after {
  content: ' \2192';
}

.home-ai-answer-cta-note {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted, #64748B);
}

.home-ai-cap {
  text-align: center;
  padding: 1.5rem 0.5rem;
}

.home-ai-cap-title {
  color: var(--color-primary-700);
  margin: 0 0 0.5rem;
}

.home-ai-cap-body {
  color: var(--color-text-primary, #111);
  margin: 0 0 1rem;
}

.home-ai-cap-note {
  font-size: 0.85rem;
  color: var(--color-text-muted, #666);
  margin-top: 0.6rem;
}

@media (max-width: 640px) {
  .home-ai-form { padding: 1rem; }
  .home-ai-submit { width: 100%; }
  .home-ai-actions { flex-direction: column; align-items: stretch; }
  .home-ai-counter { text-align: center; }
  /* #15673 — match .home-ai-submit: a full-width tap target on the phone,
   * which is where the overwhelming majority of these visitors are. */
  .home-ai-answer-cta { display: block; text-align: center; }
  /* #16560 — stacked rather than side-by-side, because the two labels are
   * localized and si/ta run materially longer than en ("ඔව්, නිවැරදි යැයි
   * පෙනේ" vs "Yes, looks right"). `flex-wrap` alone would let en sit on one
   * row and si/ta break unevenly on another; stacking makes all three
   * locales render identically and removes the 360px starve risk outright
   * (the Check 88 lesson, applied before it can bite). */
  .home-ai-answer-check-actions { flex-direction: column; }
  .home-ai-answer-check-btn { width: 100%; }
}

/* ============================================================
   Block 2 — Learn → Practice → Exam animated journey (#15453)
   ============================================================ */
.journey-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  max-width: 64rem;
  margin-inline: auto;
}

.journey-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.journey-step {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  padding: 0.75rem 0.9rem;
  border-radius: 0.6rem;
  transition: background-color 300ms ease, box-shadow 300ms ease;
  border: 1px solid transparent;
}

.journey-step-num {
  flex: 0 0 auto;
  width: 2rem; height: 2rem;
  border-radius: 999px;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center; justify-content: center;
  font-weight: 700;
}

.journey-step-loop .journey-step-num {
  background: var(--color-accent, #D4AF37);
  color: var(--color-primary-700);
  font-size: 1.4rem;
  line-height: 1;
}

.journey-step-title {
  margin: 0 0 0.25rem;
  /* #15706 — see .home-block .section-header h2. At 1.05rem/700 this is
     NOT WCAG "large text" (bold needs >= 18.66px), so the full 4.5:1 bar
     applies and --color-primary's 4.38:1 was a genuine AA failure. */
  color: var(--color-primary-700);
  font-size: 1.05rem;
}

.journey-step-copy {
  margin: 0;
  color: var(--color-text-secondary, #333);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* Device frame */
.journey-device {
  display: flex;
  justify-content: center;
}

.journey-device-frame {
  width: 100%;
  max-width: 22rem;
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.12));
  border-radius: 1rem;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.journey-device-chrome {
  display: flex;
  gap: 0.35rem;
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--color-border, rgba(0, 0, 0, 0.06));
  background: var(--color-primary-50, #E8EAF0);
}

.journey-device-dot {
  width: 0.55rem; height: 0.55rem;
  border-radius: 999px;
  background: var(--color-primary-200, #9DA6C0);
}

.journey-tabs {
  display: flex;
  border-bottom: 1px solid var(--color-border, rgba(0, 0, 0, 0.06));
}

.journey-tab {
  flex: 1;
  padding: 0.55rem 0.5rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--color-text-muted, #666);
  border-bottom: 2px solid transparent;
  transition: color 300ms ease, border-color 300ms ease;
}

.journey-screens {
  position: relative;
  min-height: 12rem;
  padding: 1rem 1.1rem;
}

.journey-screen {
  position: absolute;
  inset: 1rem 1.1rem;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 350ms ease, transform 350ms ease;
}

.journey-screen-label {
  display: block;
  font-size: 0.8rem;
  color: var(--color-text-muted, #666);
  margin-bottom: 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.journey-screen-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.9rem;
  color: var(--color-text-secondary, #333);
}

.journey-screen-list em {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.1rem 0.4rem;
  border-radius: 0.35rem;
  background: var(--color-accent, #D4AF37);
  color: var(--color-primary-900);
  font-style: normal;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
}

.journey-screen-snap {
  text-align: center;
  padding: 1rem 0;
}

.journey-screen-snap-num {
  display: block;
  font-size: 3rem;
  font-weight: 800;
  color: var(--color-primary-700);
  line-height: 1;
}

.journey-screen-snap-sub {
  display: block;
  font-size: 0.85rem;
  color: var(--color-text-muted, #666);
  margin-top: 0.3rem;
}

/* Animation — plays only after the section reveals (I1 infra flips
   .is-revealed). Off-screen the section is not revealed, so the
   animation never starts (perf). CSS-only cycle across 4 phases. */
@keyframes journeyScreenCycle {
  0%, 25%   { opacity: 0; transform: translateY(6px); }
  3%, 22%   { opacity: 1; transform: translateY(0); }
}

@keyframes journeyTabActive {
  0%, 25%, 100% { color: var(--color-text-muted, #666); border-color: transparent; }
  3%, 22%       { color: var(--color-primary-700); border-color: var(--color-primary); }
}

@keyframes journeyStepActive {
  0%, 25%, 100% {
    background-color: transparent;
    border-color: transparent;
    box-shadow: none;
  }
  3%, 22% {
    background-color: var(--color-primary-50, #E8EAF0);
    border-color: var(--color-primary-200, #9DA6C0);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
  }
}

/* Total cycle: 16s (4s per phase including the loop). */
.home-block-journey.is-revealed .journey-screen,
.home-block-journey.is-revealed .journey-tab,
.home-block-journey.is-revealed .journey-step {
  animation-duration: 16s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

.home-block-journey.is-revealed .journey-screen[data-screen="learn"]    { animation-name: journeyScreenCycle; animation-delay: 0s; }
.home-block-journey.is-revealed .journey-screen[data-screen="practice"] { animation-name: journeyScreenCycle; animation-delay: -12s; }
.home-block-journey.is-revealed .journey-screen[data-screen="exam"]     { animation-name: journeyScreenCycle; animation-delay: -8s; }

.home-block-journey.is-revealed .journey-tab[data-tab="learn"]    { animation-name: journeyTabActive; animation-delay: 0s; }
.home-block-journey.is-revealed .journey-tab[data-tab="practice"] { animation-name: journeyTabActive; animation-delay: -12s; }
.home-block-journey.is-revealed .journey-tab[data-tab="exam"]     { animation-name: journeyTabActive; animation-delay: -8s; }

.home-block-journey.is-revealed .journey-step[data-step="1"]    { animation-name: journeyStepActive; animation-delay: 0s; }
.home-block-journey.is-revealed .journey-step[data-step="2"]    { animation-name: journeyStepActive; animation-delay: -12s; }
.home-block-journey.is-revealed .journey-step[data-step="3"]    { animation-name: journeyStepActive; animation-delay: -8s; }
.home-block-journey.is-revealed .journey-step[data-step="loop"] { animation-name: journeyStepActive; animation-delay: -4s; }

/* Pause off-view — .is-revealed only re-added on scroll-in, so removal
   is handled implicitly by observer. We add an extra guard for
   prefers-reduced-motion which force-reveals but must NOT animate. */
@media (prefers-reduced-motion: reduce) {
  .home-block-journey .journey-screen,
  .home-block-journey .journey-tab,
  .home-block-journey .journey-step {
    animation: none !important;
  }
  /* All 3 screens visible as a static labelled storyboard. */
  .home-block-journey .journey-screens {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-height: 0;
  }
  .home-block-journey .journey-screen {
    position: static;
    opacity: 1;
    transform: none;
    inset: auto;
    padding: 0.75rem;
    border-radius: 0.5rem;
    background: var(--color-primary-50, #E8EAF0);
  }
  .home-block-journey .journey-tab {
    color: var(--color-primary-700);
    border-color: var(--color-primary);
  }
}

/* JS-off same static storyboard */
html:not(.js) .home-block-journey .journey-screen {
  position: static;
  opacity: 1;
  transform: none;
  inset: auto;
}

@media (max-width: 768px) {
  .journey-grid {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  .journey-device-frame { max-width: 100%; }
}

/* ============================================================
   Block 3 — Side-by-side screenshot rows (#15454)
   ============================================================ */
.screens-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 5vw, 3.5rem);
  max-width: 64rem;
  margin-inline: auto;
}

.screens-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}

.screens-row-image-right .screens-image { order: 2; }
.screens-row-image-right .screens-copy  { order: 1; }

.screens-image {
  background: var(--color-primary-50, #E8EAF0);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  border-radius: 1rem;
  padding: 1rem;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06);
  display: flex;
  justify-content: center;
  align-items: center;
}

.screens-image img {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: 0.5rem;
  background: var(--color-surface-alt, #fff); /* placeholder while lazy-loading — themes with dark mode (#15618) */
}

.screens-copy-title {
  margin: 0 0 0.5rem;
  color: var(--color-primary);
  font-size: 1.35rem;
  line-height: 1.3;
}

.screens-copy-body {
  color: var(--color-text-secondary, #333);
  line-height: 1.6;
  margin: 0 0 1rem;
}

.screens-copy-parent {
  border-left: 3px solid var(--color-accent, #D4AF37);
  padding: 0.5rem 0 0.5rem 0.9rem;
  margin: 0;
  color: var(--color-text-muted, #555);
  font-size: 0.92rem;
  background: rgba(212, 175, 55, 0.06);
  border-radius: 0 0.25rem 0.25rem 0;
}

.screens-copy-parent strong {
  color: var(--color-primary);
  font-weight: 700;
}

/* Mobile: image always above copy, single column. */
@media (max-width: 768px) {
  .screens-row {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .screens-row-image-right .screens-image { order: 0; }
  .screens-row-image-right .screens-copy  { order: 1; }
}

/* ============================================================
   Block 4 — For Parents conversion panel (#15456)
   ============================================================ */
.parents-panel {
  max-width: 60rem;
  margin-inline: auto;
}

.parents-grid {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem;
}

.parents-card {
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  border-radius: 0.75rem;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
}

.parents-card-icon {
  font-size: 1.6rem;
  line-height: 1;
}

.parents-card-title {
  color: var(--color-primary-700);
  margin: 0;
  font-size: 1.05rem;
}

.parents-card-body {
  color: var(--color-text-secondary, #333);
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
}

.parents-cta {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.parents-cta-secondary {
  color: var(--color-primary-700);
  text-decoration: underline;
  font-size: 0.9rem;
}

@media (max-width: 640px) {
  .parents-grid { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   Idasara Method surfaces (#17166)
   ---------------------------------------------------------------------------
   These four rules replace 39 hand-written inline `style=` attributes that
   were duplicated byte-for-byte across 21 files (homepage + the whole
   /method/ tree in en/si/ta). Every copy referenced `--color-bg-surface`,
   a token declared NOWHERE, so CSS silently took the light `#f8fafc`
   fallback in BOTH themes while `--color-text-primary` correctly inverted
   to #F1F5F9 — light text on a light card. 4th recurrence of the class
   (#9317 -> #14368 -> #15616 -> #17166).

   The token now lives here, once per rule, in a file `variables.css` governs
   and pre-commit Check 92 already scans. Per #17161 the mechanism is replaced
   rather than policed: there is no hand-written token left in HTML to guard.
   Do not re-inline these declarations.

   Two of these four rules bind class names that ALREADY existed in the markup
   with no CSS behind them (`.method-carousel-section`, `.method-carousel-wrapper`);
   the other two (`.method-callout`, `.method-cta-panel`) are introduced here,
   because the old markup was a bare `style=` with no class at all. An earlier
   draft of this comment claimed all four pre-existed — corrected in review.

   These rules are load-bearing for LAYOUT, not only colour: `.method-carousel-wrapper`
   carries `overflow: hidden` and `max-width`, without which the flex track's four
   `min-width: 100%` slides render side-by-side and overflow the page. That is why
   the `?v=` stamp on this file moved in the same commit — new HTML against a
   cached old copy of this file would break the homepage in both themes.
   ------------------------------------------------------------------------ */

.method-carousel-section {
  padding: 3rem 0;
  background: var(--color-surface-alt, #f1f5f9);
  border-bottom: 1px solid var(--color-border, #e2e8f0);
}

/* Was `background: #ffffff` — frozen white in every theme, with no token
   at all. `--color-surface` flips to #1E293B in dark. */
.method-carousel-wrapper {
  position: relative;
  max-width: 960px;
  margin: 0 auto;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid var(--color-border, #e2e8f0);
  background: var(--color-surface, #ffffff);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06);
}

.method-callout {
  background: var(--color-surface-alt, #f1f5f9);
  border-left: 4px solid var(--color-primary, #2563eb);
  padding: 1.25rem;
  border-radius: 0 8px 8px 0;
  margin: 2rem 0;
}

.method-cta-panel {
  margin-top: 3rem;
  padding: 2.5rem 1.5rem;
  background: var(--color-surface-alt, #f1f5f9);
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: 16px;
  text-align: center;
}
