/* MunaComponents.jsx — shared primitives for the Muna Health UI kit
   Exports to window: Button, NavTop, BottomCTA, TabBar, Chip, Card, ScoreRing,
   BreakdownBar, Field, RadioOption, CheckOption, Icon, Stepper, ProgressDots */

// ─── Icon — Lucide via static URL ───────────────────────────────────────
function Icon({ name, size = 20, color = 'currentColor', strokeWidth = 1.75, style = {} }) {
  // Inline Lucide-style strokes — small subset we use across the kit.
  const paths = {
    'chevron-left':  'M15 18l-6-6 6-6',
    'chevron-right': 'M9 18l6-6-6-6',
    'x':             'M18 6L6 18 M6 6l12 12',
    'check':         'M20 6L9 17l-5-5',
    'plus':          'M12 5v14 M5 12h14',
    'more':          'M5 12h.01 M12 12h.01 M19 12h.01',
    'arrow-right':   'M5 12h14 M13 5l7 7-7 7',
    'arrow-up':      'M12 19V5 M5 12l7-7 7 7',
    'bell':          'M6 8a6 6 0 0112 0c0 7 3 9 3 9H3s3-2 3-9 M10 21a2 2 0 004 0',
    'flame':         'M8.5 14c0-3 3.5-5 3.5-9 0 0 5 3 5 8a5 5 0 11-10 0c0 .5.2 1 .5 1.5',
    'gauge':         'M12 14l4-4 M3.34 17A10 10 0 1120.66 17',
    'sprout':        'M12 19V11 M5 11s7-4 7 4c0 0-7 0-7-4z M19 11s-7-4-7 4c0 0 7 0 7-4z',
    'sun':           'M12 2v2 M12 20v2 M4.93 4.93l1.41 1.41 M17.66 17.66l1.41 1.41 M2 12h2 M20 12h2 M4.93 19.07l1.41-1.41 M17.66 6.34l1.41-1.41',
    'siren':         'M7 18v-6a5 5 0 0110 0v6 M5 21h14 M12 2v2 M4 11h2 M18 11h2 M5.99 5.99l1.41 1.41 M17.66 6.34l1.41-1.41',
    'heart':         'M19 14c1.5-1.5 3-3.2 3-5.5A5.5 5.5 0 0016.5 3c-1.8 0-3 .5-4.5 2-1.5-1.5-2.7-2-4.5-2A5.5 5.5 0 002 8.5c0 2.3 1.5 4 3 5.5l7 7z',
    'award':         'M7 4v8a5 5 0 0010 0V4 M5 4h14 M8 21h8 M12 17v4',
    'camera':        'M14 4h-4l-2 3H4a2 2 0 00-2 2v9a2 2 0 002 2h16a2 2 0 002-2V9a2 2 0 00-2-2h-4l-2-3z M12 17a4 4 0 100-8 4 4 0 000 8z',
    'video':         'M22 8l-6 4 6 4V8z M2 6h12a2 2 0 012 2v8a2 2 0 01-2 2H2z',
    'book':          'M2 3h7a4 4 0 014 4v14a3 3 0 00-3-3H2z M22 3h-7a4 4 0 00-4 4v14a3 3 0 013-3h8z',
    'book-open':     'M12 7v14 M3 18a1 1 0 01-1-1V4a1 1 0 011-1h5a4 4 0 014 4 4 4 0 014-4h5a1 1 0 011 1v13a1 1 0 01-1 1h-6a3 3 0 00-3 3 3 3 0 00-3-3z',
    'activity':      'M3 12h4l3-9 4 18 3-9h4',
    'user':          'M12 12a4 4 0 100-8 4 4 0 000 8z M4 21a8 8 0 0116 0',
    'home':          'M3 9.5L12 3l9 6.5V21h-6v-7h-6v7H3z',
    'shield':        'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',
    'calendar':      'M3 7a2 2 0 012-2h14a2 2 0 012 2v13a2 2 0 01-2 2H5a2 2 0 01-2-2z M3 11h18 M8 3v4 M16 3v4',
    'map-pin':       'M12 22s7-7 7-12a7 7 0 10-14 0c0 5 7 12 7 12z M12 11a2 2 0 100-4 2 2 0 000 4z',
    'test-tube':     'M14 2v18a3 3 0 11-6 0V2 M8 2h8 M8 12h6',
    'lock':          'M5 11h14v10H5z M8 11V7a4 4 0 018 0v4',
    'sparkles':      'M12 3v4 M12 17v4 M3 12h4 M17 12h4 M6 6l2 2 M16 16l2 2 M6 18l2-2 M16 8l2-2',
    'alert-triangle':'M10.29 3.86 1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z M12 9v4 M12 17h.01',
    'check-circle':  'M22 11.08V12a10 10 0 11-5.93-9.14 M22 4 12 14.01l-3-3',
    'circle':        'M12 22a10 10 0 100-20 10 10 0 000 20z',
    'clock':         'M12 22a10 10 0 100-20 10 10 0 000 20z M12 6v6l4 2',
    'eye':           'M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z M12 15a3 3 0 100-6 3 3 0 000 6z',
    'file-text':     'M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6 M8 13h8 M8 17h8 M8 9h2',
    'flag':          'M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z M4 22v-7',
    'git-branch':    'M6 3v12 M18 9a3 3 0 100-6 3 3 0 000 6z M6 21a3 3 0 100-6 3 3 0 000 6z M15 6a9 9 0 01-9 9',
    'help-circle':   'M12 22a10 10 0 100-20 10 10 0 000 20z M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3 M12 17h.01',
    'mic':           'M12 2a3 3 0 00-3 3v7a3 3 0 006 0V5a3 3 0 00-3-3z M19 10v2a7 7 0 01-14 0v-2 M12 19v3',
    'phone':         'M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72c.13.96.36 1.9.7 2.81a2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0122 16.92z',
    'phone-off':     'M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72c.13.96.36 1.9.7 2.81a2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0122 16.92z M2 2l20 20',
    'pill':          'M10.5 20.5 20 11a4.95 4.95 0 10-7-7L3.5 13.5a4.95 4.95 0 107 7z M8.5 8.5l7 7',
    'shuffle':       'M16 3h5v5 M4 20 21 3 M21 16v5h-5 M15 15l6 6 M4 4l5 5',
    'rotate-ccw':    'M3 2v6h6 M3.51 15a9 9 0 102.13-9.36L3 8',
    'play':          'M6 3l14 9-14 9z',
    'play-circle':   'M12 22a10 10 0 100-20 10 10 0 000 20z M10 8l6 4-6 4z',
    'star':          'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14l-5-4.87 6.91-1.01z',
    'shopping-bag':  'M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z M3 6h18 M16 10a4 4 0 01-8 0',
    'target':        'M12 22a10 10 0 100-20 10 10 0 000 20z M12 18a6 6 0 100-12 6 6 0 000 12z M12 14a2 2 0 100-4 2 2 0 000 4z',
    'settings':      'M12 15a3 3 0 100-6 3 3 0 000 6z M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09a1.65 1.65 0 00-1-1.51 1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09a1.65 1.65 0 001.51-1 1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z',
  };
  const d = paths[name] || '';
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={color} strokeWidth={strokeWidth}
      strokeLinecap="round" strokeLinejoin="round"
      style={{ display: 'block', ...style }}>
      {d.split(' M').map((seg, i) => (
        <path key={i} d={(i === 0 ? '' : 'M') + seg} />
      ))}
    </svg>
  );
}

// ─── Button ─────────────────────────────────────────────────────────────
function Button({ children, variant = 'primary', onClick, onDisabledClick, glow = false, disabled = false, leftIcon, rightIcon, full = false, style = {} }) {
  const base = {
    font: 'var(--type-button)',
    borderRadius: 'var(--radius-pill)',
    padding: '15px 26px',
    border: 0,
    cursor: disabled ? 'not-allowed' : 'pointer',
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 8,
    width: full ? '100%' : undefined,
    transition: 'transform 80ms var(--ease-out)',
    ...style,
  };
  const variants = {
    primary: { backgroundColor: 'var(--amber-500)', color: '#fff', boxShadow: glow ? 'var(--shadow-glow-amber)' : 'none' },
    secondary: { background: 'transparent', color: 'var(--stone-700)', border: '1.5px solid var(--stone-400)', padding: '13.5px 24.5px' },
    ghost: { background: 'var(--stone-100)', color: 'var(--stone-700)' },
    tertiary: { background: 'transparent', color: 'var(--amber-600)', padding: '15px 8px' },
    danger: { background: 'var(--clay-500)', color: '#fff' },
    inverse: { background: '#fff', color: 'var(--stone-800)' },
  };
  if (disabled) {
    variants.primary = { backgroundColor: 'var(--stone-300)', color: 'var(--stone-500)', boxShadow: 'none' };
  }
  return (
    <button style={{ ...base, ...variants[variant], ...style }}
      onMouseDown={e => !disabled && (e.currentTarget.style.transform = 'scale(0.98)')}
      onMouseUp={e => (e.currentTarget.style.transform = 'scale(1)')}
      onMouseLeave={e => (e.currentTarget.style.transform = 'scale(1)')}
      onClick={disabled ? onDisabledClick : onClick}>
      {leftIcon && <Icon name={leftIcon} size={18}/>}
      {children}
      {rightIcon && <Icon name={rightIcon} size={18}/>}
    </button>
  );
}

// ─── NavTop — back chevron, centered title, optional right action ──────
// Includes a 47px top inset to clear the iOS status bar / dynamic island.
function NavTop({ title, onBack, right, transparent = false, light = false, topInset = 47 }) {
  const fg = light ? '#fff' : 'var(--fg-1)';
  return (
    <div style={{
      height: 'var(--nav-bar-h)', padding: '0 8px',
      paddingTop: topInset, boxSizing: 'content-box',
      display: 'grid', gridTemplateColumns: '44px 1fr 44px', alignItems: 'center',
      background: transparent ? 'transparent' : 'var(--bg)',
      borderBottom: transparent ? 'none' : '1px solid var(--border-subtle)',
      color: fg, flexShrink: 0,
    }}>
      <div>{onBack && (
        <button onClick={onBack} style={{ background: 'transparent', border: 0, color: fg, width: 44, height: 44, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
          <Icon name="chevron-left" size={24}/>
        </button>
      )}</div>
      <div style={{ font: 'var(--type-h2)', textAlign: 'center', color: fg }}>{title}</div>
      <div style={{ display: 'flex', justifyContent: 'flex-end' }}>{right}</div>
    </div>
  );
}

// ─── BottomCTA — pinned bottom CTA wrapper ─────────────────────────────
function BottomCTA({ children, withSecondary }) {
  return (
    <div style={{
      position: 'absolute', bottom: 34, left: 0, right: 0,
      padding: '12px var(--gutter-screen) 14px',
      display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'center',
      background: 'linear-gradient(180deg, rgba(250,248,245,0) 0%, var(--bg) 28%)',
    }}>
      {children}
    </div>
  );
}

// ─── TabBar ─────────────────────────────────────────────────────────────
function TabBar({ active = 'home', onChange = () => {} }) {
  const tabs = [
    { id: 'home', label: 'Home', icon: 'home' },
    { id: 'learn', label: 'Learn', icon: 'book' },
    { id: 'activity', label: 'Activity', icon: 'activity' },
    { id: 'profile', label: 'Profile', icon: 'user' },
  ];
  return (
    <div style={{
      position: 'absolute', bottom: 34, left: 12, right: 12,
      background: 'rgba(250, 248, 245, 0.88)',
      backdropFilter: 'blur(14px) saturate(160%)',
      WebkitBackdropFilter: 'blur(14px) saturate(160%)',
      borderRadius: 22, border: '1px solid var(--border-subtle)',
      padding: '10px 6px 10px', display: 'flex', justifyContent: 'space-around',
      boxShadow: 'var(--shadow-s)',
    }}>
      {tabs.map(t => (
        <button key={t.id} onClick={() => onChange(t.id)} style={{
          background: 'transparent', border: 0, cursor: 'pointer',
          display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
          padding: '4px 14px',
          color: active === t.id ? 'var(--amber-600)' : 'var(--fg-3)',
        }}>
          <Icon name={t.icon} size={22} strokeWidth={active === t.id ? 2 : 1.75}/>
          <div style={{ font: 'var(--type-caption)', fontWeight: active === t.id ? 600 : 500 }}>{t.label}</div>
        </button>
      ))}
    </div>
  );
}

// ─── Chip ───────────────────────────────────────────────────────────────
function Chip({ children, variant = 'neutral', leftDot = true }) {
  const styles = {
    healthy: { bg: 'var(--sage-50)', fg: 'var(--sage-700)', dot: 'var(--sage-500)' },
    moderate: { bg: 'var(--amber-50)', fg: 'var(--amber-700)', dot: 'var(--amber-500)' },
    high: { bg: 'var(--clay-50)', fg: 'var(--clay-700)', dot: 'var(--clay-500)' },
    neutral: { bg: 'var(--stone-100)', fg: 'var(--stone-700)', dot: 'var(--stone-500)' },
    urgent: { bg: 'var(--clay-500)', fg: '#fff', dot: '#fff' },
  };
  const s = styles[variant];
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '6px 12px', borderRadius: 'var(--radius-pill)',
      background: s.bg, color: s.fg, font: 'var(--type-label)', whiteSpace: 'nowrap',
    }}>
      {leftDot && <div style={{ width: 8, height: 8, borderRadius: '50%', background: s.dot }}/>}
      {children}
    </div>
  );
}

// ─── Card ───────────────────────────────────────────────────────────────
function Card({ children, elevation = 's', padding = 16, style = {}, onClick }) {
  return (
    <div onClick={onClick} style={{
      background: '#fff',
      borderRadius: 'var(--radius-m)',
      boxShadow: `var(--shadow-${elevation})`,
      padding,
      cursor: onClick ? 'pointer' : undefined,
      ...style,
    }}>{children}</div>
  );
}

// ─── OS-HRS SCALE — SYSTEM-LEVEL RULE (inverted: higher = healthier) ───
//   70–100 → healthy · 41–69 → moderate · 0–40 → high risk
//   Baked in here so no screen re-specifies tier logic. tierForScore() is the
//   single source of truth; ScoreRing & ScoreBreakdownBars both read from it.
const OS_HRS = {
  tiers: {
    healthy:  { min: 70, max: 100, color: 'var(--path-healthy)',  band: 'var(--band-healthy)',  label: 'Healthy' },
    moderate: { min: 41, max: 69,  color: 'var(--path-moderate)', band: 'var(--band-moderate)', label: 'Moderate' },
    high:     { min: 0,  max: 40,  color: 'var(--path-high)',     band: 'var(--band-high)',     label: 'High risk' },
  },
};
function tierForScore(score) {
  if (score >= OS_HRS.tiers.healthy.min)  return 'healthy';
  if (score >= OS_HRS.tiers.moderate.min) return 'moderate';
  return 'high';
}

// ─── ScoreRing — animated arc + serif numeral ──────────────────────────
//   Tier is DERIVED from the score by default (system rule); pass `variant`
//   only to force a colour against the scale (rare).
function ScoreRing({ score = 0, variant, size = 200, animate = false }) {
  const tier = variant || tierForScore(score);
  const stroke = 10;
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const pct = Math.min(score, 100) / 100;
  const offset = c * (1 - pct);
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} stroke="var(--stone-200)" strokeWidth={stroke} fill="none"/>
        <circle cx={size/2} cy={size/2} r={r} stroke={OS_HRS.tiers[tier].color} strokeWidth={stroke} fill="none"
          strokeDasharray={c} strokeDashoffset={offset} strokeLinecap="round"
          style={{ transition: animate ? 'stroke-dashoffset var(--dur-reveal) var(--ease-out)' : 'none' }}/>
      </svg>
      <div style={{
        position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center',
      }}>
        <div style={{ font: '700 ' + Math.round(size * 0.42) + 'px/0.95 var(--font-serif)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-tight)' }}>{Math.round(score)}</div>
        <div style={{ font: 'var(--type-overline)', letterSpacing: 'var(--tracking-loose)', textTransform: 'uppercase', color: 'var(--fg-3)', marginTop: 2 }}>of 100</div>
      </div>
    </div>
  );
}

// ─── BreakdownBar ─────────────────────────────────────────────────────
function BreakdownBar({ name, value, color = 'var(--path-healthy)' }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
      <div style={{ font: 'var(--type-label)', color: 'var(--fg-1)', width: 78 }}>{name}</div>
      <div style={{ flex: 1, height: 10, borderRadius: 6, background: 'var(--stone-100)', overflow: 'hidden' }}>
        <div style={{ width: value + '%', height: '100%', background: color, borderRadius: 6, transition: 'width var(--dur-slow) var(--ease-out)' }}/>
      </div>
      <div style={{ font: '600 13px/1 var(--font-sans)', color: 'var(--fg-2)', width: 56, textAlign: 'right' }}>{value} / 100</div>
    </div>
  );
}

// ─── ScoreBreakdownBars — the shared 3-bar result pattern ──────────────
//   Appears on EVERY result tier (healthy / moderate / high). Built once.
//   Labels are fixed: Oral Health, General Health, Lifestyle Factors.
//   Bar colour derives from the OVERALL tier via the OS-HRS scale unless a
//   `tier`/`color` is passed. Values are each out of 100.
function ScoreBreakdownBars({ oral, general, lifestyle, tier, color }) {
  const overall = Math.round((oral + general + lifestyle) / 3);
  const fill = color || OS_HRS.tiers[tier || tierForScore(overall)].color;
  const rows = [
    { name: 'Oral Health',       value: oral },
    { name: 'General Health',    value: general },
    { name: 'Lifestyle Factors', value: lifestyle },
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {rows.map(r => (
        <div key={r.name} style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div style={{ font: 'var(--type-label)', color: 'var(--fg-1)' }}>{r.name}</div>
            <div style={{ font: '600 13px/1 var(--font-sans)', color: 'var(--fg-2)' }}>{r.value} <span style={{ color: 'var(--fg-4)', fontWeight: 400 }}>/ 100</span></div>
          </div>
          <div style={{ height: 10, borderRadius: 6, background: 'var(--stone-100)', overflow: 'hidden' }}>
            <div style={{ width: r.value + '%', height: '100%', background: fill, borderRadius: 6, transition: 'width var(--dur-slow) var(--ease-out)' }}/>
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Field & choice options ───────────────────────────────────────────
function Field({ label, value, hint, error, focused }) {
  const border = error ? 'var(--clay-500)' : focused ? 'var(--amber-500)' : 'var(--border-default)';
  const bw = focused || error ? 2 : 1;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <div style={{ font: 'var(--type-label)', color: 'var(--fg-2)' }}>{label}</div>
      <div style={{
        font: 'var(--type-body)', padding: `${15 - (bw - 1)}px ${16 - (bw - 1)}px`,
        borderRadius: 'var(--radius-m)', border: `${bw}px solid ${border}`,
        background: '#fff', color: 'var(--fg-1)',
        boxShadow: focused ? 'var(--focus-ring)' : 'none',
      }}>{value || <span style={{ color: 'var(--fg-4)' }}>Type here…</span>}</div>
      {hint && <div style={{ font: 'var(--type-body-s)', color: error ? 'var(--clay-500)' : 'var(--fg-3)' }}>{hint}</div>}
    </div>
  );
}

function RadioOption({ label, sub, selected, onClick }) {
  return (
    <button onClick={onClick} style={{
      background: selected ? 'var(--amber-50)' : '#fff',
      border: selected ? '2px solid var(--amber-500)' : '1px solid var(--border-subtle)',
      padding: selected ? '13px 15px' : '14px 16px',
      borderRadius: 'var(--radius-m)', width: '100%',
      display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer', textAlign: 'left',
    }}>
      <div style={{
        width: 20, height: 20, borderRadius: '50%', flexShrink: 0,
        border: selected ? '6px solid var(--amber-500)' : '1.5px solid var(--stone-400)',
      }}/>
      <div style={{ flex: 1 }}>
        <div style={{ font: 'var(--type-body)', color: 'var(--fg-1)' }}>{label}</div>
        {sub && <div style={{ font: 'var(--type-body-s)', color: 'var(--fg-3)', marginTop: 2 }}>{sub}</div>}
      </div>
    </button>
  );
}

function CheckOption({ label, sub, selected, onClick }) {
  return (
    <button onClick={onClick} style={{
      background: selected ? 'var(--amber-50)' : '#fff',
      border: selected ? '2px solid var(--amber-500)' : '1px solid var(--border-subtle)',
      padding: selected ? '13px 15px' : '14px 16px',
      borderRadius: 'var(--radius-m)', width: '100%',
      display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer', textAlign: 'left',
    }}>
      <div style={{
        width: 22, height: 22, borderRadius: 6, flexShrink: 0,
        background: selected ? 'var(--amber-500)' : 'transparent',
        border: selected ? '0' : '1.5px solid var(--stone-400)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff',
      }}>{selected && <Icon name="check" size={14} strokeWidth={3}/>}</div>
      <div style={{ flex: 1 }}>
        <div style={{ font: 'var(--type-body)', color: 'var(--fg-1)' }}>{label}</div>
        {sub && <div style={{ font: 'var(--type-body-s)', color: 'var(--fg-3)', marginTop: 2 }}>{sub}</div>}
      </div>
    </button>
  );
}

// ─── ProgressDots — onboarding 1/3 etc ──────────────────────────────
function ProgressDots({ count, index, color = 'var(--amber-500)' }) {
  return (
    <div style={{ display: 'flex', gap: 6, justifyContent: 'center' }}>
      {Array.from({ length: count }).map((_, i) => (
        <div key={i} style={{
          width: i === index ? 20 : 6, height: 6, borderRadius: 3,
          background: i === index ? color : 'var(--stone-300)',
          transition: 'all var(--dur-base) var(--ease-out)',
        }}/>
      ))}
    </div>
  );
}

// ─── Stepper — top progress for questionnaire (Step 4 of 7) ─────────
function Stepper({ index, count }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <div style={{ flex: 1, height: 4, background: 'var(--stone-200)', borderRadius: 2, overflow: 'hidden' }}>
        <div style={{ height: '100%', width: ((index + 1) / count * 100) + '%', background: 'var(--amber-500)', borderRadius: 2, transition: 'width var(--dur-base) var(--ease-out)' }}/>
      </div>
      <div style={{ font: 'var(--type-caption)', color: 'var(--fg-3)', whiteSpace: 'nowrap' }}>Step {index + 1} of {count}</div>
    </div>
  );
}

Object.assign(window, { Icon, Button, NavTop, BottomCTA, TabBar, Chip, Card, ScoreRing, BreakdownBar, ScoreBreakdownBars, tierForScore, OS_HRS, Field, RadioOption, CheckOption, ProgressDots, Stepper });
