/* My Vital Cell — Floating "Get in Touch" CTA
   Self-contained overlay: animated dot-grid-headset agent icon, popup with
   Contact Us + Custom Plan Builder (persona-aware), inline captcha in chat,
   markdown rendering, plan-context handoff to AI. */

(function () {
  const { useState, useEffect, useRef, useMemo } = React;

  /* ---------- Mobile popup fix (viewport-safe, keyboard-safe) ---------- */
  if (typeof document !== 'undefined' && !document.getElementById('mvc-cta-mobile-css')) {
    const s = document.createElement('style');
    s.id = 'mvc-cta-mobile-css';
    s.textContent = `
      @media (max-width: 720px) {
        .mvc-cta-popup {
          width: 96vw !important;
          height: min(88vh, 88dvh) !important;
          min-width: 0 !important;
          min-height: 0 !important;
          max-width: 96vw !important;
          border-radius: 20px !important;
        }
        .mvc-cta-popup > div { border-radius: 18px !important; }
      }
      @supports (height: 100dvh) {
        @media (max-width: 720px) {
          .mvc-cta-popup { height: 88dvh !important; }
        }
      }
    `;
    document.head.appendChild(s);
  }

  /* ---------- Client-side mirror of src/lib/mvc-agent (personas + catalog) ---------- */
  const PERSONAS = [
    { key: 'biohacker', label: 'The Biohacker', desc: 'Quantified-self, stack optimizer, reads the papers.',
      color: '#7A5CC6', emoji: '🧬', goals: ['longevity', 'cognitive', 'metabolic'] },
    { key: 'athlete', label: 'The Athlete', desc: 'Trains hard, needs recovery and edge.',
      color: '#0F5B60', emoji: '🏋️', goals: ['recovery', 'metabolic', 'longevity'] },
    { key: 'aesthetic', label: 'Skin & Hair', desc: 'Focused on visible results — glow, thickness, post-procedure.',
      color: '#E24A63', emoji: '✨', goals: ['regeneration'] },
    { key: 'founder', label: 'The Executive', desc: 'High-output, cognitive edge, resilient sleep.',
      color: '#3A6EA5', emoji: '⚡', goals: ['cognitive', 'longevity', 'metabolic'] },
    { key: 'longevity', label: 'Healthy Aging', desc: 'Playing the long game — mitochondria, resilience, prevention.',
      color: '#C9A84C', emoji: '🌿', goals: ['longevity', 'regeneration', 'metabolic'] },
    { key: 'recovery-injury', label: 'Injury Recovery', desc: 'Rehabbing something specific and want it healed right.',
      color: '#2F855A', emoji: '🩹', goals: ['recovery'] },
  ];

  const CATALOG = [
    { slug: 'ghk-cu', name: 'GHK-Cu Copper Peptide', cat: 'regeneration', catLabel: 'Regeneration', route: 'topical', price: 79, beginner: true,
      blurb: 'Copper tripeptide — signals repair and remodeling.',
      protocol: '2mg/mL serum, AM/PM to clean skin', timing: 'Daily; visible change by week 6.',
      rationale: 'Studied for collagen synthesis and follicle stimulation.' },
    { slug: 'bpc-blend', name: 'BPC-157 + TB-500 Blend', cat: 'regeneration', catLabel: 'Regeneration', route: 'inj', price: 189,
      blurb: 'Synergy blend for skin/hair regeneration.',
      protocol: '250mcg SC daily, 4 weeks on / 2 off', timing: 'Morning, empty stomach.',
      rationale: 'Repair vascularization + tissue remodeling.' },
    { slug: 'bpc-157', name: 'BPC-157', cat: 'recovery', catLabel: 'Recovery', route: 'inj', price: 99, beginner: true,
      blurb: 'The most-studied tissue-repair peptide.',
      protocol: '250–500mcg SC daily near site, 4–6 weeks', timing: 'Post-training or bedtime.',
      rationale: 'Angiogenic; tendon/ligament/gut healing pathways.' },
    { slug: 'tb-500', name: 'TB-500 (Thymosin β4)', cat: 'recovery', catLabel: 'Recovery', route: 'inj', price: 149,
      blurb: 'Slower-acting recovery peptide.',
      protocol: '2mg 2×/wk × 4 weeks, then 2mg weekly', timing: 'Split doses across the week.',
      rationale: 'Actin modulation — cell migration and repair.' },
    { slug: 'kpv', name: 'KPV Anti-Inflammatory', cat: 'recovery', catLabel: 'Recovery', route: 'oral', price: 89, beginner: true,
      blurb: 'Oral tripeptide for systemic + gut inflammation.',
      protocol: '500mcg oral daily', timing: 'Morning with water.',
      rationale: 'α-MSH fragment — NF-κB pathway.' },
    { slug: 'aod-9604', name: 'AOD-9604', cat: 'metabolic', catLabel: 'Metabolic', route: 'inj', price: 109, beginner: true,
      blurb: 'GH fragment — fat metabolism without GH side effects.',
      protocol: '300mcg SC daily, fasted AM', timing: '30 min before food.',
      rationale: 'Targets lipolysis without affecting IGF-1.' },
    { slug: 'tesofensine', name: 'Tesofensine Research Kit', cat: 'metabolic', catLabel: 'Metabolic', route: 'oral', price: 179,
      blurb: 'Advanced-only appetite research compound.',
      protocol: 'Micro-doses, 4 weeks on / 4 off, HR monitoring', timing: 'Morning only.',
      rationale: 'Triple monoamine reuptake — cardio caution.' },
    { slug: 'epithalon', name: 'Epithalon', cat: 'longevity', catLabel: 'Longevity', route: 'inj', price: 129, beginner: true,
      blurb: 'Pineal peptide — telomerase + circadian regulation.',
      protocol: '10mg SC daily × 10 days, twice yearly', timing: 'Evening before sleep.',
      rationale: 'Studied for telomerase and melatonin rhythm.' },
    { slug: 'mots-c', name: 'MOTS-c', cat: 'longevity', catLabel: 'Longevity', route: 'inj', price: 149,
      blurb: 'Mitochondrial-derived — metabolic + longevity.',
      protocol: '10mg SC 2–3×/wk × 6 weeks', timing: 'Pre-training days.',
      rationale: 'AMPK activator; improves insulin sensitivity.' },
    { slug: 'semax', name: 'Semax Nasal', cat: 'cognitive', catLabel: 'Cognitive', route: 'topical', price: 89, beginner: true,
      blurb: 'Intranasal nootropic — focus + neuroprotection.',
      protocol: '300–600mcg intranasal, AM only', timing: 'Up to 5 days/week.',
      rationale: 'Increases BDNF; no HPA activation.' },
    { slug: 'selank', name: 'Selank Nasal', cat: 'cognitive', catLabel: 'Cognitive', route: 'topical', price: 89, beginner: true,
      blurb: 'Anxiolytic nootropic — calm focus.',
      protocol: '300mcg intranasal 1–2×/day', timing: 'AM + midday if needed.',
      rationale: 'GABA + enkephalin modulation.' },
  ];

  const BUDGET_CAP = { low: 175, mid: 425, high: 900 };

  /* ---------- Minimal Markdown → JSX (bold, bullets, line breaks, headers) ---------- */
  function Markdown({ text }) {
    const lines = String(text || '').split('\n');
    const blocks = [];
    let list = null;
    const flush = () => { if (list) { blocks.push(list); list = null; } };
    lines.forEach((raw, i) => {
      const line = raw.replace(/\s+$/, '');
      if (/^\s*[-•]\s+/.test(line)) {
        if (!list) list = { type: 'ul', items: [] };
        list.items.push(line.replace(/^\s*[-•]\s+/, ''));
      } else if (/^#{1,3}\s+/.test(line)) {
        flush();
        const level = line.match(/^#+/)[0].length;
        blocks.push({ type: 'h', level, text: line.replace(/^#+\s+/, '') });
      } else if (line.trim() === '') {
        flush();
        blocks.push({ type: 'br' });
      } else {
        flush();
        blocks.push({ type: 'p', text: line });
      }
    });
    flush();
    const inline = (s) => {
      // **bold** then `code` — safe minimal parser
      const parts = [];
      const re = /\*\*(.+?)\*\*/g;
      let last = 0, m;
      while ((m = re.exec(s))) {
        if (m.index > last) parts.push(s.slice(last, m.index));
        parts.push(<strong key={parts.length}>{m[1]}</strong>);
        last = m.index + m[0].length;
      }
      if (last < s.length) parts.push(s.slice(last));
      return parts;
    };
    return (
      <div>
        {blocks.map((b, i) => {
          if (b.type === 'h') return React.createElement('div', { key: i, style: { fontWeight: 700, fontSize: 14, margin: '4px 0' } }, inline(b.text));
          if (b.type === 'ul') return <ul key={i} style={{ margin: '4px 0 4px 16px', padding: 0 }}>{b.items.map((it, j) => <li key={j} style={{ margin: '2px 0' }}>{inline(it)}</li>)}</ul>;
          if (b.type === 'br') return <div key={i} style={{ height: 6 }} />;
          return <div key={i}>{inline(b.text)}</div>;
        })}
      </div>
    );
  }

  /* ---------- Animated Dot-Grid + Headset Agent Icon ---------- */
  function AgentIcon({ size = 22, tone = 'auto' }) {
    const ref = useRef(null);
    useEffect(() => {
      let raf = 0;
      const dots = ref.current?.querySelectorAll('circle.dot') || [];
      const start = performance.now();
      const tick = (t) => {
        const dt = (t - start) / 1000;
        dots.forEach((d, i) => {
          const r = parseFloat(d.dataset.br);
          const col = i % 5, row = (i / 5) | 0;
          const wave = 0.5 + 0.5 * Math.sin(dt * 1.6 + (col + row) * 0.55);
          d.setAttribute('r', (r * (0.75 + wave * 0.5)).toFixed(2));
          d.setAttribute('opacity', (0.45 + wave * 0.55).toFixed(2));
        });
        raf = requestAnimationFrame(tick);
      };
      raf = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf);
    }, []);
    const stroke = tone === 'light' ? '#fff' : 'currentColor';
    const s = size;
    return (
      <svg ref={ref} width={s} height={s} viewBox="0 0 48 48" style={{ display: 'block' }} aria-hidden>
        <path d="M9 26 A15 15 0 0 1 39 26" fill="none" stroke={stroke} strokeWidth="2.2" strokeLinecap="round" />
        <rect x="6.5" y="24" width="5" height="9" rx="2" fill={stroke} />
        <rect x="36.5" y="24" width="5" height="9" rx="2" fill={stroke} />
        <path d="M11 33 Q11 39 18 39 L22 39" fill="none" stroke={stroke} strokeWidth="1.8" strokeLinecap="round" />
        <circle cx="22.5" cy="39" r="1.6" fill={stroke} />
        <g transform="translate(15 15)">
          {Array.from({ length: 25 }).map((_, i) => {
            const col = i % 5, row = (i / 5) | 0;
            const br = row === 2 && (col === 1 || col === 3) ? 1.5 : 0.95;
            return <circle key={i} className="dot" data-br={br} cx={col * 4.5} cy={row * 4.5} r={br} fill={stroke} />;
          })}
        </g>
      </svg>
    );
  }

  /* ---------- Plan builder (mirrors src/lib/mvc-agent/planner.ts) ---------- */
  function buildPlan({ persona, goals, experience, route, budget, safetyFlags }) {
    if (safetyFlags.length) return { blocked: true, reasons: safetyFlags };
    const p = PERSONAS.find(x => x.key === persona) || null;
    const gs = goals.length ? goals : (p?.goals ?? []);
    let pool = CATALOG.filter(c => gs.includes(c.cat));
    if (route === 'inj') pool = pool.filter(c => c.route !== 'oral');
    if (route === 'oral') pool = pool.filter(c => c.route !== 'inj');
    if (experience === 'new') pool = pool.filter(c => c.beginner);
    const goalOrder = p?.goals ?? gs;
    pool.sort((a, b) => {
      const ai = goalOrder.indexOf(a.cat), bi = goalOrder.indexOf(b.cat);
      if (ai !== bi) return (ai < 0 ? 99 : ai) - (bi < 0 ? 99 : bi);
      if (experience === 'new') return (b.beginner ? 1 : 0) - (a.beginner ? 1 : 0);
      return a.price - b.price;
    });
    const cap = budget ? BUDGET_CAP[budget] : 425;
    const items = []; let spent = 0;
    for (const c of pool) {
      if (spent + c.price > cap) continue;
      items.push(c); spent += c.price;
      if (items.length >= 3) break;
    }
    return { blocked: false, persona: p?.label ?? null, items, monthly: spent };
  }

  /* ---------- Builder wizard ---------- */
  function Builder({ onAddToCart, onOpenAI, onPlanChange }) {
    const [step, setStep] = useState(0);
    const [state, setState] = useState({
      persona: null, personas: [], goals: [], experience: null, route: null, budget: null,
      age: null, pregnant: null, condition: null, onMed: null,
    });
    const set = (k, v) => setState(s => ({ ...s, [k]: v }));
    const toggle = (k, v) => setState(s => {
      const arr = s[k] || [];
      return { ...s, [k]: arr.includes(v) ? arr.filter(x => x !== v) : [...arr, v] };
    });

    const safetyFlags = [];
    if (state.pregnant === 'yes') safetyFlags.push('Pregnancy / breastfeeding — peptide research protocols are not appropriate. Please consult a physician.');
    if (state.condition === 'yes') safetyFlags.push('Active serious condition — plan requires physician oversight before proceeding.');
    if (state.onMed === 'yes' && state.goals.includes('metabolic')) safetyFlags.push('Already on a GLP-1 or similar — stacking is unsafe without medical supervision.');
    if (state.age === 'under') safetyFlags.push('Under 21 — our research protocols require adult (21+) participation.');

    const steps = [
      { title: 'Which of these fit your research goals?', subtitle: 'Pick as many as apply — we\'ll tune the whole plan around them.', kind: 'persona' },
      { title: 'Which other fields are you interested to incorporate?', subtitle: 'Pick one or more — we\'ll balance the plan.', kind: 'goals' },
      { title: 'What is your experience with peptides?', field: 'experience', kind: 'chips',
        opts: [['new', 'Totally New'], ['some', 'Done Some Research'], ['adv', 'Experienced Researcher']] },


      { title: 'Monthly budget?', field: 'budget', kind: 'chips',
        opts: [['low', '$100–250'], ['mid', '$250–500'], ['high', '$500+']] },
      { title: 'Disclaimer', kind: 'disclaimer' },
      { title: 'Your custom plan', kind: 'result' },
    ];

    const cur = steps[step];
    const canAdvance = (() => {
      if (cur.kind === 'persona') return (state.personas || []).length > 0;
      if (cur.kind === 'goals') return state.goals.length > 0;
      if (cur.kind === 'chips') return !!state[cur.field];
      if (cur.kind === 'disclaimer') return !!state.ack;
      return true;
    })();

    const plan = step === steps.length - 1 ? buildPlan({ ...state, safetyFlags }) : null;

    // Bubble the current plan context up so the AI has it even before "add to cart"
    useEffect(() => {
      if (!onPlanChange) return;
      onPlanChange({
        persona: state.persona, personas: state.personas, goals: state.goals, experience: state.experience,
        route: state.route, budget: state.budget,
        health: { age: state.age, pregnant: state.pregnant, condition: state.condition, onMed: state.onMed },
      });
    }, [state.persona, state.personas, state.goals, state.experience, state.route, state.budget, state.age, state.pregnant, state.condition, state.onMed]);

    return (
      <div style={{ display: 'grid', gap: 22 }}>
        <div style={{ display: 'flex', gap: 6 }}>
          {steps.map((_, i) => (
            <div key={i} style={{ height: 4, flex: 1, borderRadius: 4,
              background: i <= step ? 'var(--color-accent)' : 'var(--color-surface-sunk)', transition: 'background 300ms' }} />
          ))}
        </div>
        <div style={{ fontFamily: 'var(--font-display)', fontSize: 26, color: 'var(--color-ink-strong)', lineHeight: 1.2 }}>{cur.title}</div>
        {cur.subtitle && <div style={{ fontSize: 13, color: 'var(--color-text-muted)', marginTop: -12 }}>{cur.subtitle}</div>}

        {cur.kind === 'persona' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))', gap: 12 }}>
            {PERSONAS.map(p => {
              const sel = state.personas || [];
              const on = sel.includes(p.key);
              const pick = () => setState(s => {
                const cursel = s.personas || [];
                const next = cursel.includes(p.key) ? cursel.filter(x => x !== p.key) : [...cursel, p.key];
                const goals = [];
                next.forEach(k => {
                  const pp = PERSONAS.find(x => x.key === k);
                  (pp?.goals || []).slice(0, 2).forEach(g => { if (!goals.includes(g)) goals.push(g); });
                });
                return { ...s, personas: next, persona: next[0] || null, goals };
              });
              return (
                <button key={p.key} onClick={pick} aria-pressed={on}
                  style={{
                    position: 'relative',
                    textAlign: 'left', padding: '18px 44px 18px 18px', borderRadius: 14, cursor: 'pointer',
                    border: `1.5px solid ${on ? p.color : 'var(--color-border)'}`,
                    background: on ? `linear-gradient(135deg, ${p.color}18, #fff)` : '#fff',
                    transition: 'all 180ms', transform: on ? 'translateY(-2px)' : 'none',
                    boxShadow: on ? `0 8px 24px -12px ${p.color}88` : 'none',
                  }}>
                  <span style={{
                    position: 'absolute', top: 16, right: 16, width: 20, height: 20, borderRadius: 6,
                    border: `1.5px solid ${on ? p.color : 'var(--color-border)'}`,
                    background: on ? p.color : '#fff', color: '#fff',
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: 12, fontWeight: 700, lineHeight: 1,
                  }}>{on ? '✓' : ''}</span>
                  <div style={{ fontSize: 22, marginBottom: 6 }}>{p.emoji}</div>
                  <div style={{ fontWeight: 600, fontSize: 15, color: 'var(--color-ink-strong)' }}>{p.label}</div>
                  <div style={{ fontSize: 12, color: 'var(--color-text-muted)', marginTop: 4, lineHeight: 1.5 }}>{p.desc}</div>
                </button>
              );
            })}
          </div>
        )}

        {cur.kind === 'goals' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 12 }}>
            {[
              { k: 'regeneration', t: 'Skin & Aesthetics', d: 'Glow, hair, post-procedure', color: '#E24A63' },
              { k: 'recovery', t: 'Recovery & Performance', d: 'Joints, tendons, training', color: '#0F5B60' },
              { k: 'metabolic', t: 'Metabolic & Weight', d: 'Appetite, glucose, body comp', color: '#C9A84C' },
              { k: 'longevity', t: 'Longevity & Energy', d: 'Mitochondria, healthy aging', color: '#3A6EA5' },
              { k: 'cognitive', t: 'Focus & Mood', d: 'Clarity, resilience, sleep', color: '#7A5CC6' },
            ].map(g => {
              const on = state.goals.includes(g.k);
              return (
                <button key={g.k} onClick={() => toggle('goals', g.k)}
                  style={{
                    textAlign: 'left', padding: '16px 18px', borderRadius: 14, cursor: 'pointer',
                    border: `1.5px solid ${on ? g.color : 'var(--color-border)'}`,
                    background: on ? `linear-gradient(135deg, ${g.color}18, #fff)` : '#fff',
                    transition: 'all 180ms', transform: on ? 'translateY(-2px)' : 'none',
                    boxShadow: on ? `0 8px 24px -12px ${g.color}88` : 'none',
                  }}>
                  <div style={{ width: 10, height: 10, borderRadius: 10, background: g.color, marginBottom: 10 }} />
                  <div style={{ fontWeight: 600, fontSize: 15, color: 'var(--color-ink-strong)' }}>{g.t}</div>
                  <div style={{ fontSize: 12, color: 'var(--color-text-muted)', marginTop: 4 }}>{g.d}</div>
                </button>
              );
            })}
          </div>
        )}

        {cur.kind === 'chips' && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
            {cur.opts.map(([k, l]) => (
              <button key={k} onClick={() => set(cur.field, k)}
                style={{
                  padding: '12px 20px', borderRadius: 999, cursor: 'pointer', fontSize: 14, fontWeight: 500,
                  border: `1.5px solid ${state[cur.field] === k ? 'var(--color-accent)' : 'var(--color-border)'}`,
                  background: state[cur.field] === k ? 'var(--color-accent-soft)' : '#fff',
                  color: 'var(--color-ink-strong)', transition: 'all 160ms',
                }}>{l}</button>
            ))}
          </div>
        )}

        {cur.kind === 'disclaimer' && (
          <div style={{ display: 'grid', gap: 16 }}>
            <label style={{
              display: 'flex', gap: 12, alignItems: 'flex-start', cursor: 'pointer',
              padding: 18, borderRadius: 16, background: '#fff',
              border: `1.5px solid ${state.ack ? 'var(--color-accent)' : 'var(--color-border)'}`,
              transition: 'all 160ms',
            }}>
              <input type="checkbox" checked={!!state.ack} onChange={e => set('ack', e.target.checked)}
                style={{ marginTop: 3, width: 18, height: 18, accentColor: 'var(--color-accent)', cursor: 'pointer' }} />
              <span style={{ fontSize: 13.5, lineHeight: 1.7, color: 'var(--color-ink)' }}>
                I understand these statements have not been approved by the FDA, and legal consumption is only to be
                conducted within the context of research. As a frontier science, I understand that results may vary,
                and My Vital Cell only guarantees pure products for established research purposes — not proven results
                for individual consumption, nor officially recognized cures or human consumables.
              </span>
            </label>
          </div>
        )}

        {cur.kind === 'result' && plan && (
          plan.blocked ? (
            <div style={{ display: 'grid', gap: 14, padding: 22, borderRadius: 16, background: '#FBEEF1', border: '1px solid var(--vc-crimson-100)' }}>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 20, color: 'var(--vc-crimson-600)' }}>Let's talk to a specialist first.</div>
              <ul style={{ margin: 0, paddingLeft: 18, fontSize: 13, color: 'var(--color-ink)', lineHeight: 1.7 }}>
                {plan.reasons.map((r, i) => <li key={i}>{r}</li>)}
              </ul>
              <button onClick={onOpenAI} style={primaryBtn}>Talk to our team →</button>
            </div>
          ) : (
            <div style={{ display: 'grid', gap: 14 }}>
              <div style={{ fontSize: 13, color: 'var(--color-text-muted)' }}>
                {plan.persona ? <>Tuned for <b style={{ color: 'var(--color-ink-strong)' }}>{plan.persona}</b> · </> : null}
                Estimated monthly: <b style={{ color: 'var(--color-ink-strong)' }}>${plan.monthly}</b>
              </div>
              <div style={{ display: 'grid', gap: 10 }}>
                {plan.items.map(p => (
                  <div key={p.slug} style={{ padding: 16, borderRadius: 12, border: '1px solid var(--color-border)', background: '#fff' }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
                      <div style={{ fontWeight: 600, color: 'var(--color-ink-strong)', fontSize: 15 }}>{p.name}</div>
                      <div style={{ fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--color-text-muted)' }}>{p.catLabel} · ${p.price}/mo</div>
                    </div>
                    <div style={{ fontSize: 12.5, color: 'var(--color-ink)', marginTop: 4, lineHeight: 1.6 }}>{p.blurb}</div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 10, fontSize: 11.5, color: 'var(--color-text-muted)' }}>
                      <div><b style={{ color: 'var(--color-ink-strong)', display: 'block', fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 3 }}>Protocol</b>{p.protocol}</div>
                      <div><b style={{ color: 'var(--color-ink-strong)', display: 'block', fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 3 }}>Timing</b>{p.timing}</div>
                    </div>
                    <div style={{ fontSize: 11.5, color: 'var(--color-text-muted)', marginTop: 8, fontStyle: 'italic' }}>Why: {p.rationale}</div>
                  </div>
                ))}
              </div>
              {plan.items.length === 0 && <div style={{ fontSize: 13, color: 'var(--color-text-muted)' }}>No compounds match your filters — try loosening budget or route.</div>}
              <div style={{ display: 'flex', gap: 10, marginTop: 6 }}>
                <button onClick={() => window.VC_ORDER && window.VC_ORDER.open()} style={primaryBtn} disabled={plan.items.length === 0}>Ready to order</button>
                <button onClick={onOpenAI} style={ghostBtn}>Ask a specialist</button>
              </div>
            </div>
          )
        )}

        <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6 }}>
          <button onClick={() => setStep(s => Math.max(0, s - 1))} disabled={step === 0} style={{ ...ghostBtn, opacity: step === 0 ? 0.4 : 1 }}>← Back</button>
          {step < steps.length - 1 && (
            <button onClick={() => canAdvance && setStep(s => s + 1)} disabled={!canAdvance} style={{ ...primaryBtn, opacity: canAdvance ? 1 : 0.5 }}>
              Continue →
            </button>
          )}
        </div>
      </div>
    );
  }

  function YesNoRow({ label, val, onSet }) {
    return (
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
        <div style={{ fontSize: 14, color: 'var(--color-ink)' }}>{label}</div>
        <div style={{ display: 'flex', gap: 6 }}>
          {['no', 'yes'].map(v => (
            <button key={v} onClick={() => onSet(v)}
              style={{
                padding: '7px 16px', borderRadius: 999, cursor: 'pointer', fontSize: 12, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase',
                border: `1.5px solid ${val === v ? 'var(--color-accent)' : 'var(--color-border)'}`,
                background: val === v ? 'var(--color-accent-soft)' : '#fff',
                color: 'var(--color-ink-strong)',
              }}>{v}</button>
          ))}
        </div>
      </div>
    );
  }

  /* ---------- Chat pane with inline captcha + markdown + final synthesis + plan → cart ---------- */
  function ChatPane({ context, onAddToCart }) {
    const [messages, setMessages] = useState([
      { role: 'assistant', text: "Hey — before I open the floodgates, one **carbon-based** check:", captcha: true },
    ]);
    const [passed, setPassed] = useState(false);
    const [input, setInput] = useState('');
    const [busy, setBusy] = useState(false);
    const [remaining, setRemaining] = useState(10);
    const [finalPlan, setFinalPlan] = useState(null);
    const scrollRef = useRef(null);

    useEffect(() => { scrollRef.current?.scrollTo({ top: 1e9, behavior: 'smooth' }); }, [messages, busy]);

    const onCaptchaPass = () => {
      setPassed(true);
      setMessages(m => [
        ...m,
        { role: 'user', text: "🐝 not a robot" },
        { role: 'assistant', text: context?.goals?.length
          ? `Nice — human confirmed. I've got your plan context (${context.persona || 'no persona set'}, goals: ${context.goals.join(', ') || '—'}). What do you want to dig into?`
          : "Nice — human confirmed. Tell me what you're optimizing for and I'll get specific." },
      ]);
    };

    const send = async () => {
      const q = input.trim(); if (!q || busy || remaining <= 0 || !passed) return;
      setInput(''); setBusy(true);
      const next = [...messages, { role: 'user', text: q }];
      setMessages(next);
      try {
        const agent = window.MVC_AGENT;
        const reply = agent ? await agent.ask(q, next, context) : { text: "AI specialist is warming up — try Contact Us for a human.", counted: false };
        setMessages(m => [...m, { role: 'assistant', text: reply.text, final: reply.final }]);
        if (reply.counted !== false) setRemaining(r => Math.max(0, r - 1));
        if (reply.final) { setRemaining(0); setFinalPlan(reply.text); }
      } catch (e) {
        setMessages(m => [...m, { role: 'assistant', text: "I hit a snag reaching my server. Please try Contact Us for a human specialist." }]);
      } finally { setBusy(false); }
    };

    return (
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
        <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--color-border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, color: 'var(--color-ink-strong)' }}>
            <AgentIcon size={22} />
            <div style={{ fontWeight: 600, fontSize: 14 }}>Vital Cell Specialist</div>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            {context?.items?.length > 0 && (
              <button onClick={() => onAddToCart?.(context.items)}
                style={{ padding: '6px 12px', borderRadius: 999, border: '1px solid var(--color-accent)', background: 'var(--color-accent-soft)', color: 'var(--color-ink-strong)', fontSize: 11, fontWeight: 600, letterSpacing: '0.08em', cursor: 'pointer' }}>
                + Cart plan
              </button>
            )}
            <div style={{ fontSize: 11, color: 'var(--color-text-muted)' }}>{remaining} msgs left</div>
          </div>
        </div>
        <div ref={scrollRef} style={{ flex: 1, overflowY: 'auto', padding: 18, display: 'flex', flexDirection: 'column', gap: 12 }}>
          {messages.map((m, i) => (
            <div key={i} style={{
              alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start',
              maxWidth: '90%', padding: '10px 14px', borderRadius: 14, fontSize: 13.5, lineHeight: 1.55,
              background: m.role === 'user' ? 'var(--color-accent)' : '#fff',
              color: m.role === 'user' ? '#fff' : 'var(--color-ink-strong)',
              border: m.role === 'user' ? 'none' : '1px solid var(--color-border)',
              boxShadow: '0 1px 2px rgba(0,0,0,0.04)',
            }}>
              {m.role === 'user' ? m.text : <Markdown text={m.text} />}
              {m.captcha && !passed && <InlineCaptcha onPass={onCaptchaPass} />}
              {m.final && (
                <div style={{ marginTop: 10, display: 'flex', gap: 6 }}>
                  <button onClick={() => window.VC_ORDER && window.VC_ORDER.open()} style={{ ...primaryBtn, padding: '7px 14px', fontSize: 11 }}>Ready to order</button>
                </div>
              )}
            </div>
          ))}
          {busy && (
            <div style={{ alignSelf: 'flex-start', fontSize: 12, color: 'var(--color-text-muted)', display: 'flex', gap: 6, alignItems: 'center' }}>
              <AgentIcon size={16} /> thinking…
            </div>
          )}
          {remaining === 0 && (
            <div style={{ padding: 12, borderRadius: 12, background: 'var(--color-accent-soft)', fontSize: 12, color: 'var(--color-ink)' }}>
              Session complete — for deeper personalization, book a call with a human specialist.
            </div>
          )}
        </div>
        <div style={{ padding: 12, borderTop: '1px solid var(--color-border)', display: 'flex', gap: 8 }}>
          <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => e.key === 'Enter' && send()}
            placeholder={!passed ? 'Prove you\'re human first ↑' : remaining === 0 ? 'Session complete' : 'Ask about a compound, dose, stack…'}
            disabled={remaining === 0 || !passed}
            style={{ flex: 1, padding: '11px 14px', borderRadius: 10, border: '1px solid var(--color-border)', fontSize: 13, outline: 'none', background: '#fff' }} />
          <button onClick={send} disabled={busy || !input.trim() || remaining === 0 || !passed} style={{ ...primaryBtn, padding: '10px 16px' }}>Send</button>
        </div>
      </div>
    );
  }

  /* ---------- Inline captcha bubble (charming, low-friction) ---------- */
  function InlineCaptcha({ onPass }) {
    const [pick, setPick] = useState(null);
    const opts = ['🐝', '🤖', '🐝'];
    return (
      <div style={{ marginTop: 8 }}>
        <div style={{ fontSize: 12, color: 'var(--color-text-muted)', marginBottom: 6 }}>Tap the one that's <b style={{ color: 'var(--color-ink-strong)' }}>not</b> a robot:</div>
        <div style={{ display: 'flex', gap: 8 }}>
          {opts.map((e, i) => (
            <button key={i} onClick={() => { setPick(i); if (e === '🐝') setTimeout(onPass, 300); }}
              style={{
                width: 44, height: 44, borderRadius: 12, fontSize: 22, cursor: 'pointer',
                border: `1.5px solid ${pick === i ? (e === '🐝' ? 'var(--color-accent)' : 'var(--vc-crimson-500)') : 'var(--color-border)'}`,
                background: '#fff', transition: 'all 200ms', transform: pick === i ? 'scale(1.1)' : 'scale(1)',
              }}>{e}</button>
          ))}
        </div>
        {pick !== null && opts[pick] !== '🐝' && (
          <div style={{ fontSize: 11, color: 'var(--vc-crimson-500)', marginTop: 6 }}>Close — the bees are the humans here.</div>
        )}
      </div>
    );
  }

  /* ---------- Styles ---------- */
  const primaryBtn = {
    padding: '11px 20px', borderRadius: 10, border: 'none', cursor: 'pointer',
    background: 'var(--color-ink-strong)', color: '#fff', fontSize: 13, fontWeight: 600,
    letterSpacing: '0.06em', transition: 'background 160ms',
  };
  const ghostBtn = {
    padding: '11px 18px', borderRadius: 10, cursor: 'pointer',
    background: 'transparent', color: 'var(--color-ink-strong)', border: '1px solid var(--color-border)',
    fontSize: 13, fontWeight: 500,
  };
  const inputStyle = {
    padding: '12px 14px', borderRadius: 10, border: '1px solid var(--color-border)',
    fontSize: 14, outline: 'none', background: '#fff', fontFamily: 'inherit', color: 'var(--color-ink-strong)',
  };

  /* ---------- Main CTA ---------- */
  function CTA() {
    const [open, setOpen] = useState(false);
    const [view, setView] = useState('onboard');
    const [iconAtBottom, setIconAtBottom] = useState(false);
    const [planContext, setPlanContext] = useState(null);
    const [toast, setToast] = useState(null);
    const [cartOpen, setCartOpen] = useState(false);

    const goChat = () => {
      if (!iconAtBottom) { setIconAtBottom(true); setTimeout(() => setView('chat'), 550); }
      else setView('chat');
    };
    const startBuilder = () => { setView('builder'); setIconAtBottom(true); };
    const addToCart = (items) => {
      try {
        if (window.VC_CART && Array.isArray(items)) {
          items.forEach((it) => {
            const name = typeof it === 'string' ? it : (it?.name || it?.title || 'Custom item');
            window.VC_CART.add({ name, catLabel: it?.catLabel || 'Custom plan', formula: it?.formula || '' });
          });
        }
      } catch {}
      setPlanContext(pc => ({ ...(pc || {}), items }));
      setToast(`Added ${items.length} item${items.length > 1 ? 's' : ''} to cart`);
      setTimeout(() => setToast(null), 2400);
    };
    const reset = () => { setView('onboard'); setIconAtBottom(false); };
    const onPlanChange = (ctx) => setPlanContext(pc => ({ ...ctx, items: pc?.items }));

    useEffect(() => {
      const openFromEvent = (event) => {
        const nextView = event?.detail?.view || 'builder';
        setOpen(true);
        if (nextView === 'builder' || nextView === 'start') {
          setView('builder');
          setIconAtBottom(true);
        } else if (nextView === 'contact') {
          setView('contact');
          setIconAtBottom(false);
        } else if (nextView === 'chat') {
          setView('chat');
          setIconAtBottom(true);
        } else {
          setView('onboard');
          setIconAtBottom(false);
        }
      };
      window.addEventListener('mvc-cta-open', openFromEvent);
      return () => window.removeEventListener('mvc-cta-open', openFromEvent);
    }, []);

    useEffect(() => {
      const updateCartVisibility = (event) => setCartOpen(Boolean(event?.detail?.open));
      window.addEventListener('vc-cart-visibility', updateCartVisibility);
      return () => window.removeEventListener('vc-cart-visibility', updateCartVisibility);
    }, []);

    return (
      <>
        <div className="mvc-gradient-border"
          style={{
            position: 'fixed', right: 22, bottom: 'calc(var(--devbar-h, 34px) + 18px)', zIndex: 60,
            display: open || cartOpen ? 'none' : 'inline-block',
            padding: 2.5, borderRadius: 999,
            boxShadow: '0 0 34px 6px rgba(255,255,255,0.85), 0 20px 50px -12px rgba(255,110,50,0.45)',
            animation: 'mvcBorderFlow 6s ease-in-out infinite',
          }}>
          <button className="mvc-cta-fab" aria-label="Get in touch" onClick={() => { setOpen(true); setView('onboard'); setIconAtBottom(false); }}
            style={{
              display: 'inline-flex', alignItems: 'center', gap: 14,
              padding: '14px 24px 14px 14px', borderRadius: 999,
              background: '#fff', color: 'var(--color-ink-strong)', border: 'none',
              fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 700, letterSpacing: '0.16em',
              cursor: 'pointer',
            }}>
            <span style={{
              width: 52, height: 52, borderRadius: 999,
              background: 'linear-gradient(135deg, #FFF, #FFF3EC)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              color: '#E85A2C', animation: 'mvcAgentFloat 3s ease-in-out infinite',
              boxShadow: 'inset 0 0 0 1px rgba(255,120,50,0.18)',
            }}><AgentIcon size={36} /></span>
            <span className="mvc-fab-label">GET IN TOUCH</span>
          </button>
          <style>{`
            @media (max-width: 760px) {
              .mvc-cta-fab .mvc-fab-label { display: none; }
              .mvc-cta-fab { padding: 8px !important; gap: 0 !important; }
              .mvc-cta-fab > span:first-child { width: 44px !important; height: 44px !important; }
            }
          `}</style>
        </div>


        {toast && (
          <div style={{ position: 'fixed', bottom: 'calc(var(--devbar-h, 34px) + 84px)', right: 22, zIndex: 70,
            padding: '10px 16px', borderRadius: 10, background: '#0f0f14', color: '#fff', fontSize: 12, boxShadow: '0 10px 30px rgba(0,0,0,0.25)' }}>
            ✓ {toast}
          </div>
        )}

        {open && (
          <div onClick={(e) => { if (e.target === e.currentTarget) { setOpen(false); reset(); } }}
            style={{
              position: 'fixed', inset: 0, zIndex: 65,
              background: 'rgba(20,20,28,0.28)', backdropFilter: 'blur(8px)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              animation: 'mvcFadeIn 200ms ease-out',
            }}>
            <div className="mvc-cta-popup mvc-gradient-border" style={{
              width: '62vw', height: '62vh', minWidth: 640, minHeight: 480,
              borderRadius: 26, position: 'relative', padding: 2.5,
              boxShadow: '0 0 60px 10px rgba(255,255,255,0.9), 0 40px 100px -20px rgba(255,110,50,0.35), 0 40px 100px -30px rgba(20,20,40,0.35)',
              animation: 'mvcPopIn 320ms cubic-bezier(.2,.9,.2,1.05), mvcBorderFlow 6s ease-in-out infinite',
            }}>
              <div style={{
                width: '100%', height: '100%', borderRadius: 24, position: 'relative', overflow: 'hidden',
                background: 'linear-gradient(160deg, #ffffff 0%, #fffaf6 60%, #fff5ee 100%)',
              }}>
              <button onClick={() => { setOpen(false); reset(); }}
                style={{ position: 'absolute', top: 14, right: 14, zIndex: 5, width: 34, height: 34, borderRadius: 999,
                  background: 'rgba(255,255,255,0.9)', border: '1px solid var(--color-border)', cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: 'var(--color-ink-strong)', fontSize: 18 }}>×</button>

              <div style={{ display: 'flex', height: '100%' }}>
                <div style={{ flex: view === 'chat' ? '0 0 63%' : '1 1 100%', padding: iconAtBottom && view !== 'chat' ? '38px 44px 132px' : '38px 44px', overflowY: 'auto', transition: 'flex 400ms cubic-bezier(.2,.9,.2,1)' }}>

                  <button type="button"
                    aria-label={iconAtBottom ? 'Activate AI specialist' : 'AI specialist'}
                    onClick={iconAtBottom && view !== 'chat' ? goChat : undefined}
                    disabled={!iconAtBottom || view === 'chat'}
                    style={{
                      position: 'absolute',
                      top: iconAtBottom ? 'auto' : 28,
                      left: iconAtBottom ? 'auto' : '50%',
                      bottom: iconAtBottom ? 26 : 'auto',
                      right: iconAtBottom ? (view === 'chat' ? 'auto' : 26) : 'auto',
                      left: iconAtBottom && view === 'chat' ? 26 : (iconAtBottom ? 'auto' : '50%'),

                      transform: iconAtBottom ? 'translate(0,0)' : 'translate(-50%, 0)',
                      transition: 'all 620ms cubic-bezier(.6,.05,.3,1.1)',
                      background: iconAtBottom
                        ? 'radial-gradient(circle at 30% 25%, #FF6B3D 0%, #E63946 55%, #A6132A 100%)' : 'transparent',
                      border: 'none',
                      borderRadius: iconAtBottom ? 999 : 0,
                      width: iconAtBottom ? 82 : 'auto',
                      height: iconAtBottom ? 82 : 'auto',
                      padding: 0,
                      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                      color: iconAtBottom ? '#fff' : 'var(--color-ink-strong)',
                      cursor: iconAtBottom && view !== 'chat' ? 'pointer' : 'default',
                      boxShadow: iconAtBottom
                        ? '0 14px 34px -8px rgba(230,57,70,0.55), 0 0 0 4px rgba(255,255,255,0.9), 0 0 40px 6px rgba(255,120,60,0.35)'
                        : 'none',
                      animation: iconAtBottom ? 'mvcAgentFloat 3.4s ease-in-out infinite' : 'none',
                      zIndex: 4,
                    }}>
                    <AgentIcon size={iconAtBottom ? 44 : 72} tone={iconAtBottom ? 'light' : 'auto'} />
                    {iconAtBottom && view === 'builder' && (
                      <span style={{
                        position: 'absolute', bottom: -26, left: '50%', transform: 'translateX(-50%)',
                        fontSize: 9.5, letterSpacing: '0.22em', fontWeight: 700, color: 'var(--color-accent)',
                        whiteSpace: 'nowrap',
                      }}>ASK AI →</span>
                    )}
                  </button>

                  <div style={{ marginTop: view === 'onboard' && !iconAtBottom ? 130 : 60, height: view === 'onboard' && !iconAtBottom ? 'calc(100% - 150px)' : 'auto' }}>

                    {view === 'onboard' && (
                      <div style={{ display: 'flex', flexDirection: 'column', gap: 20, textAlign: 'center', height: '100%' }}>
                        <div>
                          <div style={{ fontFamily: 'var(--font-display)', fontSize: 34, color: 'var(--color-ink-strong)', lineHeight: 1.15 }}>How can we help?</div>
                          <div style={{ fontSize: 14, color: 'var(--color-text-muted)', marginTop: 8 }}>Choose the path that fits — we'll take it from there.</div>
                        </div>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 22, flex: 1, minHeight: 260 }}>
                          <OptionCard title="Contact Us" desc="Get in touch with a live specialist to answer questions and build your custom plan." accent="#0F5B60" onClick={() => setView('contact')} full />
                          <OptionCard title="Start Now" desc="Design your custom plan with our smart form, and get help from our trained AI agent. Tap the agent anytime for live help." accent="var(--color-accent)" onClick={startBuilder} badge="or" full />
                        </div>
                      </div>
                    )}

                    {view === 'contact' && (
                      <div style={{ display: 'grid', gap: 20, maxWidth: 560, margin: '0 auto' }}>
                        <button onClick={() => setView('onboard')} style={{ ...ghostBtn, justifySelf: 'start', padding: '6px 12px', fontSize: 12 }}>← Back</button>
                        <div style={{ fontFamily: 'var(--font-display)', fontSize: 26, color: 'var(--color-ink-strong)' }}>Talk to a specialist</div>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                          <OptionCard title="Schedule a Call" desc="Pick a 20-minute slot with a specialist." accent="#0F5B60" onClick={() => setView('schedule')} />
                          <OptionCard title="Send us a Message" desc="Write to us — we reply within one business day." accent="var(--color-accent)" onClick={() => setView('message')} />
                        </div>
                      </div>
                    )}

                    {view === 'schedule' && (
                      <div style={{ display: 'grid', gap: 16, maxWidth: 520, margin: '0 auto' }}>
                        <button onClick={() => setView('contact')} style={{ ...ghostBtn, justifySelf: 'start', padding: '6px 12px', fontSize: 12 }}>← Back</button>
                        <div style={{ fontFamily: 'var(--font-display)', fontSize: 24, color: 'var(--color-ink-strong)' }}>Pick a time</div>
                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
                          {['Mon 10:00', 'Mon 14:30', 'Tue 09:00', 'Tue 15:00', 'Wed 11:00', 'Thu 13:30'].map(s => (
                            <button key={s} onClick={() => { setToast('Slot requested — we\'ll confirm by email'); setTimeout(() => { setToast(null); setOpen(false); reset(); }, 1800); }}
                              style={{ padding: '14px 12px', borderRadius: 12, border: '1px solid var(--color-border)', background: '#fff', cursor: 'pointer', fontSize: 13, color: 'var(--color-ink-strong)' }}>{s}</button>
                          ))}
                        </div>
                      </div>
                    )}

                    {view === 'message' && (
                      <div style={{ display: 'grid', gap: 12, maxWidth: 520, margin: '0 auto' }}>
                        <button onClick={() => setView('contact')} style={{ ...ghostBtn, justifySelf: 'start', padding: '6px 12px', fontSize: 12 }}>← Back</button>
                        <div style={{ fontFamily: 'var(--font-display)', fontSize: 24, color: 'var(--color-ink-strong)' }}>Send a message</div>
                        <input placeholder="Your email" style={inputStyle} />
                        <textarea placeholder="How can we help?" rows={5} style={{ ...inputStyle, resize: 'vertical' }} />
                        <button onClick={() => { setToast('Message sent — we\'ll reply within 1 business day'); setTimeout(() => { setToast(null); setOpen(false); reset(); }, 1800); }} style={primaryBtn}>Send message</button>
                      </div>
                    )}

                    {view === 'builder' && (
                      <div style={{ maxWidth: 640, margin: '0 auto' }}>
                        <button onClick={() => setView('onboard')} style={{ ...ghostBtn, padding: '6px 12px', fontSize: 12, marginBottom: 14 }}>← Back</button>
                        <Builder onAddToCart={addToCart} onOpenAI={goChat} onPlanChange={onPlanChange} />
                      </div>
                    )}

                    {view === 'chat' && (
                      <div style={{ maxWidth: 520, margin: '0 auto' }}>
                        <div style={{ fontFamily: 'var(--font-display)', fontSize: 22, color: 'var(--color-ink-strong)', marginBottom: 12 }}>Your session</div>
                        <div style={{ fontSize: 13, color: 'var(--color-text-muted)', lineHeight: 1.7 }}>
                          The specialist to the right knows your plan and safety profile. Ask about compounds, stacks, dosing frameworks, or timing.
                          <br /><br />
                          <b style={{ color: 'var(--color-ink)' }}>Safety first:</b> we won't recommend anything past your stated conditions.
                          Sessions are capped at 10 messages — we'll wrap with a final recommendation.
                        </div>
                      </div>
                    )}
                  </div>
                </div>

                {view === 'chat' && (
                  <div style={{ flex: '0 0 37%', borderLeft: '1px solid var(--color-border)', background: 'rgba(255,255,255,0.6)', backdropFilter: 'blur(6px)' }}>
                    <ChatPane context={planContext} onAddToCart={addToCart} />
                  </div>
                )}
              </div>
              </div>
            </div>
          </div>
        )}
      </>
    );
  }

  function OptionCard({ title, desc, accent, onClick, badge, full }) {
    return (
      <button onClick={onClick} style={{
        position: 'relative', textAlign: 'left',
        padding: full ? '32px 30px' : '22px 22px',
        borderRadius: 20, cursor: 'pointer',
        border: '1.5px solid var(--color-border)',
        background: 'linear-gradient(160deg, #ffffff, #fffaf5)',
        transition: 'all 220ms', height: full ? '100%' : 'auto',
        display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'flex-start',
        boxShadow: full ? '0 2px 12px -6px rgba(0,0,0,0.06)' : 'none',
      }}
        onMouseEnter={e => { e.currentTarget.style.transform = 'translateY(-4px)'; e.currentTarget.style.boxShadow = `0 22px 44px -20px ${accent}99, 0 0 24px 4px rgba(255,255,255,0.9)`; e.currentTarget.style.borderColor = accent; }}
        onMouseLeave={e => { e.currentTarget.style.transform = 'none'; e.currentTarget.style.boxShadow = full ? '0 2px 12px -6px rgba(0,0,0,0.06)' : 'none'; e.currentTarget.style.borderColor = 'var(--color-border)'; }}>
        {badge && <div style={{ position: 'absolute', top: -10, left: 22, fontSize: 10, letterSpacing: '0.22em', fontWeight: 700, color: 'var(--color-text-muted)', background: '#fff', padding: '3px 10px', borderRadius: 4, border: '1px solid var(--color-border)' }}>{badge}</div>}
        <div>
          <div style={{ width: 10, height: 10, borderRadius: 10, background: accent, marginBottom: 14 }} />
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 500, fontSize: full ? 26 : 16, color: 'var(--color-ink-strong)', marginBottom: 10, lineHeight: 1.2 }}>{title}</div>
          <div style={{ fontSize: full ? 14 : 12.5, color: 'var(--color-text-muted)', lineHeight: 1.6 }}>{desc}</div>
        </div>
      </button>
    );
  }

  window.MVC_CTA = CTA;
})();
