// auth.jsx — Login + Signup + 6-step Onboarding for uri-jib.com

function LoginPage() {
  const { login } = useAuth();
  const [email, setEmail] = useState('');
  const [pw, setPw] = useState('');
  const [err, setErr] = useState('');
  const [loading, setLoading] = useState(null);

  useEffect(() => { document.title = '로그인 — 우리집사기'; }, []);

  const ssoLogin = async (provider) => {
    setLoading(provider);
    window.UJTrack.track('login_attempt', { provider, method: 'sso' });
    // 시뮬레이션: 실제로는 OAuth redirect
    await new Promise(r => setTimeout(r, 900));
    const user = {
      id: 'u_' + provider + '_' + Math.random().toString(36).slice(2, 8),
      name: provider === 'kakao' ? '김민준' : provider === 'naver' ? '이서연' : provider === 'google' ? 'Jin Park' : 'Hyun Lee',
      email: 'demo@' + provider + '.test',
      provider,
      method: 'sso',
      avatar: null,
      joinedAt: Date.now(),
    };
    login(user);
    setLoading(null);
    navigate('/app/dashboard');
  };

  const emailLogin = (e) => {
    e.preventDefault();
    setErr('');
    window.UJTrack.track('login_attempt', { provider: 'email', method: 'password' });
    if (!email || !pw) {
      setErr('이메일과 비밀번호를 모두 입력해주세요.');
      window.UJTrack.track('login_fail', { reason: 'missing_fields' });
      return;
    }
    if (pw.length < 6) {
      setErr('비밀번호가 일치하지 않습니다.');
      window.UJTrack.track('login_fail', { reason: 'wrong_password' });
      return;
    }
    setLoading('email');
    setTimeout(() => {
      login({
        id: 'u_email_' + Math.random().toString(36).slice(2, 8),
        name: email.split('@')[0],
        email,
        provider: 'email',
        method: 'password',
        joinedAt: Date.now(),
      });
      setLoading(null);
      navigate('/app/dashboard');
    }, 700);
  };

  return (
    <AuthShell title="다시 오신 것을 환영합니다" subtitle="계속하려면 로그인 방식을 선택하세요.">
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <SSOButton provider="kakao" loading={loading === 'kakao'} onClick={() => ssoLogin('kakao')} />
        <SSOButton provider="naver" loading={loading === 'naver'} onClick={() => ssoLogin('naver')} />
        <SSOButton provider="google" loading={loading === 'google'} onClick={() => ssoLogin('google')} />
        <SSOButton provider="apple" loading={loading === 'apple'} onClick={() => ssoLogin('apple')} />
      </div>

      <Divider label="또는 이메일로" />

      <form onSubmit={emailLogin} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <Field label="이메일" type="email" value={email} onChange={setEmail} placeholder="you@example.com" />
        <Field label="비밀번호" type="password" value={pw} onChange={setPw} placeholder="••••••••" />
        {err && <div style={{ fontSize: 12, color: T.down, fontFamily: T.mono }}>⚠ {err}</div>}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 4 }}>
          <a href="#/forgot" data-track="forgot_password" style={{ fontSize: 12, color: T.fgDim, textDecoration: 'none' }}>비밀번호를 잊으셨나요?</a>
          <button type="submit" data-track="login_submit" disabled={loading === 'email'} style={{
            ...primaryBtn, opacity: loading === 'email' ? 0.6 : 1, padding: '12px 24px',
          }}>
            {loading === 'email' ? '로그인 중…' : '로그인 →'}
          </button>
        </div>
      </form>

      <div style={{ textAlign: 'center', marginTop: 24, fontSize: 13, color: T.fgMuted }}>
        계정이 없으신가요? <a href="#/signup" data-track="to_signup" style={{ color: T.hot, textDecoration: 'none', fontWeight: 600 }}>가입하기 →</a>
      </div>
    </AuthShell>
  );
}

function SignupPage() {
  const { login } = useAuth();
  const [email, setEmail] = useState(new URLSearchParams(location.hash.split('?')[1] || '').get('email') || '');
  const [pw, setPw] = useState('');
  const [name, setName] = useState('');
  const [agree, setAgree] = useState({ tos: false, privacy: false, marketing: false });
  const [err, setErr] = useState('');
  const [loading, setLoading] = useState(null);

  useEffect(() => { document.title = '회원가입 — 우리집사기'; }, []);

  const ssoSignup = async (provider) => {
    setLoading(provider);
    window.UJTrack.track('signup_start', { provider, method: 'sso' });
    await new Promise(r => setTimeout(r, 900));
    const user = {
      id: 'u_' + provider + '_' + Math.random().toString(36).slice(2, 8),
      name: '새 사용자',
      email: 'demo@' + provider + '.test',
      provider, method: 'sso', joinedAt: Date.now(), onboarded: false,
    };
    login(user);
    window.UJTrack.track('signup_complete', { provider });
    setLoading(null);
    navigate('/onboarding/1');
  };

  const onSubmit = (e) => {
    e.preventDefault();
    setErr('');
    window.UJTrack.track('signup_attempt', { provider: 'email' });
    if (!agree.tos || !agree.privacy) {
      setErr('필수 약관에 동의해주세요.');
      window.UJTrack.track('signup_fail', { reason: 'tos' });
      return;
    }
    if (pw.length < 8) {
      setErr('비밀번호는 8자 이상이어야 합니다.');
      window.UJTrack.track('signup_fail', { reason: 'pw_short' });
      return;
    }
    setLoading('email');
    setTimeout(() => {
      login({
        id: 'u_email_' + Math.random().toString(36).slice(2, 8),
        name: name || email.split('@')[0],
        email, provider: 'email', method: 'password',
        joinedAt: Date.now(), onboarded: false,
        consent: { ...agree, ts: Date.now() },
      });
      window.UJTrack.track('signup_complete', { provider: 'email', marketing_opt_in: agree.marketing });
      setLoading(null);
      navigate('/onboarding/1');
    }, 700);
  };

  return (
    <AuthShell title="무료로 시작하기" subtitle="30초면 끝나요. 신용카드 불필요.">
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <SSOButton provider="kakao" loading={loading === 'kakao'} onClick={() => ssoSignup('kakao')} signup />
        <SSOButton provider="naver" loading={loading === 'naver'} onClick={() => ssoSignup('naver')} signup />
        <SSOButton provider="google" loading={loading === 'google'} onClick={() => ssoSignup('google')} signup />
        <SSOButton provider="apple" loading={loading === 'apple'} onClick={() => ssoSignup('apple')} signup />
      </div>

      <Divider label="또는 이메일로" />

      <form onSubmit={onSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <Field label="이름" value={name} onChange={setName} placeholder="홍길동" />
        <Field label="이메일" type="email" value={email} onChange={setEmail} placeholder="you@example.com" required />
        <Field label="비밀번호 (8자 이상)" type="password" value={pw} onChange={setPw} placeholder="••••••••" required />

        <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 8 }}>
          <Checkbox checked={agree.tos} onChange={(v) => setAgree({...agree, tos: v})} required
            label={<>이용약관에 동의합니다 <span style={{ color: T.down }}>*</span> <a href="#/terms" data-track="view_tos" style={{ color: T.info, fontSize: 11, marginLeft: 4 }}>보기</a></>} />
          <Checkbox checked={agree.privacy} onChange={(v) => setAgree({...agree, privacy: v})} required
            label={<>개인정보 수집·이용에 동의합니다 <span style={{ color: T.down }}>*</span> <a href="#/privacy" data-track="view_privacy" style={{ color: T.info, fontSize: 11, marginLeft: 4 }}>보기</a></>} />
          <Checkbox checked={agree.marketing} onChange={(v) => setAgree({...agree, marketing: v})}
            label="마케팅 알림 수신 (선택)" />
        </div>

        {err && <div style={{ fontSize: 12, color: T.down, fontFamily: T.mono }}>⚠ {err}</div>}

        <button type="submit" data-track="signup_submit" disabled={loading === 'email'} style={{
          ...primaryBtn, marginTop: 8, padding: '14px 24px', width: '100%', justifyContent: 'center', opacity: loading === 'email' ? 0.6 : 1,
        }}>
          {loading === 'email' ? '가입 중…' : '계정 만들기 →'}
        </button>
      </form>

      <div style={{ textAlign: 'center', marginTop: 24, fontSize: 13, color: T.fgMuted }}>
        이미 계정이 있으신가요? <a href="#/login" data-track="to_login" style={{ color: T.hot, textDecoration: 'none', fontWeight: 600 }}>로그인 →</a>
      </div>
    </AuthShell>
  );
}

// ─────────────────────────────────────────────────────────
// Onboarding 6 steps
// ─────────────────────────────────────────────────────────
const ONBOARD_STEPS = 6;

function OnboardingPage({ step }) {
  const { user, login } = useAuth();
  const [data, setData] = useState(() => {
    try { return JSON.parse(localStorage.getItem('urijib_onboard') || '{}'); } catch (e) { return {}; }
  });

  useEffect(() => {
    document.title = `온보딩 ${step}/${ONBOARD_STEPS} — 우리집사기`;
    window.UJTrack.track('onboarding_step', { step });
  }, [step]);

  useEffect(() => {
    localStorage.setItem('urijib_onboard', JSON.stringify(data));
  }, [data]);

  if (!user) {
    useEffect(() => { navigate('/login'); }, []);
    return null;
  }

  const next = () => {
    if (step < ONBOARD_STEPS) navigate('/onboarding/' + (step + 1));
    else {
      window.UJTrack.track('onboarding_complete', data);
      login({ ...user, onboarded: true, preferences: data });
      navigate('/app/dashboard');
    }
  };
  const back = () => { if (step > 1) navigate('/onboarding/' + (step - 1)); };

  return (
    <div style={{ minHeight: '100vh', background: T.bg, color: T.fg, fontFamily: T.font, display: 'flex', flexDirection: 'column' }}>
      <header style={{ padding: '20px 24px', borderBottom: '1px solid ' + T.line, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Logo size={24} />
          <span style={{ fontSize: 14, fontWeight: 600 }}>우리집사기</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ fontFamily: T.mono, fontSize: 12, color: T.fgMuted }}>{step}/{ONBOARD_STEPS}</span>
          <a href="#/app/dashboard" data-track="onboarding_skip" data-track-step={step} style={{ fontSize: 12, color: T.fgDim, textDecoration: 'none' }}>건너뛰기</a>
        </div>
      </header>

      {/* Progress */}
      <div style={{ height: 2, background: T.line }}>
        <div style={{ height: '100%', width: (step / ONBOARD_STEPS * 100) + '%', background: T.hot, transition: 'width .3s' }} />
      </div>

      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
        <div style={{ width: '100%', maxWidth: 560 }}>
          {step === 1 && <Step1Welcome user={user} />}
          {step === 2 && <Step2Terms data={data} setData={setData} />}
          {step === 3 && <Step3Mode data={data} setData={setData} />}
          {step === 4 && <Step4Region data={data} setData={setData} />}
          {step === 5 && <Step5Budget data={data} setData={setData} />}
          {step === 6 && <Step6Notify data={data} setData={setData} />}
        </div>
      </div>

      <footer style={{ borderTop: '1px solid ' + T.line, padding: '16px 24px', display: 'flex', justifyContent: 'space-between', gap: 12 }}>
        <button onClick={back} disabled={step <= 1} data-track="onboarding_back"
          style={{ ...ghostBtn, opacity: step <= 1 ? 0.3 : 1, padding: '10px 20px' }}>
          ← 이전
        </button>
        <button onClick={next} data-track="onboarding_next" data-track-step={step}
          style={{ ...primaryBtn, padding: '12px 28px' }}>
          {step === ONBOARD_STEPS ? '완료 · 시작하기' : '다음 →'}
        </button>
      </footer>
    </div>
  );
}

function Step1Welcome({ user }) {
  return (
    <div style={{ textAlign: 'center' }}>
      <Logo size={72} />
      <h1 style={{ fontSize: 32, fontWeight: 800, margin: '24px 0 12px' }}>
        환영합니다, {user.name}님.
      </h1>
      <p style={{ fontSize: 15, color: T.fgDim, lineHeight: 1.7, maxWidth: 420, margin: '0 auto' }}>
        매수 적기를 알려드리려면 몇 가지만 알려주세요.<br/>
        모든 항목은 언제든 설정에서 바꿀 수 있습니다.
      </p>
      <div style={{ marginTop: 32, display: 'flex', flexDirection: 'column', gap: 10, textAlign: 'left' }}>
        {['이용약관 확인', '관심 모드 선택', '관심 지역 선택', '예산 설정', '알림 권한'].map((label, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 16px', background: T.card, border: '1px solid ' + T.line, borderRadius: 4 }}>
            <div style={{ width: 24, height: 24, borderRadius: 12, background: T.cardLo, color: T.fgDim, fontFamily: T.mono, fontSize: 11, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{i + 2}</div>
            <div style={{ fontSize: 13 }}>{label}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function Step2Terms({ data, setData }) {
  const items = [
    { key: 'tos', label: '이용약관 동의', required: true },
    { key: 'privacy', label: '개인정보 처리방침 동의', required: true },
    { key: 'over14', label: '만 14세 이상입니다', required: true },
    { key: 'marketing', label: '마케팅 알림 수신 (선택)', required: false },
  ];
  const consent = data.consent || {};
  const set = (k, v) => setData({ ...data, consent: { ...consent, [k]: v, ts: Date.now() } });
  return (
    <div>
      <StepHeader num={2} title="약관 동의" desc="서비스 이용을 위해 필요한 동의입니다." />
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {items.map((it) => (
          <label key={it.key} style={{
            display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px',
            background: T.card, border: '1px solid ' + (consent[it.key] ? T.hot : T.line),
            borderRadius: 4, cursor: 'pointer',
          }}>
            <Checkbox checked={!!consent[it.key]} onChange={(v) => set(it.key, v)} />
            <div style={{ flex: 1, fontSize: 14 }}>
              {it.label} {it.required && <span style={{ color: T.down, fontSize: 11 }}>*필수</span>}
            </div>
            <a href={'#/' + it.key} data-track="view_terms_doc" data-track-doc={it.key}
              style={{ fontSize: 11, color: T.info, fontFamily: T.mono }}>보기</a>
          </label>
        ))}
      </div>
    </div>
  );
}

function Step3Mode({ data, setData }) {
  const modes = [
    { id: 'first', label: '생애 첫 주택', desc: '실거주 위주, 대출 한도 중심' },
    { id: 'upgrade', label: '갈아타기', desc: '현 자산 활용 + 양도세 최적화' },
    { id: 'invest', label: '투자', desc: '시세차익 + 임대수익 중심' },
  ];
  return (
    <div>
      <StepHeader num={3} title="어떤 목적으로 보고 계세요?" desc="모드에 따라 추천 단지와 지표가 달라집니다." />
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {modes.map((m) => (
          <button key={m.id} data-track="onboarding_mode" data-track-mode={m.id}
            onClick={() => setData({ ...data, mode: m.id })}
            style={{
              textAlign: 'left', padding: '16px 20px',
              background: data.mode === m.id ? T.hotBg : T.card,
              border: '1px solid ' + (data.mode === m.id ? T.hot : T.line),
              borderRadius: 4, cursor: 'pointer', color: T.fg, fontFamily: T.font,
            }}>
            <div style={{ fontSize: 15, fontWeight: 600 }}>{m.label}</div>
            <div style={{ fontSize: 12, color: T.fgDim, marginTop: 4 }}>{m.desc}</div>
          </button>
        ))}
      </div>
    </div>
  );
}

function Step4Region({ data, setData }) {
  const regions = ['강남구', '서초구', '송파구', '용산구', '마포구', '분당구', '판교', '광교/수원', '일산', '인천 송도', '대전 둔산', '부산 해운대'];
  const selected = data.regions || [];
  const toggle = (r) => {
    const next = selected.includes(r) ? selected.filter(x => x !== r) : [...selected, r];
    setData({ ...data, regions: next });
    window.UJTrack.track('onboarding_region_toggle', { region: r, selected: !selected.includes(r) });
  };
  return (
    <div>
      <StepHeader num={4} title="관심 지역" desc="최대 5개까지 선택. 시그널·뉴스가 이 지역 중심으로 노출됩니다." />
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
        {regions.map((r) => (
          <button key={r} onClick={() => toggle(r)} data-track="onboarding_region"
            style={{
              padding: '10px 16px', borderRadius: 999,
              background: selected.includes(r) ? T.hot : T.card,
              color: selected.includes(r) ? T.bg : T.fg,
              border: '1px solid ' + (selected.includes(r) ? T.hot : T.line),
              fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: T.font,
            }}>{r}</button>
        ))}
      </div>
      <div style={{ marginTop: 12, fontSize: 12, color: T.fgMuted, fontFamily: T.mono }}>
        선택: {selected.length}/5
      </div>
    </div>
  );
}

function Step5Budget({ data, setData }) {
  const v = data.budget || 80000; // 8억 default
  return (
    <div>
      <StepHeader num={5} title="예산" desc="총 매수 가능 금액 (대출 포함)" />
      <div style={{ background: T.card, border: '1px solid ' + T.line, borderRadius: 4, padding: 24 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 16 }}>
          <span style={{ fontSize: 12, color: T.fgMuted, fontFamily: T.mono, letterSpacing: 1 }}>예산</span>
          <span className="uj-num" style={{ fontSize: 32, fontWeight: 700, color: T.hot }}>{won(v)}</span>
        </div>
        <input type="range" min={20000} max={500000} step={5000} value={v}
          onChange={(e) => setData({ ...data, budget: parseInt(e.target.value) })}
          onMouseUp={() => window.UJTrack.track('onboarding_budget_change', { value: v })}
          style={{ width: '100%', accentColor: T.hot }} />
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: T.fgFaint, fontFamily: T.mono, marginTop: 8 }}>
          <span>2억</span><span>50억</span>
        </div>
        <div style={{ marginTop: 20, padding: 12, background: T.cardLo, borderRadius: 4, fontSize: 12, color: T.fgDim, lineHeight: 1.6 }}>
          이 예산이면 대략 <strong style={{ color: T.fg }}>{Math.floor(v / 10000)}억대</strong> 단지가 후보로 들어옵니다.
          대출 한도는 다음 단계에서 정확히 계산해드려요.
        </div>
      </div>
    </div>
  );
}

function Step6Notify({ data, setData }) {
  const prefs = data.notify || { push: true, email: true, news: true, signal: true };
  const set = (k, v) => setData({ ...data, notify: { ...prefs, [k]: v } });
  const items = [
    { k: 'signal', label: 'AI 시그널 변동', desc: 'BUY/WATCH/HOLD 변화 시 알림' },
    { k: 'news', label: '관심 지역 뉴스', desc: 'GTX·재건축·정책 호재/악재' },
    { k: 'push', label: '푸시 알림', desc: '모바일 푸시 메시지' },
    { k: 'email', label: '이메일 다이제스트', desc: '주 1회 시장 요약' },
  ];
  return (
    <div>
      <StepHeader num={6} title="알림 설정" desc="원하는 만큼만 받으세요. 언제든 끌 수 있습니다." />
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {items.map((it) => (
          <div key={it.k} style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            padding: '14px 16px', background: T.card, border: '1px solid ' + T.line, borderRadius: 4,
          }}>
            <div>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{it.label}</div>
              <div style={{ fontSize: 12, color: T.fgMuted, marginTop: 2 }}>{it.desc}</div>
            </div>
            <Toggle on={prefs[it.k]} onChange={(v) => { set(it.k, v); window.UJTrack.track('onboarding_notify_toggle', { kind: it.k, on: v }); }} />
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── Atoms ──────────────────────────────────────────────
function AuthShell({ title, subtitle, children }) {
  return (
    <div style={{ minHeight: '100vh', background: T.bg, color: T.fg, fontFamily: T.font, display: 'flex', flexDirection: 'column' }}>
      <header style={{ padding: '20px 24px', borderBottom: '1px solid ' + T.line }}>
        <a href="#/" data-track="auth_back_home" style={{ display: 'inline-flex', alignItems: 'center', gap: 10, textDecoration: 'none' }}>
          <Logo size={24} />
          <span style={{ fontSize: 14, fontWeight: 600, color: T.fg }}>우리집사기</span>
        </a>
      </header>
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
        <div style={{ width: '100%', maxWidth: 420 }}>
          <h1 style={{ fontSize: 28, fontWeight: 700, margin: 0, letterSpacing: '-0.01em' }}>{title}</h1>
          {subtitle && <p style={{ fontSize: 13, color: T.fgDim, marginTop: 8, marginBottom: 32 }}>{subtitle}</p>}
          {children}
        </div>
      </div>
    </div>
  );
}

function SSOButton({ provider, onClick, loading, signup }) {
  const styles = {
    kakao:  { bg: '#FEE500', fg: '#1A1A1A', label: '카카오' },
    naver:  { bg: '#03C75A', fg: '#FFFFFF', label: '네이버' },
    google: { bg: '#FFFFFF', fg: '#1F1F1F', label: 'Google', border: '#DADCE0' },
    apple:  { bg: '#000000', fg: '#FFFFFF', label: 'Apple' },
  }[provider];
  const verb = signup ? '으로 가입' : '으로 계속';
  return (
    <button onClick={onClick} disabled={loading}
      data-track="sso_click" data-track-provider={provider} data-track-action={signup ? 'signup' : 'login'}
      style={{
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
        padding: '12px 16px', borderRadius: 4,
        background: styles.bg, color: styles.fg,
        border: styles.border ? '1px solid ' + styles.border : 'none',
        fontSize: 14, fontWeight: 600, cursor: loading ? 'wait' : 'pointer',
        fontFamily: T.font, opacity: loading ? 0.7 : 1,
        transition: 'transform .1s',
      }}
      onMouseDown={(e) => e.currentTarget.style.transform = 'scale(0.99)'}
      onMouseUp={(e) => e.currentTarget.style.transform = 'none'}
    >
      <ProviderGlyph provider={provider} color={styles.fg} />
      <span>{loading ? '연결 중…' : styles.label + verb}</span>
    </button>
  );
}

// Original SSO mark — simple letter glyphs, NOT brand logos
function ProviderGlyph({ provider, color }) {
  const size = 18;
  if (provider === 'kakao') {
    return (
      <svg width={size} height={size} viewBox="0 0 18 18">
        <ellipse cx="9" cy="8" rx="7" ry="5.5" fill={color} opacity="0.9"/>
        <path d="M6 12 L5 15 L8 13" fill={color} opacity="0.9"/>
      </svg>
    );
  }
  if (provider === 'naver') {
    return (
      <svg width={size} height={size} viewBox="0 0 18 18">
        <rect x="3" y="3" width="12" height="12" rx="1" fill={color}/>
        <path d="M6 6 L6 12 M6 6 L11 12 M11 6 L11 12" stroke={provider === 'naver' ? '#03C75A' : color} strokeWidth="1.6" fill="none"/>
      </svg>
    );
  }
  if (provider === 'google') {
    return (
      <svg width={size} height={size} viewBox="0 0 18 18">
        <circle cx="9" cy="9" r="6" fill="none" stroke={color} strokeWidth="2"/>
        <rect x="9" y="8" width="6" height="2" fill={color}/>
      </svg>
    );
  }
  if (provider === 'apple') {
    return (
      <svg width={size} height={size} viewBox="0 0 18 18">
        <circle cx="9" cy="10" r="4" fill={color}/>
        <ellipse cx="11" cy="5" rx="1.2" ry="2" fill={color} transform="rotate(20 11 5)"/>
      </svg>
    );
  }
  return null;
}

function Divider({ label }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '24px 0', color: T.fgMuted, fontSize: 11, fontFamily: T.mono, letterSpacing: 1 }}>
      <div style={{ flex: 1, height: 1, background: T.line }} />
      <span>{label}</span>
      <div style={{ flex: 1, height: 1, background: T.line }} />
    </div>
  );
}

function Field({ label, value, onChange, type = 'text', placeholder, required }) {
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <span style={{ fontSize: 11, color: T.fgDim, fontFamily: T.mono, letterSpacing: 1, textTransform: 'uppercase' }}>{label}</span>
      <input
        type={type} required={required} value={value} placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
        onFocus={() => window.UJTrack.track('field_focus', { field: label })}
        style={{
          padding: '12px 14px', borderRadius: 4,
          background: T.cardLo, color: T.fg, border: '1px solid ' + T.line,
          fontSize: 14, fontFamily: T.font, outline: 'none',
        }}
        onFocusCapture={(e) => e.target.style.borderColor = T.hot}
        onBlur={(e) => e.target.style.borderColor = T.line}
      />
    </label>
  );
}

function Checkbox({ checked, onChange, label, required }) {
  return (
    <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 13, color: T.fgDim }}>
      <span style={{
        width: 18, height: 18, borderRadius: 3,
        background: checked ? T.hot : T.cardLo,
        border: '1px solid ' + (checked ? T.hot : T.lineHi),
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}>
        {checked && <svg width="12" height="12" viewBox="0 0 12 12"><path d="M2 6 L5 9 L10 3" stroke={T.bg} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>}
      </span>
      <input type="checkbox" checked={checked} required={required}
        onChange={(e) => onChange(e.target.checked)} style={{ display: 'none' }} />
      {label && <span>{label}</span>}
    </label>
  );
}

function Toggle({ on, onChange }) {
  return (
    <button onClick={() => onChange(!on)} style={{
      width: 42, height: 24, borderRadius: 12,
      background: on ? T.up : T.line, border: 'none',
      position: 'relative', cursor: 'pointer',
      transition: 'background .2s',
    }}>
      <span style={{
        position: 'absolute', top: 2, left: on ? 20 : 2,
        width: 20, height: 20, borderRadius: 10,
        background: T.fg, transition: 'left .2s',
      }} />
    </button>
  );
}

function StepHeader({ num, title, desc }) {
  return (
    <div style={{ marginBottom: 24 }}>
      <div style={{ fontSize: 11, color: T.hot, fontFamily: T.mono, letterSpacing: 1.5 }}>STEP {num}</div>
      <h2 style={{ fontSize: 24, fontWeight: 700, margin: '8px 0 6px' }}>{title}</h2>
      <p style={{ fontSize: 13, color: T.fgDim }}>{desc}</p>
    </div>
  );
}

Object.assign(window, { LoginPage, SignupPage, OnboardingPage, AuthShell, Field, Checkbox, Toggle });
