/* ========================================================================
   vc-b2b2c.css — the $30M Series-B STORY components.

   Phase 0 foundation (owner: FOUND-COMPONENTS). Consumes the §1 SEMANTIC
   tokens authored by FOUND-TOKENS in vc-tokens.css — NO raw hexes here.
   All components are SVG/CSS (print- & dark-safe), data-bound by markup,
   theme-agnostic (reference semantic roles → dark "just works"), and honor
   prefers-reduced-motion.

   CSP: external CSS only. The ONLY allowed dynamic style is
   el.style.setProperty('--w', pct) (dilution-bar segment widths), consumed
   by the width:var(--w) rules below. Everything else is class toggles.

   Components:
     §4.1 .b2b2c-flow      — two-sided 3-node partnership flow + edges
     §4.2 .embed-visual    — partner-frame with embedded RPP card (toggle)
     §4.3 .scenario-model  — segmented radiogroup + chart/table swap + <details>
     §4.4 .data-room       — sidebar + doc grid + locked overlay
     §4.5 .cap-table / .dilution-bar — stacked 100% pre/post bars + legend
     §4.6 .nexus-hub       — central node + radiating pillars (reduced-motion)
   ======================================================================== */

/* ========================================================================
   §4.1  B2B2C partnership flow  (.b2b2c-flow) — the signature visual
   Structure (data-bound from gtm.twoSidedLoop / gtm.b2b2c):
     <figure class="b2b2c-flow" role="img" aria-label="…">
       <div class="flow-track">
         <div class="flow-node flow-node--institution"> … </div>
         <div class="flow-edges"> … labeled arrows … </div>
         <div class="flow-node flow-node--platform"> … </div>
         <div class="flow-edges"> … labeled arrows … </div>
         <div class="flow-node flow-node--member"> … </div>
       </div>
       <ol class="visually-hidden"> text version for SR/print </ol>
       <figcaption class="flow-caption"> … </figcaption>
     </figure>
   Horizontal ≥48rem; vertical stack <48rem. Arrowheads via currentColor.
   ======================================================================== */
.b2b2c-flow {
  margin: var(--space-8) 0;
  padding: var(--space-6);
  background: var(--bg-surface);
  border: 0.0625rem solid var(--border-subtle);
  border-radius: var(--radius-lg);
}
.flow-track {
  display: flex;
  flex-direction: column;     /* mobile-first: vertical stack */
  align-items: stretch;
  gap: var(--space-4);
}
.flow-node {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  border: 0.0625rem solid var(--border-subtle);
  box-shadow: var(--shadow-sm);
  text-align: center;
}
.flow-node__label {
  font-family: var(--font-data);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text-primary);
}
.flow-node__sublabel {
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  line-height: 1.5;
}
.flow-node__icon {
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-md);
  margin-bottom: var(--space-1);
  color: var(--text-on-brand);
  background: var(--accent-primary);
}
.flow-node__icon svg { width: 1.5rem; height: 1.5rem; fill: currentColor; }
/* Center node elevated + brand gradient (the platform); flanks neutral */
.flow-node--platform {
  background: var(--grad-brand);
  border-color: transparent;
  box-shadow: var(--shadow-lg);
  color: var(--text-on-brand);
}
.flow-node--platform .flow-node__label { color: var(--text-on-brand); }
.flow-node--platform .flow-node__sublabel { color: var(--text-on-brand-dim); }
.flow-node--platform .flow-node__icon { background: rgba(255, 255, 255, 0.16); }
.flow-node--institution .flow-node__icon { background: var(--accent-partner); }
.flow-node--member .flow-node__icon { background: var(--accent-secondary); }

/* Edge group between two nodes: two stacked labeled arrows (down + up) */
.flow-edges {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  justify-content: center;
  align-items: stretch;
  padding: var(--space-1) 0;
}
.flow-edge {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-data);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-secondary);
}
.flow-edge__label {
  flex: 1;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--bg-surface-2);
}
/* Arrow built from currentColor: a line + a CSS triangle head.
   Direction set by modifier; colour tracks theme via the accent role. */
.flow-edge__arrow {
  position: relative;
  flex-shrink: 0;
  width: 1.75rem;
  height: 0.75rem;
  color: var(--accent-primary);
}
.flow-edge__arrow::before {     /* shaft */
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 0.125rem;
  transform: translateY(-50%);
  background: currentColor;
}
.flow-edge__arrow::after {      /* head (triangle via borders, currentColor) */
  content: "";
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  transform: translateY(-50%);
  border-block: 0.3125rem solid transparent;
}
.flow-edge--down .flow-edge__arrow::after {
  right: 0;
  border-left: 0.4375rem solid currentColor;
}
.flow-edge--up .flow-edge__arrow { color: var(--accent-secondary); }
.flow-edge--up .flow-edge__arrow::after {
  left: 0;
  border-right: 0.4375rem solid currentColor;
}
.flow-edge--up { color: var(--text-muted); }

/* Channel-economics callout chip ("CAC ↓ via embedded distribution").
   Background is mixed over --bg-surface (opaque, theme-aware) so the text
   contrast is deterministic regardless of the host surface it sits on.
   Light text darkened to green-700 for WCAG 1.4.3 AA on the tinted fill
   (~4.6:1 vs ~3.2:1 for green-600 at fs-sm/700 = small text). */
.flow-callout {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--accent-secondary) 14%, var(--bg-surface));
  color: var(--green-700);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 700;
}
/* Dark keeps the lighter accent token (green-400 ≈ 5.7:1 on the dark tint). */
[data-theme="dark"] .flow-callout { color: var(--accent-secondary); }
.flow-caption {
  margin-top: var(--space-4);
  font-size: var(--fs-sm);
  font-style: italic;
  color: var(--text-muted);
  line-height: 1.5;
}

/* Horizontal layout ≥48rem: nodes in a row, edge groups become the
   connective tissue between them. */
@media (min-width: 48rem) {
  .flow-track { flex-direction: row; align-items: center; }
  .flow-edges { flex: 0 0 auto; min-width: 8rem; }
  .flow-edge__arrow { width: 100%; min-width: 3rem; }
}

/* ========================================================================
   §4.2  Two-sided embed visual  (.embed-visual)
   A stylized "partner app" frame with an RPP module embedded inside it,
   plus the reverse (partner products inside RPP). Toggle flips states via a
   class (.is-reversed) set by JS on a real <button aria-pressed>.
   ======================================================================== */
.embed-visual {
  margin: var(--space-8) 0;
}
.embed-toggle {
  display: inline-flex;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
  padding: var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--bg-surface-2);
  border: 0.0625rem solid var(--border-subtle);
}
.embed-toggle__btn {
  min-height: 2.75rem;
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}
.embed-toggle__btn[aria-pressed="true"] {
  background: var(--bg-surface);
  color: var(--accent-primary);
  box-shadow: var(--shadow-sm);
}
.embed-toggle__btn:focus-visible {
  outline: 0.125rem solid transparent;
  box-shadow: var(--focus-ring);
}

/* The partner-app "browser/app chrome" frame */
.embed-frame {
  border: 0.0625rem solid var(--border-strong);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-surface);
  box-shadow: var(--shadow-md);
}
.embed-frame__bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-surface-2);
  border-bottom: 0.0625rem solid var(--border-subtle);
}
.embed-frame__dots {
  display: inline-flex;
  gap: var(--space-1);
}
.embed-frame__dots span {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--border-strong);
}
.embed-frame__title {
  font-family: var(--font-data);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--text-muted);
}
.embed-frame__body {
  padding: var(--space-6);
  display: grid;
  gap: var(--space-4);
  background:
    repeating-linear-gradient(
      0deg,
      transparent 0 1.25rem,
      color-mix(in srgb, var(--border-subtle) 40%, transparent) 1.25rem 1.3125rem
    );
  min-height: 12rem;
}
/* The embedded RPP white-label module sitting inside the partner surface */
.embed-card {
  border-radius: var(--radius-md);
  padding: var(--space-5);
  background: var(--grad-brand);
  color: var(--text-on-brand);
  box-shadow: var(--shadow-lg);
}
.embed-card__eyebrow {
  font-family: var(--font-data);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-on-brand-dim);
}
.embed-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--text-on-brand);
  margin: var(--space-1) 0 var(--space-2);
}
.embed-card__meta {
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  color: var(--text-on-brand-dim);
}
/* Reversed state: partner products surfaced inside RPP — swap framing.
   JS toggles .is-reversed; CSS flips which surface reads as host vs guest. */
.embed-visual.is-reversed .embed-frame__body { background: var(--bg-surface); }
.embed-visual.is-reversed .embed-card {
  background: var(--bg-surface-2);
  color: var(--text-primary);
  border: 0.0625rem solid var(--border-subtle);
}
.embed-visual.is-reversed .embed-card__title { color: var(--text-primary); }
.embed-visual.is-reversed .embed-card__eyebrow,
.embed-visual.is-reversed .embed-card__meta { color: var(--text-muted); }
.embed-caption {
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  font-style: italic;
  color: var(--text-muted);
}

/* ========================================================================
   §4.3  Scenario model  (.scenario-model)
   Segmented radiogroup (Conservative / Base / Upside) + chart/table swap
   container + <details> assumptions. JS swaps datasets + persists in
   sessionStorage; CSS owns the segmented control + the swap surface.
   ======================================================================== */
.scenario-model { margin: var(--space-8) 0; }

.scenario-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
/* segmented radiogroup */
.scenario-seg {
  display: inline-flex;
  padding: var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--bg-surface-2);
  border: 0.0625rem solid var(--border-subtle);
}
.scenario-seg__opt {
  min-height: 2.75rem;
  padding: 0 var(--space-5);
  display: inline-flex;
  align-items: center;
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}
.scenario-seg__opt[aria-checked="true"] {
  background: var(--accent-primary);
  color: var(--text-on-brand);
  box-shadow: var(--shadow-sm);
}
.scenario-seg__opt:focus-visible {
  outline: 0.125rem solid transparent;
  box-shadow: var(--focus-ring);
}
.scenario-note {
  font-family: var(--font-data);
  font-size: var(--fs-xs);
  font-style: italic;
  color: var(--text-muted);
}

/* Swap container: chart + table; JS updates content, CSS animates the
   refresh (reduced-motion-safe). Metric cards above can reuse .metric-grid. */
.scenario-swap {
  display: grid;
  gap: var(--space-6);
}
.scenario-swap.is-updating { opacity: 0.5; transition: opacity var(--dur-fast) var(--ease-standard); }

/* Assumptions disclosure */
.scenario-assumptions {
  margin-top: var(--space-4);
  border: 0.0625rem solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
}
.scenario-assumptions > summary {
  list-style: none;
  cursor: pointer;
  padding: var(--space-3) var(--space-4);
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-primary);
}
.scenario-assumptions > summary::-webkit-details-marker { display: none; }
.scenario-assumptions > summary::before {
  content: "\25B8";              /* ▸ */
  color: var(--text-muted);
  transition: transform var(--dur-fast) var(--ease-standard);
}
.scenario-assumptions[open] > summary::before { transform: rotate(90deg); }
.scenario-assumptions > summary:focus-visible {
  outline: 0.125rem solid transparent;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-md);
}
.scenario-assumptions__body {
  padding: 0 var(--space-4) var(--space-4);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  line-height: 1.6;
}
.scenario-illustrative {
  margin-top: var(--space-3);
  font-size: var(--fs-xs);
  font-style: italic;
  color: var(--text-muted);
}

/* ========================================================================
   §4.4  Investor data-room  (.data-room) — sidebar + doc grid + locked overlay
   Structure:
     <div class="data-room">
       <nav class="data-room__rail" aria-label="Document categories"> … </nav>
       <div class="data-room__main"> <ul class="doc-grid"> … </ul> </div>
     </div>
   Locked categories show a .data-room__gate overlay → open-registration.
   (.doc-card / .doc-card--locked live in vc-components.css.)
   ======================================================================== */
.data-room {
  display: grid;
  grid-template-columns: 1fr;     /* mobile-first: stacked */
  gap: var(--space-6);
  margin: var(--space-8) 0;
}
.data-room__rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.data-room__cat {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 2.75rem;
  padding: var(--space-3) var(--space-4);
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}
.data-room__cat:hover { background: var(--bg-surface-2); color: var(--text-primary); }
.data-room__cat[aria-current="true"],
.data-room__cat[aria-selected="true"] {
  background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
  color: var(--accent-primary);
}
.data-room__cat:focus-visible {
  outline: 0.125rem solid transparent;
  box-shadow: var(--focus-ring);
}
/* lock affordance on a gated category in the rail */
.data-room__cat .cat-lock {
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.data-room__cat .cat-lock::before { content: "\1F512"; }   /* 🔒 */

.data-room__main { position: relative; min-width: 0; }
.data-room__panel[hidden] { display: none; }

/* Locked overlay covering a gated panel — tier text + CTA (not colour-alone) */
.data-room__gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  text-align: center;
  padding: var(--space-12) var(--space-6);
  border: 0.0625rem dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-inset);
  color: var(--text-secondary);
}
.data-room__gate-icon {
  font-size: var(--fs-4xl);
  color: var(--text-muted);
  line-height: 1;
}
.data-room__gate-icon::before { content: "\1F512"; }       /* 🔒 */
.data-room__gate-title {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 700;
  color: var(--text-primary);
  margin: 0;
}
/* Tier-access pill. fs-2xs (11px) uppercase = small text, so 4.5:1 applies.
   amber-500 text on the amber-14% tint is only ~2.5:1 in light, so the text
   uses --text-secondary (~6:1 light / ~8.5:1 dark) while the amber/partner
   identity is carried by the tinted fill + amber border + lock icon — colour
   is never the sole carrier (WCAG 1.4.1) and contrast clears AA (WCAG 1.4.3). */
.data-room__gate-tier {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-family: var(--font-data);
  font-size: var(--fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  background: color-mix(in srgb, var(--accent-partner) 14%, transparent);
  border: 0.0625rem solid color-mix(in srgb, var(--accent-partner) 45%, transparent);
}
.data-room__gate p { max-width: 28rem; margin: 0; }

@media (min-width: 64rem) {
  .data-room { grid-template-columns: var(--sidebar-width, 17.5rem) 1fr; }
}

/* ========================================================================
   §4.5  Cap table & dilution  (.cap-table, .dilution-bar)
   Cap table is a .vc-table variant (vc-components.css). The dilution bars
   are 100%-width stacked horizontal bars (pre vs post). Segment widths are
   the ONE sanctioned dynamic style: el.style.setProperty('--w', pct) →
   consumed by width:var(--w) here. Legend carries the meaning (not colour).
   ======================================================================== */
.cap-table { margin: var(--space-6) 0; }   /* applied alongside .vc-table */

.dilution {
  margin: var(--space-8) 0;
  display: grid;
  gap: var(--space-5);
}
.dilution-row {
  display: grid;
  gap: var(--space-2);
}
.dilution-row__label {
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-secondary);
}
.dilution-bar {
  display: flex;
  width: 100%;
  height: 2.25rem;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-surface-2);
  border: 0.0625rem solid var(--border-subtle);
}
.dilution-seg {
  width: var(--w, 0%);          /* set via setProperty('--w', pct) */
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-family: var(--font-data);
  font-size: var(--fs-2xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  /* In-bar % label colour. Per-segment --seg-fg (set below per holder-class /
     per theme) so the figure clears WCAG 1.4.3 AA at fs-2xs (small text) on
     EVERY fill — white only works on the dark fills, so lighter fills flip the
     label to a dark slate. Default = white for unmapped segments. The number is
     role=presentation / aria-hidden in markup; the legend + cap table are the
     accessible source, so this is the visible-polish layer, not the SR path. */
  color: var(--seg-fg, var(--text-on-brand));
  white-space: nowrap;
  transition: width var(--dur-slow) var(--ease-standard);
}
/* Holder-class colours — fixed mapping so legend ↔ bar agree. Semantic
   roles only; legend repeats each label so colour is never the sole carrier.
   --seg-fg sets the in-bar label colour to whichever of white / slate-900
   clears AA on that fill in the LIGHT theme (verified ≥4.5:1 @ fs-2xs):
     founders blue-700  → white     8.72   seriesa violet-600 → white     5.70
     seriesb  green-600 → slate-900 4.74   seed    amber-500  → slate-900 5.60
     advisors muted     → white     5.81   other   slate-300  → slate-900 12.0
   esop (status-info) is the lone residual — see the esop rule + flags. */
.dilution-seg--founders { background: var(--accent-primary);   --seg-fg: var(--text-on-brand); }
.dilution-seg--seriesb  { background: var(--accent-secondary); --seg-fg: var(--slate-900); }
.dilution-seg--seriesa  { background: var(--accent-tertiary);  --seg-fg: var(--text-on-brand); }
.dilution-seg--seed     { background: var(--accent-partner);   --seg-fg: var(--slate-900); }
.dilution-seg--esop     { background: var(--status-info);      --seg-fg: var(--slate-900); }
.dilution-seg--advisors { background: var(--text-muted);       --seg-fg: var(--text-on-brand); }
.dilution-seg--other    { background: var(--border-strong);    --seg-fg: var(--slate-900); }

/* Dark theme: the accents lighten to mid-tones (accent-*-400), so the label
   flips per fill again. Verified ≥4.5:1 @ fs-2xs against the dark fills:
     founders blue-400  → slate-900 5.74   seriesa violet-400 → slate-900 6.56
     seriesb  green-400 → slate-900 9.29   seed    amber-400  → slate-900 8.31
     advisors muted-d   → slate-900 6.96   other   slate-600  → white     7.58
   (slate-900 is a fixed-dark raw token, so it stays dark in both themes —
   unlike --text-primary, which inverts to light here.) esop: see flags. */
[data-theme="dark"] .dilution-seg--founders { --seg-fg: var(--slate-900); }
[data-theme="dark"] .dilution-seg--seriesb  { --seg-fg: var(--slate-900); }
[data-theme="dark"] .dilution-seg--seriesa  { --seg-fg: var(--slate-900); }
[data-theme="dark"] .dilution-seg--seed     { --seg-fg: var(--slate-900); }
[data-theme="dark"] .dilution-seg--esop     { --seg-fg: var(--text-on-brand); }
[data-theme="dark"] .dilution-seg--advisors { --seg-fg: var(--slate-900); }
[data-theme="dark"] .dilution-seg--other    { --seg-fg: var(--text-on-brand); }

.dilution-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
}
.dilution-legend li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.dilution-legend .swatch {
  width: 0.875rem;
  height: 0.875rem;
  border-radius: var(--radius-xs);
  flex-shrink: 0;
}

/* ========================================================================
   §4.6  NEXUS-agent visual  (.nexus-hub) — central node + radiating pillars
   Repositions the old "AI concierge hub" as a per-member NEXUS agent backed
   by healthhaven.ai. Reduced-motion-safe glow. Variants: --orbit, --stack.
   ======================================================================== */
.nexus-hub {
  position: relative;
  margin: var(--space-8) 0;
  padding: var(--space-8) var(--space-6);
  border-radius: var(--radius-xl);
  background: var(--bg-surface);
  border: 0.0625rem solid var(--border-subtle);
  text-align: center;
  isolation: isolate;
  overflow: hidden;
}
.nexus-hub::before {              /* AI glow backdrop (decorative) */
  content: "";
  position: absolute;
  inset: 0;
  background: var(--grad-glow-ai);
  z-index: -1;
  pointer-events: none;
}
.nexus-core {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  width: 9rem;
  height: 9rem;
  margin: 0 auto var(--space-6);
  border-radius: 50%;
  background: var(--grad-ai);
  color: var(--text-on-brand);
  box-shadow: var(--shadow-lg);
  position: relative;
}
/* pulsing glow ring — paused under reduced-motion */
.nexus-core::after {
  content: "";
  position: absolute;
  inset: -0.5rem;
  border-radius: 50%;
  border: 0.125rem solid var(--accent-tertiary);
  opacity: 0.5;
  animation: nexus-pulse 2.8s var(--ease-standard) infinite;
}
@keyframes nexus-pulse {
  0%   { transform: scale(1);    opacity: 0.5; }
  70%  { transform: scale(1.18); opacity: 0; }
  100% { transform: scale(1.18); opacity: 0; }
}
.nexus-core__label {
  font-family: var(--font-data);
  font-size: var(--fs-lg);
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--text-on-brand);
}
.nexus-core__sub {
  font-family: var(--font-data);
  font-size: var(--fs-2xs);
  color: var(--text-on-brand-dim);
}

/* Radiating pillar chips around the core */
.nexus-pillars {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 40rem;
}
.nexus-pillar {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--bg-surface-2);
  border: 0.0625rem solid var(--border-subtle);
  font-family: var(--font-data);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-secondary);
}
.nexus-pillar .nexus-pillar__icon { color: var(--accent-tertiary); }
.nexus-caption {
  margin-top: var(--space-5);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.nexus-caption .healthhaven {
  font-weight: 700;
  color: var(--accent-secondary);
}

/* Orbit variant (pitch deck): pillars positioned around the core.
   Falls back gracefully to the flex flow on small screens. */
@media (min-width: 48rem) {
  .nexus-hub--orbit .nexus-pillars {
    position: relative;
    min-height: 4rem;
  }
}
/* Stack variant (mobile/print): purely vertical, no orbit, glow off */
.nexus-hub--stack .nexus-core::after { animation: none; opacity: 0.35; }
.nexus-hub--stack .nexus-pillars { flex-direction: column; align-items: stretch; }

/* ========================================================================
   Reduced motion — stop the NEXUS pulse and dilution grow; charts/data
   render statically. (Global blanket also applies via vc-tokens/vc-base.)
   ======================================================================== */
@media (prefers-reduced-motion: reduce) {
  .nexus-core::after { animation: none; opacity: 0.35; }
  .dilution-seg { transition: none; }
  .scenario-swap.is-updating { transition: none; }
}

/* ========================================================================
   Print — flatten gradients/shadows, keep the accessible content.
   Diagrams stay on one page; the dilution bars and cap table print as-is.
   ======================================================================== */
@media print {
  .b2b2c-flow,
  .nexus-hub,
  .embed-frame,
  .dilution,
  .data-room { page-break-inside: avoid; box-shadow: none; }
  .embed-toggle,
  .scenario-controls,
  .scenario-assumptions > summary::before { display: none; }
  /* print the Base scenario as rendered; note added in markup per spec */
  .scenario-assumptions { border: none; }
  .nexus-core::after { display: none; }
  .data-room { grid-template-columns: 1fr; }
}
