/* TIF Synergy site — additions on top of site.css.
   Drop AFTER site.css in <link> order, or merge into site.css. */

/* ── Fix .btn-gold text on dark sections ────────────────────────
   .section-forest a / .section-ink a sets link colour to gold,
   which collapses text on a .btn-gold (gold bg) — invisible.
   Force ink-coloured text on every .btn-gold. */
.btn-gold,
.section-forest .btn-gold,
.section-ink .btn-gold,
.section-paper .btn-gold,
.section-cream .btn-gold,
.hero-forest .btn-gold,
.hero-sub .btn-gold {
  color: var(--neutral-900) !important;
}
.btn-gold:hover,
.section-forest .btn-gold:hover,
.section-ink .btn-gold:hover {
  color: var(--neutral-900) !important;
  background: #a8862e;
}

/* ── Tool tile — cream system ───────────────────────────────────
   Cream background, forest text, brand-primary hover border.
   Replaces the dark-gradient direction shipped in PR #15.
   Dark-section overrides restored for any future dark-section use. ── */

.tool-tile {
  background: var(--surface);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius-lg);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
  color: var(--text);
  text-decoration: none !important;
  position: relative;
  overflow: hidden;
}
.tool-tile:hover {
  border-color: var(--brand-primary);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

/* Breathing room for /app/suite.html#taxlex-style fragment links (suite.js
   scrollToHashTile()). suite.html has no sticky/fixed nav to clear, so this
   is just a small offset rather than a nav-height compensation. */
.tool-tile[id] {
  scroll-margin-top: 24px;
}

/* Inline SVG pictograms inherit forest via currentColor */
.tool-tile svg.tool-mark {
  width: 40px;
  height: 40px;
  color: var(--brand-primary);
  flex-shrink: 0;
}
/* Img-tag marks (TaxMap uses the complex multi-stroke chain-link glyph) */
.tool-tile img.tool-mark { width: 40px; height: 40px; }

/* Eyebrow category label */
.tool-tile .tool-summary {
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand-secondary);
  opacity: 0.80;
  font-weight: 500;
  margin-top: -8px;
}

/* Product name */
.tool-tile h3 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 500;
  color: var(--brand-primary);
  margin: 0;
}

/* Descriptor paragraph */
.tool-tile p {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-2);
}

/* Meta row: action link + stage chip */
.tool-tile .tool-meta {
  margin-top: auto;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 500;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* Stage chip — mono, gold, opacity encodes lifecycle
   .tool-tile sits on --surface (white) — same gold-on-light failure as
   .eyebrow (2.81:1). Same darkened value. WCAG AA contrast fix, 2026-07-10. */
.tool-tile .tool-meta .stage {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--brand-gold-dk);
}
/* Beta: 70% opacity */
.tool-tile .tool-meta .stage.stage--beta {
  opacity: 0.70;
}
/* In design: 40% opacity + dashed gold border on chip span */
.tool-tile .tool-meta .stage.stage--design {
  opacity: 0.40;
  border: 1px dashed var(--brand-gold);
  padding: 1px 5px;
  border-radius: 3px;
}

/* Portal tiles have a single child in .tool-meta ("Launch →" only, no stage chip).
   space-between with one child pins it to the left — override to right-align. */
.tool-tile--launch .tool-meta {
  justify-content: flex-end;
}

/* Launch affordance (portal tiles — replaces stage chip) */
.tool-tile .tool-meta .tile-launch {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--brand-primary);
  font-weight: 500;
}

/* Dark-section context — cream tiles on .section-forest / .section-ink render as
   elevated white cards against the forest background. The tile's own cream/white
   background provides the contrast; no colour overrides needed here.
   This comment block is a placeholder for future per-section theming if required. */

/* ── Suite grid layouts ──────────────────────────────────────── */
.suite-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  margin-top: 40px;
}
@media (max-width: 980px) {
  .suite-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .suite-grid { grid-template-columns: 1fr; }
}

/* ── Trial banner (replaces the old SaaS/Transfer license-pair) ─ */
.trial-banner {
  margin-top: 40px;
  background: rgba(184, 150, 62, 0.08);
  border: 1px solid color-mix(in oklch, var(--brand-gold) 35%, transparent);
  border-radius: var(--radius-lg);
  padding: 28px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.trial-banner .trial-text {
  flex: 1;
  min-width: 280px;
}
/* This is the default (non-forest) value. .trial-banner's own background
   is a translucent gold wash (8%) composited over whichever section it
   sits in; on the live services.html usage that is --surface (white) —
   same gold-on-light failure as .eyebrow, computed against the actual
   blended background (#f9f7f0): 2.62:1. Same darkened value.
   .section-forest overrides this below with a bespoke lighter value.
   WCAG AA contrast fix, 2026-07-10. */
.trial-banner .trial-eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-gold-dk);
  font-weight: 500;
  margin-bottom: 8px;
  display: block;
}
.trial-banner h4 {
  font-family: var(--font-display);
  font-size: 24px;
  color: var(--brand-primary);
  font-weight: 500;
  margin-bottom: 6px;
}
.trial-banner p {
  font-size: 14px;
  color: var(--text-2);
  margin: 0;
}
.section-forest .trial-banner {
  background: rgba(184, 150, 62, 0.12);
  border-color: rgba(184, 150, 62, 0.45);
}
.section-forest .trial-banner h4 { color: var(--neutral-50); }
.section-forest .trial-banner p { color: rgba(247, 245, 240, 0.78); }
/* Bespoke value, not a drop-in of the ramp: .trial-banner's background
   here is a 12% gold wash over forest (#1a4a3a), which blends to a
   lighter #2d533a than the solid forest --brand-gold-on-dark was tuned
   against. --brand-gold-on-dark on that actual blended background only
   reaches 4.06:1, short of 4.5:1. This shade (#d5bd81, same hue, lighter)
   clears 4.74:1 against the real #2d533a background. WCAG AA contrast fix,
   2026-07-10. */
.section-forest .trial-banner .trial-eyebrow { color: #d5bd81; }

/* ── Specialty card (capability strip) ─────────────────────── */
.specialty-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 40px;
}
@media (max-width: 860px) { .specialty-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .specialty-grid { grid-template-columns: 1fr; } }

.specialty {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand-gold);
  border-radius: 8px;
  padding: 24px 28px;
}
/* .specialty sits on --surface (white) — same gold-on-light failure as
   .eyebrow (2.81:1). Same darkened value. WCAG AA contrast fix, 2026-07-10. */
.specialty .specialty-tag {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-gold-dk);
  font-weight: 500;
  margin-bottom: 8px;
  display: block;
}
.specialty h4 {
  font-family: var(--font-display);
  font-size: 20px;
  color: var(--brand-primary);
  font-weight: 500;
  margin-bottom: 8px;
  line-height: 1.2;
}
.specialty p {
  font-size: 14px;
  color: var(--text-2);
  line-height: 1.55;
  margin: 0;
}

/* ── Helper classes (replace v4 inline styles — CSP keeps them out of HTML) ── */
/* .role-line sits inside .card on --surface (white) — same gold-on-light
   failure as .eyebrow (2.81:1). Same darkened value. WCAG AA contrast fix,
   2026-07-10. */
.role-line {
  font-size: 13px;
  color: var(--brand-gold-dk);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 500;
  margin-top: -8px;
  margin-bottom: 16px;
}
.note-footnote {
  text-align: center;
  color: var(--text-3);
}
.max-w-60ch { max-width: 60ch; }
.metrics.metrics-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 760px) {
  .metrics.metrics-3 { grid-template-columns: repeat(2, 1fr); }
}

/* ── Suite portal tile grid (post-sign-in, tighter than marketing 2×2) ── */
.suite-grid--portal {
  grid-template-columns: repeat(3, 1fr);
  margin-top: 32px;
}
@media (max-width: 860px) {
  .suite-grid--portal { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .suite-grid--portal { grid-template-columns: 1fr; }
}

/* ── Microsoft sign-in button — official brand spec ──────────────
   White background, Segoe UI, #5e5e5e text, 1px #8c8c8c border.
   Do not modify colours — this is a Microsoft brand-compliance requirement.
   Ref: https://learn.microsoft.com/en-us/entra/identity-platform/howto-add-branding-in-apps ── */
.ms-signin-button {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  background: #ffffff;
  color: #5e5e5e;
  border: 1px solid #8c8c8c;
  border-radius: 0;   /* Microsoft spec: no border radius on this button */
  padding: 0 12px;
  height: 41px;
  font-family: 'Segoe UI', Helvetica, Arial, sans-serif;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.14s ease, background 0.14s ease;
  width: 100%;
  justify-content: center;
}
.ms-signin-button:hover {
  border-color: #505050;
  background: #f8f8f8;
}
.ms-signin-button:focus-visible {
  /* brand-primary (forest #163d30) gives ~7:1 on white — well above WCAG 1.4.11 3:1 threshold.
     brand-gold (#b8963e) only reaches ~2.5:1 on white and fails the non-text contrast requirement. */
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}
.ms-signin-button__logo {
  width: 21px;
  height: 21px;
  flex-shrink: 0;
  display: block;
}

/* ── SSO page brand chrome — scoped to .suite-sso body class ──── */

/* Page shell: cream, matches main-site body. Dark gradient dropped.
   No overflow:hidden — the tile grid (signed-in state) can be taller than
   the viewport on mobile (5 tiles stacked on a small iPhone) and clipping
   the body kills scroll. The flex-column + justify-content:center still
   keeps the sign-in card centred when content fits; when content is taller
   than min-height:100vh the page grows and body-level scroll handles it. */
.suite-sso {
  background: var(--surface);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  position: relative;
}

/* Top-centre logo — dark wordmark on cream page */
.suite-sso__logo {
  position: absolute;
  top: 32px;
  left: 50%;
  transform: translateX(-50%);
  width: 140px;
  height: auto;
  display: block;
}

/* Sign-in card — white, elevated above the cream page */
.suite-sso__card {
  position: relative;
  z-index: 1;
  background: #ffffff;
  border: 1px solid rgba(26, 74, 58, 0.08);
  max-width: 28rem;
  width: 100%;
  border-radius: 16px;
  padding: 32px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
  margin-top: 88px; /* clear the top logo */
}

.suite-sso__card h1 {
  font-family: var(--font-display);
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 500;
  color: var(--brand-primary);
  margin-bottom: 12px;
  line-height: 1.2;
}

.suite-sso__card > p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-2);
  margin-bottom: 28px;
}

.suite-sso__demo-link {
  display: block;
  margin-top: 20px;
  font-size: 13px;
  text-align: center;
  color: var(--text-3);
  text-decoration: none;
}
.suite-sso__demo-link:hover {
  color: var(--brand-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Suite portal header (rendered by suite.js post sign-in) */
.suite-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.suite-header h2 {
  font-family: var(--font-display);
  font-size: 28px;
  color: var(--brand-primary);
  margin: 0;
}
.suite-header p { color: var(--text-2); margin: 0; }

/* Post-sign-in root container needs padding since there's no card */
.suite-sso #suite-root {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1100px;
}

/* Mobile responsive */
@media (max-width: 600px) {
  .suite-sso__logo { width: 110px; top: 24px; }
  .suite-sso__card {
    max-width: 92vw;
    padding: 24px 20px;
    margin-top: 72px;
  }
  .suite-sso__card h1 { font-size: 20px; }
}

/* ── INTERACTIVE POLISH — motion layer ──────────────────────────
   All animation is gated behind:
     1. html.js-motion  (set by main.js as its first operation)
     2. @media (prefers-reduced-motion: no-preference)
   Without both conditions, elements render in their visible final state.
   This satisfies both no-JS and reduced-motion requirements. ── */

/* ── D. Smooth anchor scrolling ─────────────────────────────────
   Pure CSS: gated behind prefers-reduced-motion so keyboard users
   who opt out of motion get instant jumps, not smooth scrolls.
   Overrides the unconditional html { scroll-behavior: smooth } in
   site.css with a targeted media-gated version. ── */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Anchor targets: add scroll-margin-top so sticky nav doesn't overlap.
   72px = nav height; +8px breathing room. Applied to all section IDs
   and anything with an id on a non-inline element. */
section[id],
div[id],
header[id],
article[id] {
  scroll-margin-top: 80px;
}

/* ── A. Scroll-reveal base states ───────────────────────────────
   Only applied when html.js-motion is present AND user has not
   requested reduced motion. Without both gates, elements are
   fully visible at all times. ── */
@media (prefers-reduced-motion: no-preference) {
  html.js-motion .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.5s ease-out, transform 0.5s ease-out;
  }
  html.js-motion .reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  /* Stagger delays — class-based to stay CSP-clean (no inline style) */
  html.js-motion .reveal-stagger.reveal-delay-0 { transition-delay: 0ms; }
  html.js-motion .reveal-stagger.reveal-delay-1 { transition-delay: 60ms; }
  html.js-motion .reveal-stagger.reveal-delay-2 { transition-delay: 120ms; }
  html.js-motion .reveal-stagger.reveal-delay-3 { transition-delay: 180ms; }
  html.js-motion .reveal-stagger.reveal-delay-4 { transition-delay: 220ms; }
  html.js-motion .reveal-stagger.reveal-delay-5 { transition-delay: 240ms; }
}

/* ── F. Hero entrance ────────────────────────────────────────────
   Separate class so hero items don't double-trigger from both
   the reveal observer AND the hero entrance init. ── */
@media (prefers-reduced-motion: no-preference) {
  html.js-motion .hero-reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.48s ease-out, transform 0.48s ease-out;
  }
  html.js-motion .hero-reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  /* Hero entrance stagger: tighter gaps for a single sequential flow */
  html.js-motion .hero-stagger.reveal-delay-0 { transition-delay: 0ms; }
  html.js-motion .hero-stagger.reveal-delay-1 { transition-delay: 80ms; }
  html.js-motion .hero-stagger.reveal-delay-2 { transition-delay: 160ms; }
  html.js-motion .hero-stagger.reveal-delay-3 { transition-delay: 260ms; }
  html.js-motion .hero-stagger.reveal-delay-4 { transition-delay: 340ms; }
  html.js-motion .hero-stagger.reveal-delay-5 { transition-delay: 400ms; }
}

/* ── C. Sticky nav — scrolled state ─────────────────────────────
   .scrolled is added by main.js via rAF-throttled scroll listener.
   Tighter vertical padding + added shadow signal nav is now sticky
   and the user has scrolled past the top. Transition is CSS so it
   works regardless of motion preference (it's subtle, not animating
   content position). ── */
.site-nav {
  transition: box-shadow 0.22s ease, padding 0.22s ease, background 0.22s ease;
}
.site-nav.scrolled {
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.10);
  background: rgba(247, 245, 240, 0.97);
}
.site-nav.scrolled .container {
  height: 60px;
  transition: height 0.22s ease;
}
/* Ensure the container height transition is smooth on first scroll too */
.site-nav .container {
  transition: height 0.22s ease;
}

/* ── E. Hover micro-interactions ────────────────────────────────
   All CSS-only, in this file. Enhanced lift + shadow on cards and
   pillars, arrow nudge on tool-tile Visit → affordance.
   Focus-visible ring uses brand tokens for accessibility. ── */

/* Cards — hover lift. -2px keeps cards softer than the clickable .tool-tile
   tiles (-4px), which are the primary product affordances. */
.card {
  transition: box-shadow 0.22s ease, transform 0.22s ease, border-color 0.22s ease;
}
.card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.10);
}

/* Pillars — hover lift gated behind prefers-reduced-motion for consistency
   with the rest of the file (transforms should never fire unconditionally). */
.pillar {
  transition: box-shadow 0.22s ease, transform 0.22s ease;
}
.pillar:hover {
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.08);
}
@media (prefers-reduced-motion: no-preference) {
  .pillar:hover {
    transform: translateY(-3px);
  }
}

/* Specialty cards — same gate as pillars above. */
.specialty {
  transition: box-shadow 0.22s ease, transform 0.22s ease;
}
.specialty:hover {
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.08);
}
@media (prefers-reduced-motion: no-preference) {
  .specialty:hover {
    transform: translateY(-3px);
  }
}

/* Tool tile — the existing transition covers border-color + transform.
   Enhanced here: stronger shadow, and arrow nudge on the Visit → span. */
.tool-tile:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.10);
}
/* Arrow affordance nudge — target the first span in .tool-meta (the "Visit →") */
.tool-tile .tool-meta span:first-child {
  display: inline-block;
  transition: transform 0.18s ease;
}
.tool-tile:hover .tool-meta span:first-child {
  transform: translateX(3px);
}

/* Case cards */
.case {
  transition: box-shadow 0.22s ease, transform 0.22s ease;
}
.case:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.09);
}

/* Buttons — lift + shadow, focus-visible ring using brand tokens */
.btn {
  transition: background 0.18s ease, border-color 0.18s ease,
              transform 0.18s ease, box-shadow 0.18s ease;
}
.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.btn:focus-visible {
  outline: 2px solid var(--brand-gold);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(184, 150, 62, 0.18);
}
/* Focus ring on dark sections uses the same gold — readable on forest/ink */
.section-forest .btn:focus-visible,
.section-ink .btn:focus-visible,
.hero-forest .btn:focus-visible {
  outline-color: var(--brand-gold);
}

/* Portal layout — replaces .suite-sso__card once user signs in.
   Removes the 28rem max-width constraint so the tile grid spans the full canvas. */
.suite-sso__portal {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1100px;
  padding: 20px 0;
  margin-top: 100px; /* clear the top logo */
}

/* HIGH-1 fix: hide sign-in H1 and descriptor paragraph once the user is
   authenticated and the card swaps to .suite-sso__portal. Both elements sit
   inside #suite-card but outside #suite-root, so JS can't reach them via the
   root innerHTML swap — CSS scoping is the right lever here. */
:where(.suite-sso__portal) h1,
:where(.suite-sso__portal) > p {
  display: none;
}

/* Generic hide — used by suite.js to remove the demo link post sign-in */
.is-hidden { display: none !important; }

/* Empty / error states on cream background — use forest colours */
.suite-sso .suite-error h2,
.suite-sso .suite-loading p,
.suite-sso .suite-empty h2 { color: var(--brand-primary); }
.suite-sso .suite-error .lede,
.suite-sso .suite-loading .lede,
.suite-sso .suite-empty .lede { color: var(--text-2); }
.suite-sso .card {
  background: var(--surface);
  border-color: var(--border);
}
.suite-sso .card h3 { color: var(--brand-primary); }
.suite-sso .card p { color: var(--text-2); }

/* Suite diagnostic panel — used by suite.js showDiagnostic() to render the
   tile-access failure/claims dump. Replaces inline styles the CSP blocks. */
.suite-diagnostic {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.85em;
  line-height: 1.4;
}
.suite-diagnostic__body {
  white-space: pre-wrap;
  word-break: break-all;
  background: #f0ece4; /* no exact token match (closest is --neutral-100 #f0ede6) */
  padding: 0.5em;
  margin-top: 0.25em;
}

/* ── Engagement-process roadmap ──────────────────────────────────
   Five-stage horizontal connected steps on desktop, vertical stack
   on mobile. Semantic <ol> with .engagement-step items.
   No inline styles, no JS. Uses existing design tokens.
   Respects prefers-reduced-motion (no transforms on motion-sensitive
   elements; connector line is CSS-only, non-animated). ── */

.engagement-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 0;
  counter-reset: none; /* numbers supplied by .step-num, not CSS counter */
}

/* Each step occupies equal width in the row */
.engagement-step {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  position: relative;
  padding: 0 12px;
}

/* Horizontal connector line between steps — pseudo-element on all but last */
.engagement-step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 22px; /* centre on the step-num circle */
  left: calc(50% + 22px); /* start after the number circle */
  right: calc(-50% + 22px); /* end before the next circle */
  height: 2px;
  background: var(--neutral-200);
  z-index: 0;
}

/* Number circle */
.step-num {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--brand-primary);
  color: var(--neutral-0);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  margin-bottom: 16px;
}

/* Step 5 (optional) — lighter treatment to signal it is not required */
.engagement-step:last-child .step-num {
  background: var(--neutral-0);
  color: var(--brand-primary);
  border: 2px solid var(--brand-primary);
}

/* Step body text */
.step-body h3 {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--brand-primary);
  margin: 0 0 6px;
  line-height: 1.3;
}

.step-body .small {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
}

/* Optional badge on stage 5 heading */
.step-optional {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 400;
  color: var(--text-2);
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}

/* Horizontal layout up to 860px, then stack vertically */
@media (max-width: 860px) {
  .engagement-steps {
    flex-direction: column;
    gap: 0;
  }

  .engagement-step {
    flex-direction: row;
    align-items: flex-start;
    text-align: left;
    padding: 0 0 28px;
    width: 100%;
  }

  /* Vertical connector — override horizontal pseudo-element */
  .engagement-step:not(:last-child)::after {
    top: 44px;        /* below the circle */
    left: 21px;       /* centre on the 44px circle */
    right: auto;
    width: 2px;
    height: calc(100% - 44px + 28px); /* span the gap to the next item */
    background: var(--neutral-200);
  }

  .step-num {
    margin-bottom: 0;
    margin-right: 20px;
    flex-shrink: 0;
  }

  .step-body {
    padding-top: 10px;
  }
}
