// onboarding.jsx — 5-step new-user onboarding wizard
const { useState, useEffect, useRef, useCallback } = React;

// ─── STEP PROGRESS BAR ───────────────────────────────────────────────────────
const StepBar = ({ current, total }) => (
  <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
    {Array.from({ length: total }).map((_, i) => (
      <div key={i} style={{
        height: 3, borderRadius: 2, transition: 'all 0.4s var(--ease-out-expo)',
        background: i < current ? 'var(--p5)' : i === current ? 'var(--p4)' : 'var(--bg4)',
        flex: i === current ? 2.2 : 1,
        boxShadow: i < current ? '0 0 6px rgba(6,182,212,0.5)' : i === current ? '0 0 10px rgba(129,140,252,0.7)' : 'none',
      }} />
    ))}
  </div>
);

// ─── SHARED STEP WRAPPER ──────────────────────────────────────────────────────
const StepWrap = ({ children, style = {} }) => (
  <div style={{
    animation: 'step-in 0.38s var(--ease-out-expo) both',
    display: 'flex', flexDirection: 'column', gap: 0,
    ...style,
  }}>
    {children}
  </div>
);

// ─── LOGO MARK (uses global pin glyph) ───────────────────────────────────────
const LogoMark = ({ size = 52, glow = true }) => (
  <div style={{
    width: size, height: size, borderRadius: size * 0.26, flexShrink: 0,
    background: 'linear-gradient(150deg, #0B2A30 0%, #05161A 100%)',
    border: '1px solid rgba(34,211,238,0.32)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    boxShadow: glow ? '0 0 0 1px rgba(34,211,238,0.06) inset, 0 0 28px rgba(6,182,212,0.5), 0 0 60px rgba(6,182,212,0.18)' : 'none',
    animation: 'pop-in 0.5s var(--ease-out-expo) both',
  }}>
    <LogoGlyph size={size * 0.62} />
  </div>
);

// ─── RADAR RINGS BG ───────────────────────────────────────────────────────────
const RadarBg = () => (
  <>
    <div style={{
      position: 'absolute', top: '50%', left: '50%',
      transform: 'translate(-50%, -50%)',
      width: 700, height: 700, pointerEvents: 'none', zIndex: 0,
      background: [
        'radial-gradient(circle at center, transparent 90px, rgba(6,182,212,0.07) 91px, rgba(6,182,212,0.07) 92px, transparent 93px)',
        'radial-gradient(circle at center, transparent 165px, rgba(6,182,212,0.05) 166px, rgba(6,182,212,0.05) 167px, transparent 168px)',
        'radial-gradient(circle at center, transparent 248px, rgba(6,182,212,0.035) 249px, rgba(6,182,212,0.035) 250px, transparent 251px)',
        'radial-gradient(circle at center, transparent 340px, rgba(6,182,212,0.022) 341px, transparent 343px)',
      ].join(','),
    }} />
    <div style={{
      position: 'absolute', top: '50%', left: '50%',
      width: 700, height: 700, marginTop: -350, marginLeft: -350,
      pointerEvents: 'none', zIndex: 0, borderRadius: '50%', overflow: 'hidden',
      animation: 'radar-rotate 10s linear infinite',
      background: 'conic-gradient(from 0deg, rgba(6,182,212,0.09) 0deg, rgba(6,182,212,0.01) 50deg, transparent 80deg)',
      maskImage: 'radial-gradient(circle at center, transparent 82px, black 88px, black 95%, transparent 100%)',
      WebkitMaskImage: 'radial-gradient(circle at center, transparent 82px, black 88px, black 95%, transparent 100%)',
    }} />
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 0,
      background: 'radial-gradient(ellipse 80% 80% at 50% 50%, rgba(6,182,212,0.14) 0%, transparent 65%)',
    }} />
  </>
);

// ─── STEP 1: WELCOME ─────────────────────────────────────────────────────────
const Step1Welcome = ({ username, onNext }) => (
  <StepWrap style={{ alignItems: 'center', textAlign: 'center' }}>
    <LogoMark size={60} />
    <div style={{ marginTop: 28, animation: 'fadein 0.5s var(--ease-out-expo) 0.15s both' }}>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--p4)', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 12 }}>Welcome to RoStealth</div>
      <h1 style={{ fontSize: 'clamp(28px,4vw,40px)', fontWeight: 700, letterSpacing: '-0.045em', color: 'var(--t1)', lineHeight: 1.05 }}>
        Hey, <span style={{ color: 'var(--p3)' }}>{username}</span>.<br />Let's get you set up.
      </h1>
      <p style={{ fontSize: 15, color: 'var(--t2)', marginTop: 16, lineHeight: 1.65, maxWidth: 380, margin: '16px auto 0' }}>
        In the next 2 minutes you'll add your first Roblox user to track, set your alerts, and go live.
      </p>
    </div>
    <div style={{ marginTop: 36, display: 'flex', flexDirection: 'column', gap: 10, alignItems: 'center', animation: 'fadein 0.5s var(--ease-out-expo) 0.3s both' }}>
      <Btn size="lg" onClick={onNext} icon={<Icon.ArrowRight />} style={{ minWidth: 200, justifyContent: 'center' }}>
        Get started
      </Btn>
      <span style={{ fontSize: 12, color: 'var(--t4)', fontFamily: 'var(--mono)' }}>Takes about 2 minutes</span>
    </div>
    {/* social proof row */}
    <div style={{ marginTop: 48, display: 'flex', alignItems: 'center', gap: 8, animation: 'fadein 0.5s var(--ease-out-expo) 0.45s both' }}>
      {['S','X','P','F','V'].map((l, i) => (
        <div key={i} style={{ width: 26, height: 26, borderRadius: '50%', background: ['#0891B2','#0E7490','#155E63','#06B6D4','#0E7490'][i], border: '2px solid var(--bg1)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 10, fontWeight: 700, color: '#fff', marginLeft: i > 0 ? -6 : 0 }}>{l}</div>
      ))}
      <span style={{ fontSize: 12, color: 'var(--t3)', marginLeft: 6 }}>2,300+ group owners already tracking</span>
    </div>
  </StepWrap>
);

// ─── STEP 2: TRACK FIRST USER ────────────────────────────────────────────────
const Step2Track = ({ onNext, onSkip, trackedInput, setTrackedInput, resolvedUser, setResolvedUser }) => {
  const [loading, setLoading] = useState(false);

  const fakeUsers = {
    'xshadowreaper':    { username: 'xShadowReaper',    robloxId: '285113055', status: 'online',  game: 'Da Hood'  },
    'phantom_wolf':     { username: 'Phantom_Wolf',     robloxId: '776523400', status: 'in-game', game: 'Bloxburg' },
    'velocityx99':      { username: 'VelocityX99',      robloxId: '104561190', status: 'offline', game: null       },
    'frostclan_leader': { username: 'FrostClan_Leader', robloxId: '398412773', status: 'in-game', game: 'Arsenal'  },
  };

  const handleResolve = async () => {
    if (!trackedInput.trim()) return;
    setLoading(true); setResolvedUser(null);
    await new Promise(r => setTimeout(r, 900));
    const key = trackedInput.trim().toLowerCase();
    const found = fakeUsers[key] || { username: trackedInput.trim(), robloxId: Math.floor(Math.random() * 900000000 + 100000000).toString(), status: 'offline', game: null };
    setResolvedUser(found);
    setLoading(false);
  };

  const statusColors = { online: 'var(--green)', 'in-game': 'var(--amber)', offline: 'var(--t4)' };
  const statusAnims  = { online: 'pulse-dot 2s infinite', 'in-game': 'pulse-amber 2s infinite', offline: 'none' };

  return (
    <StepWrap>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 10.5, color: 'var(--p4)', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 10 }}>Step 2 of 5</div>
      <h2 style={{ fontSize: 26, fontWeight: 700, letterSpacing: '-0.04em', color: 'var(--t1)', marginBottom: 8 }}>Track your first member</h2>
      <p style={{ fontSize: 14, color: 'var(--t2)', marginBottom: 28, lineHeight: 1.6 }}>
        Enter any Roblox username or User ID. We'll resolve it and start monitoring straight away.
      </p>

      {/* input row */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 16 }}>
        <div style={{ flex: 1 }}>
          <Input
            value={trackedInput}
            onChange={setTrackedInput}
            placeholder="Username or User ID..."
            icon={<Icon.User />}
            autoFocus
            onKeyDown={e => e.key === 'Enter' && handleResolve()}
          />
        </div>
        <Btn onClick={handleResolve} disabled={loading || !trackedInput.trim()}>
          {loading ? (
            <span style={{ animation: 'spin 0.7s linear infinite', display: 'inline-block' }}>&#8635;</span>
          ) : 'Resolve'}
        </Btn>
      </div>

      {/* resolved card */}
      {resolvedUser && (
        <div style={{ background: 'var(--bg3)', border: '1px solid rgba(52,211,153,0.25)', borderRadius: 12, padding: '14px 16px', marginBottom: 20, animation: 'pop-in 0.3s var(--ease-out-expo) both', boxShadow: '0 0 20px rgba(52,211,153,0.07)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <Avatar name={resolvedUser.username} size={38} status={resolvedUser.status} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--t1)' }}>{resolvedUser.username}</div>
              <div style={{ fontSize: 10.5, color: 'var(--t4)', fontFamily: 'var(--mono)', marginTop: 2 }}>ID: {resolvedUser.robloxId}</div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 5 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <span style={{ width: 7, height: 7, borderRadius: '50%', background: statusColors[resolvedUser.status], animation: statusAnims[resolvedUser.status] }}/>
                <span style={{ fontSize: 11, color: statusColors[resolvedUser.status], fontFamily: 'var(--mono)', textTransform: 'capitalize' }}>{resolvedUser.status}</span>
              </div>
              {resolvedUser.game && <span style={{ fontSize: 10.5, color: 'var(--t3)' }}>{resolvedUser.game}</span>}
            </div>
          </div>
          <div style={{ marginTop: 12, display: 'flex', alignItems: 'center', gap: 6, color: 'var(--green)', fontSize: 11.5, fontWeight: 500 }}>
            <svg width="12" height="12" viewBox="0 0 12 12" fill="none" style={{ animation: 'check-pop 0.4s var(--ease-out-expo) both' }}><path d="M2 6l2.8 2.8L10 3.5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/></svg> Resolved - ready to track
          </div>
        </div>
      )}

      {/* try example links */}
      {!resolvedUser && (
        <div style={{ marginBottom: 20, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          <span style={{ fontSize: 11.5, color: 'var(--t4)', alignSelf: 'center' }}>Try:</span>
          {['xShadowReaper','Phantom_Wolf','VelocityX99'].map(u => (
            <button key={u} onClick={() => { setTrackedInput(u); setResolvedUser(null); }} style={{ fontSize: 11.5, color: 'var(--p4)', background: 'var(--p-dim)', border: '1px solid rgba(6,182,212,0.2)', borderRadius: 20, padding: '3px 10px', cursor: 'pointer', fontFamily: 'var(--mono)', transition: 'all 0.15s' }}
              onMouseEnter={e => e.currentTarget.style.background = 'rgba(6,182,212,0.2)'}
              onMouseLeave={e => e.currentTarget.style.background = 'var(--p-dim)'}
            >{u}</button>
          ))}
        </div>
      )}

      <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginTop: 4 }}>
        <Btn onClick={onNext} disabled={!resolvedUser} style={{ minWidth: 160, justifyContent: 'center' }} icon={<Icon.ArrowRight />}>
          {resolvedUser ? `Track ${resolvedUser.username}` : 'Continue'}
        </Btn>
        <button onClick={onSkip} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--t4)', fontSize: 12.5, fontFamily: 'var(--font)', transition: 'color 0.15s' }} onMouseEnter={e => e.currentTarget.style.color='var(--t2)'} onMouseLeave={e => e.currentTarget.style.color='var(--t4)'}>
          Skip for now ->
        </button>
      </div>
    </StepWrap>
  );
};

// ─── STEP 3: ALERT PREFS ─────────────────────────────────────────────────────
const Step3Alerts = ({ onNext, prefs, setPrefs }) => {
  const options = [
    { id: 'online',  label: 'Member comes online',  desc: 'Fire when a tracked user goes online',         color: 'var(--green)', border: 'rgba(52,211,153,0.22)', bg: 'rgba(52,211,153,0.055)' },
    { id: 'game',    label: 'Member joins a game',   desc: 'Fire when someone starts a Roblox session',   color: 'var(--amber)', border: 'rgba(251,191,36,0.22)', bg: 'rgba(251,191,36,0.055)' },
    { id: 'offline', label: 'Member goes offline',   desc: 'Fire when a tracked user disconnects',        color: 'var(--t3)',    border: 'var(--border)',          bg: 'var(--bg3)'              },
    { id: 'discord', label: 'Discord notifications', desc: 'Push all alerts into your server via webhook', color: 'var(--blue)',  border: 'rgba(96,165,250,0.22)', bg: 'rgba(96,165,250,0.055)' },
  ];

  const optionIcons = {
    online:  <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="3.5" stroke="currentColor" strokeWidth="1.4"/><circle cx="8" cy="8" r="1.5" fill="currentColor"/><path d="M8 1v1.8M8 13.2V15M1 8h1.8M13.2 8H15" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" opacity="0.5"/></svg>,
    game:    <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="1.5" y="5" width="13" height="7.5" rx="2" stroke="currentColor" strokeWidth="1.3"/><path d="M5 8.5H7M6 7.5V9.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/><circle cx="10" cy="8" r=".8" fill="currentColor"/><circle cx="11.5" cy="9.3" r=".8" fill="currentColor"/></svg>,
    offline: <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="5.5" stroke="currentColor" strokeWidth="1.3" opacity="0.4"/><path d="M5 8h6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>,
    discord: <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M13.5 2.5A13 13 0 0 0 10.3 1.5a9 9 0 0 0-.4.8A12 12 0 0 0 6.1 2.3a9 9 0 0 0-.4-.8 13 13 0 0 0-3.2 1 13.7 13.7 0 0 0-2.4 9.3 13 13 0 0 0 4 2 9.7 9.7 0 0 0 .8-1.3A8.5 8.5 0 0 1 3.5 12l.3.2a9.5 9.5 0 0 0 8.4 0l.3-.2a8.5 8.5 0 0 1-1.4.7 9.7 9.7 0 0 0 .8 1.3 13 13 0 0 0 4-2 13.7 13.7 0 0 0-2.4-9.5z" fill="currentColor" opacity="0.9"/><circle cx="5.8" cy="9" r="1.3" fill="var(--bg0)"/><circle cx="10.2" cy="9" r="1.3" fill="var(--bg0)"/></svg>,
  };

  const toggle = (id) => setPrefs(p => ({ ...p, [id]: !p[id] }));

  return (
    <StepWrap>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 10.5, color: 'var(--p4)', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 10 }}>Step 3 of 5</div>
      <h2 style={{ fontSize: 26, fontWeight: 700, letterSpacing: '-0.04em', color: 'var(--t1)', marginBottom: 8 }}>Choose your alerts</h2>
      <p style={{ fontSize: 14, color: 'var(--t2)', marginBottom: 28, lineHeight: 1.6 }}>
        Pick which events fire an alert. You can change these any time in Settings.
      </p>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 28 }}>
        {options.map((opt, i) => {
          const on = prefs[opt.id];
          return (
            <button key={opt.id} onClick={() => toggle(opt.id)} style={{
              display: 'flex', flexDirection: 'column', gap: 10,
              padding: '16px 16px', borderRadius: 12, cursor: 'pointer', textAlign: 'left',
              border: `1.5px solid ${on ? opt.border : 'var(--border)'}`,
              background: on ? opt.bg : 'rgba(255,255,255,0.022)',
              transition: 'all 0.22s var(--ease-out-expo)',
              boxShadow: on ? `0 0 24px ${opt.bg}` : 'none',
              animation: `fadein 0.4s var(--ease-out-expo) ${i * 55}ms both`,
              position: 'relative',
            }}>
              <div style={{ position: 'absolute', top: 12, right: 12, width: 18, height: 18, borderRadius: '50%', background: on ? opt.color : 'var(--bg4)', border: `1.5px solid ${on ? opt.color : 'var(--border)'}`, display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.22s', boxShadow: on ? `0 0 8px ${opt.color}66` : 'none' }}>
                {on && <svg width="9" height="9" viewBox="0 0 10 10" fill="none" style={{ animation: 'check-pop 0.3s var(--ease-out-expo) both' }}><path d="M2 5l2.5 2.5L8 3" stroke="var(--bg0)" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>}
              </div>
              <span style={{ color: opt.color, opacity: on ? 1 : 0.5, display: 'flex', transition: 'opacity 0.2s' }}>{optionIcons[opt.id]}</span>
              <div>
                <div style={{ fontSize: 13, fontWeight: 600, color: on ? 'var(--t1)' : 'var(--t2)', letterSpacing: '-0.01em' }}>{opt.label}</div>
                <div style={{ fontSize: 11.5, color: 'var(--t3)', marginTop: 4, lineHeight: 1.5 }}>{opt.desc}</div>
              </div>
            </button>
          );
        })}
      </div>

      <Btn onClick={onNext} style={{ minWidth: 200, justifyContent: 'center' }} icon={<Icon.ArrowRight />}>
        Continue
      </Btn>
    </StepWrap>
  );
};

// ─── STEP 4: DISCORD SETUP ───────────────────────────────────────────────────
const Step4Discord = ({ onNext, onSkip, webhookUrl, setWebhookUrl }) => {
  const [testing, setTesting] = useState(false);
  const [tested, setTested]   = useState(false);

  const handleTest = async () => {
    setTesting(true); setTested(false);
    await new Promise(r => setTimeout(r, 900));
    setTesting(false); setTested(true);
    setTimeout(() => setTested(false), 3000);
  };

  const isValid = webhookUrl.startsWith('https://discord.com/api/webhooks/');

  return (
    <StepWrap>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 10.5, color: 'var(--p4)', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 10 }}>Step 4 of 5</div>
      <h2 style={{ fontSize: 26, fontWeight: 700, letterSpacing: '-0.04em', color: 'var(--t1)', marginBottom: 8 }}>Connect Discord</h2>
      <p style={{ fontSize: 14, color: 'var(--t2)', marginBottom: 22, lineHeight: 1.6 }}>
        Paste a webhook URL and alerts will fire straight into your server. Totally optional.
      </p>

      <div style={{ display: 'flex', gap: 8, marginBottom: 14 }}>
        <div style={{ flex: 1 }}>
          <Input value={webhookUrl} onChange={setWebhookUrl} placeholder="https://discord.com/api/webhooks/..." icon={<Icon.Discord />} />
        </div>
        {webhookUrl && (
          <Btn variant="ghost" onClick={handleTest} disabled={testing || !isValid}>
            {testing ? <span style={{ animation: 'spin 0.7s linear infinite', display: 'inline-block', fontSize: 15 }}>&#8635;</span> : tested ? 'Sent' : 'Test'}
          </Btn>
        )}
      </div>

      {/* Discord message preview */}
      <div style={{ background: '#313338', borderRadius: 12, padding: 16, marginBottom: 24, border: '1px solid rgba(255,255,255,0.06)' }}>
        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ width: 36, height: 36, borderRadius: '50%', background: 'var(--p6)', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, fontWeight: 700, color: '#fff' }}>R</div>
          <div style={{ flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
              <span style={{ fontSize: 13, fontWeight: 700, color: '#fff' }}>RoStealth</span>
              <span style={{ fontSize: 10, background: '#5865F2', color: '#fff', padding: '1px 5px', borderRadius: 3, fontWeight: 600 }}>BOT</span>
              <span style={{ fontSize: 11, color: '#949ba4' }}>Today at 2:04 PM</span>
            </div>
            <div style={{ fontSize: 12.5, color: '#dbdee1', lineHeight: 1.5 }}>
              <span style={{ color: '#34D399', fontWeight: 600 }}>xShadowReaper</span> is now <span style={{ color: '#34D399' }}>online</span> · <span style={{ color: '#949ba4' }}>Da Hood</span>
            </div>
          </div>
        </div>
        <div style={{ marginTop: 10, fontSize: 10.5, color: '#949ba4', fontFamily: 'var(--mono)' }}>Preview — how alerts appear in your server</div>
      </div>

      <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
        <Btn onClick={onNext} style={{ minWidth: 160, justifyContent: 'center' }} icon={<Icon.ArrowRight />}>
          {webhookUrl ? 'Save & continue' : 'Continue'}
        </Btn>
        <button onClick={onSkip} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--t4)', fontSize: 12.5, fontFamily: 'var(--font)', transition: 'color 0.15s' }} onMouseEnter={e => e.currentTarget.style.color='var(--t2)'} onMouseLeave={e => e.currentTarget.style.color='var(--t4)'}>
          Skip Discord →
        </button>
      </div>
    </StepWrap>
  );
};

// ─── STEP 5: PAYMENT ─────────────────────────────────────────────────────────
const Step5Pay = ({ onPay, paying, resolvedUser, prefs, webhookUrl }) => {
  const activePrefs = Object.entries(prefs).filter(([, v]) => v).map(([k]) => k);
  const prefLabels = { online: 'Online alerts', game: 'Game join alerts', offline: 'Offline alerts', discord: 'Discord notifications' };

  const features = [
    'Unlimited users & groups',
    'Status refresh every 30 seconds',
    '30-day session history',
    'Discord webhook alerts',
    'Custom alert rules',
    'Full REST API access',
  ];

  return (
    <StepWrap>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 10.5, color: 'var(--p4)', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 10 }}>Step 5 of 5</div>
      <h2 style={{ fontSize: 26, fontWeight: 700, letterSpacing: '-0.04em', color: 'var(--t1)', marginBottom: 6 }}>You're all set up.</h2>
      <p style={{ fontSize: 14, color: 'var(--t2)', marginBottom: 24, lineHeight: 1.6 }}>
        Start watching for <span style={{ color: 'var(--t1)', fontWeight: 600 }}>$5</span> — one payment, 30 days of full access.
      </p>

      {/* summary card */}
      {(resolvedUser || activePrefs.length > 0 || webhookUrl) && (
        <div style={{ background: 'var(--bg3)', border: '1px solid var(--border)', borderRadius: 12, padding: '14px 16px', marginBottom: 18, animation: 'fadein 0.4s var(--ease-out-expo) 0.08s both' }}>
          <div style={{ fontSize: 10.5, color: 'var(--t4)', fontFamily: 'var(--mono)', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 12 }}>Your setup</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {resolvedUser && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Avatar name={resolvedUser.username} size={22} />
                <span style={{ fontSize: 12.5, color: 'var(--t1)' }}>Tracking <b>{resolvedUser.username}</b></span>
                <span style={{ marginLeft: 'auto', fontSize: 10, color: 'var(--green)', fontFamily: 'var(--mono)' }}>READY</span>
              </div>
            )}
            {activePrefs.map(k => (
              <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ color: 'var(--p4)', fontSize: 10 }}><Icon.Check /></span>
                <span style={{ fontSize: 12.5, color: 'var(--t2)' }}>{prefLabels[k]}</span>
              </div>
            ))}
            {webhookUrl && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ color: 'var(--blue)' }}><Icon.Discord /></span>
                <span style={{ fontSize: 12.5, color: 'var(--t2)' }}>Discord connected</span>
              </div>
            )}
          </div>
        </div>
      )}

      {/* pricing card */}
      <div style={{ background: 'var(--bg2)', border: '1px solid rgba(6,182,212,0.28)', borderRadius: 16, overflow: 'hidden', marginBottom: 20, boxShadow: '0 0 30px rgba(6,182,212,0.1)', animation: 'fadein 0.4s var(--ease-out-expo) 0.16s both' }}>
        <div style={{ height: 2, background: 'linear-gradient(90deg, var(--p6), var(--p4), transparent)', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', inset: 0, width: '40%', background: 'linear-gradient(90deg,transparent,rgba(255,255,255,0.5),transparent)', animation: 'shimmer 3s ease-in-out infinite 0.8s' }}/>
        </div>
        <div style={{ padding: '20px 22px' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 4 }}>
            <span style={{ fontSize: 44, fontWeight: 700, color: 'var(--t1)', letterSpacing: '-0.055em', lineHeight: 1, textShadow: '0 0 28px rgba(6,182,212,0.25)' }}>$5</span>
            <span style={{ fontSize: 14, color: 'var(--t3)' }}>/ 30 days</span>
          </div>
          <div style={{ fontSize: 12, color: 'var(--t3)', marginBottom: 16 }}>One payment · no subscription · renew when you want</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '7px 18px' }}>
            {features.map(f => (
              <div key={f} style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
                <span style={{ color: 'var(--p4)', flexShrink: 0, fontSize: 10 }}><Icon.Check /></span>
                <span style={{ fontSize: 12, color: 'var(--t2)' }}>{f}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* pay button */}
      <button onClick={onPay} disabled={paying} style={{
        width: '100%', padding: '14px 24px', borderRadius: 12, border: 'none', cursor: paying ? 'not-allowed' : 'pointer',
        background: paying ? 'var(--bg4)' : 'var(--p6)', color: '#fff', fontFamily: 'var(--font)', fontSize: 15, fontWeight: 700, letterSpacing: '-0.01em',
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
        boxShadow: paying ? 'none' : '0 0 0 1px rgba(255,255,255,0.08) inset, 0 4px 24px rgba(6,182,212,0.45), 0 0 50px rgba(6,182,212,0.15)',
        transition: 'all 0.2s var(--ease-out-expo)',
        animation: 'fadein 0.4s var(--ease-out-expo) 0.24s both',
      }}
        onMouseEnter={e => { if (!paying) e.currentTarget.style.filter='brightness(1.12)'; }}
        onMouseLeave={e => e.currentTarget.style.filter='none'}
      >
        {paying ? (
          <><span style={{ animation: 'spin 0.8s linear infinite', display: 'inline-block' }}>&#8635;</span> Processing...</>
        ) : (
          <><Icon.Bolt /> Pay $5 · Start watching</>
        )}
      </button>
      <div style={{ marginTop: 10, fontSize: 11, color: 'var(--t4)', textAlign: 'center', lineHeight: 1.6 }}>
        Secure payment · access activates instantly · not affiliated with Roblox Corp.
      </div>
    </StepWrap>
  );
};

// ─── ONBOARDING SHELL ─────────────────────────────────────────────────────────
const Onboarding = ({ user, onComplete }) => {
  const [step, setStep]             = useState(0);
  const [trackedInput, setTrackedInput] = useState('');
  const [resolvedUser, setResolvedUser] = useState(null);
  const [prefs, setPrefs]           = useState({ online: true, game: true, offline: false, discord: true });
  const [webhookUrl, setWebhookUrl] = useState('');
  const [paying, setPaying]         = useState(false);

  const goNext = useCallback(() => setStep(s => s + 1), []);

  const handlePay = async () => {
    setPaying(true);
    await new Promise(r => setTimeout(r, 1400));
    const firstUser = resolvedUser ? {
      id: Date.now(), robloxId: resolvedUser.robloxId, username: resolvedUser.username,
      status: resolvedUser.status, game: resolvedUser.game, lastSeen: resolvedUser.status !== 'offline' ? 'Now' : 'Never',
      sessions: 0, hours: 0, flagged: false, type: 'user',
    } : null;
    onComplete({ firstUser, prefs, webhookUrl });
  };

  const steps = [
    <Step1Welcome key={0} username={user.username} onNext={goNext} />,
    <Step2Track   key={1} onNext={goNext} onSkip={goNext} trackedInput={trackedInput} setTrackedInput={setTrackedInput} resolvedUser={resolvedUser} setResolvedUser={setResolvedUser} />,
    <Step3Alerts  key={2} onNext={goNext} prefs={prefs} setPrefs={setPrefs} />,
    <Step4Discord key={3} onNext={goNext} onSkip={goNext} webhookUrl={webhookUrl} setWebhookUrl={setWebhookUrl} />,
    <Step5Pay     key={4} onPay={handlePay} paying={paying} resolvedUser={resolvedUser} prefs={prefs} webhookUrl={webhookUrl} />,
  ];

  return (
    <div style={{ minHeight: '100vh', background: 'var(--bg0)', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '32px 24px', position: 'relative', overflow: 'hidden' }}>
      <RadarBg />

      {/* edge vignette */}
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', background: 'radial-gradient(ellipse 110% 110% at 50% 50%, transparent 45%, rgba(0,0,0,0.55) 100%)' }} />

      {/* content panel */}
      <div style={{ position: 'relative', zIndex: 1, width: '100%', maxWidth: 520, display: 'flex', flexDirection: 'column', gap: 0 }}>

        {/* top bar: logo + step bar */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 40, animation: 'fadein 0.5s var(--ease-out-expo) both' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
            <div style={{ width: 26, height: 26, borderRadius: 7, background: 'linear-gradient(145deg,#0891B2,#0E7490)', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 0 10px rgba(6,182,212,0.4)' }}>
              <svg width="12" height="12" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="5.5" stroke="white" strokeWidth="1.1" opacity="0.45"/><circle cx="8" cy="8" r="2.3" stroke="white" strokeWidth="1" opacity="0.65"/><circle cx="8" cy="8" r="1.1" fill="white"/></svg>
            </div>
            <span style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--t1)' }}>RoStealth</span>
          </div>
          <div style={{ flex: 1 }}>
            <StepBar current={step} total={5} />
          </div>
          {step > 0 && step < 4 && (
            <button onClick={() => setStep(s => Math.max(0, s - 1))} style={{ background: 'none', border: 'none', color: 'var(--t4)', cursor: 'pointer', fontSize: 12, fontFamily: 'var(--mono)', flexShrink: 0, transition: 'color 0.15s' }} onMouseEnter={e => e.currentTarget.style.color='var(--t2)'} onMouseLeave={e => e.currentTarget.style.color='var(--t4)'}>
              ← Back
            </button>
          )}
        </div>

        {/* step content */}
        <div key={step} style={{ animation: 'step-in 0.36s var(--ease-out-expo) both' }}>
          {steps[step]}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { Onboarding });
