// PROVE — additional web app pages.
// Auth, onboarding, notifications, activity, coins, pro, settings,
// post flow, search, rooms, milestones, errors.

const { useState: useStateP, useEffect: useEffectP } = React;

// ────────────────────────────────────────────────────────────────────────
// AUTH — LOGIN
// ────────────────────────────────────────────────────────────────────────
function LoginPage({ width = 1280, height = 900 }) {
  const [email, setEmail] = useStateP('');
  const [pw, setPw] = useStateP('');
  return (
    <AuthShell width={width} height={height}>
      <div style={authCardStyle}>
        <AuthBrandHeader size={36} />
        <h1 style={{
          fontFamily: 'var(--display)', fontSize: 40, fontWeight: 800,
          letterSpacing: '-0.04em', margin: '4px 0 10px',
          textTransform: 'uppercase', color: '#fff', lineHeight: 0.94, textAlign: 'center',
        }}>Welcome <span style={{ color: 'var(--coral)', fontStyle: 'italic', fontWeight: 900 }}>back.</span></h1>
        <p style={{ ...authSubStyle, textAlign: 'center', marginBottom: 28 }}>Pick up where your streak left off.</p>

        <AppleButton full />

        <OrDivider />

        <FormField label="Email" type="email" value={email} onChange={setEmail} placeholder="you@email.com" />
        <FormField
          label="Password"
          type="password"
          value={pw}
          onChange={setPw}
          placeholder="••••••••"
          rightHint={<a style={authLinkStyle}>Forgot password?</a>}
        />

        <div style={{ marginTop: 8 }}>
          <CoralButton full size="lg">Sign in</CoralButton>
        </div>

        <div style={{ textAlign: 'center', fontSize: 13, color: 'var(--text-2)', marginTop: 22 }}>
          New here? <a style={{ ...authLinkStyle, marginLeft: 4 }}>Create account →</a>
        </div>
      </div>
    </AuthShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// AUTH — SIGNUP
// ────────────────────────────────────────────────────────────────────────
function SignupPage({ width = 1280, height = 900 }) {
  const [username, setUsername] = useStateP('maya.k');
  const taken = username === 'maya.k';
  const checkmark = !taken && username.length > 2 ? (
    <span style={{
      width: 16, height: 16, borderRadius: '50%',
      background: 'rgba(255,255,255,0.18)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      {Icon.check({ size: 11, stroke: '#fff', strokeWidth: 2.4 })}
    </span>
  ) : taken ? (
    <span style={{
      width: 8, height: 8, borderRadius: '50%', background: 'var(--coral)',
    }} />
  ) : null;

  return (
    <AuthShell width={width} height={height}>
      <div style={authCardStyle}>
        <AuthBrandHeader />
        <h1 style={{ ...authHeadlineStyle, marginTop: 6, textAlign: 'center' }}>Claim your handle.</h1>
        <p style={{ ...authSubStyle, textAlign: 'center' }}>Lock in founding member status.</p>

        <AppleButton full label="Sign up with Apple" />

        <OrDivider />

        <FormField label="Username" value={username} onChange={setUsername} placeholder="maya.k" suffix={checkmark}
          hint={taken ? <span style={{ color: 'var(--coral)' }}>Handle taken</span> : 'Available — locked in forever'} />
        <FormField label="Email" type="email" placeholder="you@email.com" />
        <FormField label="Password" type="password" placeholder="8+ characters" />

        <div style={{ marginTop: 14 }}>
          <CoralButton full size="lg">Create account</CoralButton>
        </div>

        <div style={{ textAlign: 'center', fontSize: 12, color: 'var(--text-3)', marginTop: 18 }}>
          By signing up you agree to PROVE’s Terms & Privacy.
        </div>
      </div>
    </AuthShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// AUTH — FORGOT / CHECK YOUR EMAIL
// ────────────────────────────────────────────────────────────────────────
function ForgotPasswordPage({ width = 1280, height = 900, state = 'form' }) {
  return (
    <AuthShell width={width} height={height}>
      <div style={{ ...authCardStyle, textAlign: state === 'sent' ? 'center' : 'left' }}>
        <AuthBrandHeader />
        {state === 'sent' ? (
          <>
            <div style={{
              width: 72, height: 72, borderRadius: '50%',
              background: 'rgba(255,97,85,0.1)',
              border: '1px solid rgba(255,97,85,0.4)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              margin: '0 auto 22px',
            }}>
              {Icon.envelope({ size: 30, stroke: 'var(--coral)' })}
            </div>
            <h1 style={authHeadlineStyle}>Check your email.</h1>
            <p style={{ ...authSubStyle, marginBottom: 28 }}>
              We sent a reset link to <span style={{ color: '#fff', fontFamily: 'var(--mono)' }}>you@email.com</span>. It expires in 30 minutes.
            </p>
            <GhostButton full>Back to login</GhostButton>
          </>
        ) : (
          <>
            <h1 style={{ ...authHeadlineStyle, fontSize: 28 }}>Forgot password.</h1>
            <p style={authSubStyle}>Enter your email and we’ll send a reset link.</p>
            <FormField label="Email" type="email" placeholder="you@email.com" />
            <div style={{ marginTop: 8 }}>
              <CoralButton full size="lg">Send reset link</CoralButton>
            </div>
          </>
        )}
      </div>
    </AuthShell>
  );
}

const authCardStyle = {
  width: 440,
  background: 'linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02))',
  border: '1px solid rgba(255,255,255,0.12)',
  borderRadius: 'var(--radius-modal)',
  padding: 40,
  boxShadow: '0 40px 80px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.04)',
  position: 'relative',
  zIndex: 2,
};
const authHeadlineStyle = {
  fontFamily: 'var(--display)', fontSize: 30, fontWeight: 700,
  letterSpacing: '-0.03em', margin: '20px 0 8px',
  textTransform: 'uppercase', color: '#fff', lineHeight: 1.05,
};
const authSubStyle = {
  fontSize: 14, color: 'var(--text-2)',
  margin: '0 0 24px', lineHeight: 1.5,
};
const dividerStyle = {
  display: 'flex', alignItems: 'center', gap: 12, color: 'var(--text-3)',
  fontSize: 11, fontFamily: 'var(--mono)', letterSpacing: 0.1 + 'em',
  textTransform: 'uppercase', margin: '18px 0',
  textAlign: 'center',
};
const authLinkStyle = {
  color: 'var(--coral)', fontSize: 12, fontWeight: 600,
  textDecoration: 'none', cursor: 'pointer',
};

function AuthBrandHeader({ size = 32 }) {
  return (
    <div style={{ textAlign: 'center', marginBottom: 28 }}>
      <div style={{ display: 'flex', justifyContent: 'center' }}>
        <ProveLogo size={size} color="#fff" />
      </div>
      <p style={{
        fontSize: 13, color: 'rgba(255,255,255,0.5)',
        margin: '12px 0 0', fontFamily: 'var(--mono)',
        letterSpacing: 0.02 + 'em',
      }}>“Daily proof or it didn’t happen.”</p>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// ONBOARDING — HABIT PICKER
// ────────────────────────────────────────────────────────────────────────
function OnboardingHabitPage({ width = 1280, height = 900 }) {
  const [picked, setPicked] = useStateP('lifting');
  const tiles = [
    { id: 'lifting',  emoji: '🏋️',  label: 'Lifting' },
    { id: 'running',  emoji: '🏃',  label: 'Running' },
    { id: 'reading',  emoji: '📚',  label: 'Reading' },
    { id: 'meditate', emoji: '🧘',  label: 'Meditation' },
    { id: 'cooking',  emoji: '🍳',  label: 'Cooking' },
    { id: 'coding',   emoji: '💻',  label: 'Coding' },
    { id: 'writing',  emoji: '✍️',  label: 'Writing' },
    { id: 'cold',     emoji: '🧊',  label: 'Cold plunge' },
  ];

  return (
    <AuthShell width={width} height={height}>
      <div style={{ width: 760, paddingTop: 40 }}>
        <div style={{ textAlign: 'center', marginBottom: 8 }}>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text-3)', letterSpacing: 0.12 + 'em', textTransform: 'uppercase' }}>
            Step 01 / 02
          </span>
        </div>
        <h1 style={{
          fontFamily: 'var(--display)', fontSize: 56, fontWeight: 900,
          letterSpacing: '-0.04em', textAlign: 'center', margin: '4px 0 12px',
          textTransform: 'uppercase', color: '#fff',
        }}>What are you proving?</h1>
        <p style={{ textAlign: 'center', color: 'var(--text-2)', fontSize: 15, margin: '0 0 36px' }}>
          One habit at a time. You can change it later — but your streak resets.
        </p>

        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12,
          marginBottom: 36,
        }}>
          {tiles.map((t) => (
            <button key={t.id} onClick={() => setPicked(t.id)}
              style={{
                padding: '22px 14px',
                background: picked === t.id ? 'rgba(255,97,85,0.08)' : 'var(--surface)',
                border: `1.5px solid ${picked === t.id ? 'var(--coral)' : 'var(--border)'}`,
                borderRadius: 'var(--radius-card)',
                cursor: 'pointer', fontFamily: 'inherit',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12,
                transition: 'all 0.12s',
              }}>
              <span style={{ fontSize: 36, lineHeight: 1 }}>{t.emoji}</span>
              <span style={{
                fontSize: 13, fontWeight: 600,
                color: picked === t.id ? 'var(--coral)' : '#fff',
                letterSpacing: 0.02 + 'em', textTransform: 'uppercase',
              }}>{t.label}</span>
            </button>
          ))}
        </div>

        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16 }}>
          <GhostButton onClick={() => history.back()}>Back</GhostButton>
          <CoralButton size="lg" icon="chevronR" onClick={() => (window.location.hash = '/onboarding/stake')}>Continue</CoralButton>
        </div>
      </div>
    </AuthShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// ONBOARDING — OPENING STAKE
// ────────────────────────────────────────────────────────────────────────
function OnboardingStakePage({ width = 1280, height = 900 }) {
  const [amount, setAmount] = useStateP(50);
  const presets = [10, 25, 50, 100];
  return (
    <AuthShell width={width} height={height}>
      <div style={{ width: 560, paddingTop: 40, textAlign: 'center' }}>
        <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text-3)', letterSpacing: 0.12 + 'em', textTransform: 'uppercase' }}>
          Step 02 / 02
        </span>
        <h1 style={{
          fontFamily: 'var(--display)', fontSize: 48, fontWeight: 900,
          letterSpacing: '-0.04em', margin: '4px 0 14px',
          textTransform: 'uppercase', color: '#fff', lineHeight: 1.02,
        }}>Set your opening stake.</h1>
        <p style={{ color: 'var(--text-2)', fontSize: 16, margin: '0 0 36px', lineHeight: 1.5 }}>
          This is how many coins ride on your first proof.<br/>
          Free coins to start — you can’t buy more.
        </p>

        {/* Big amount display */}
        <div style={{
          padding: '36px 0', background: 'var(--surface)',
          border: '1px solid var(--border)',
          borderRadius: 'var(--radius-card)',
          marginBottom: 18,
        }}>
          <MonoNum size={80} weight={700} color="var(--coral)" style={{ letterSpacing: '-0.04em' }}>{amount}</MonoNum>
          <div style={{ fontSize: 12, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: 0.12 + 'em', marginTop: -4 }}>coins on the line</div>
        </div>

        <div style={{ display: 'flex', gap: 8, marginBottom: 14 }}>
          {presets.map((p) => (
            <button key={p} onClick={() => setAmount(p)}
              style={{
                flex: 1, padding: '12px 0',
                background: amount === p ? 'var(--coral)' : 'var(--surface)',
                color: amount === p ? '#0D0D0D' : '#fff',
                border: amount === p ? '1px solid var(--coral)' : '1px solid var(--border)',
                borderRadius: 999,
                fontFamily: 'var(--mono)', fontSize: 14, fontWeight: 700,
                cursor: 'pointer',
              }}>{p}</button>
          ))}
        </div>

        <input type="range" min={5} max={200} step={5} value={amount}
          onChange={(e) => setAmount(parseInt(e.target.value, 10))}
          style={{
            width: '100%', accentColor: 'var(--coral)', marginBottom: 28,
          }} />

        <div style={{ display: 'flex', gap: 10 }}>
          <GhostButton full onClick={() => history.back()}>Back</GhostButton>
          <CoralButton full size="lg" onClick={() => (window.location.hash = '/feed')}>Start proving →</CoralButton>
        </div>
      </div>
    </AuthShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// NOTIFICATIONS PAGE
// ────────────────────────────────────────────────────────────────────────
function NotificationsPage({ width = 1280, height = 1100 }) {
  const D = window.PROVE_DATA;
  const items = [
    { kind: 'back',     unread: true,  user: 'devon.r',  text: 'backed your proof', meta: '+50 coins', t: '3m', icon: 'coin', accent: 'coral' },
    { kind: 'milestone',unread: true,  text: 'Your streak hit day 47!', meta: '+50 coins bonus', t: '6m', icon: 'flame', accent: 'celebration' },
    { kind: 'window',   unread: true,  text: 'PROVE Window closes in 30 minutes', meta: 'post now', t: '12m', icon: 'bell', accent: 'urgent' },
    { kind: 'doubt',    unread: true,  user: 'jordan.b', text: 'doubted your proof', meta: '-10 coins riding', t: '34m', icon: 'coin' },
    { kind: 'follow',   unread: false, user: 'sasha.m',  text: 'started following you', t: '1h', icon: 'user' },
    { kind: 'comment',  unread: false, user: 'priya_s',  text: 'commented:', meta: '"PR + bad sleep + posting it? respect."', t: '2h', icon: 'chat' },
    { kind: 'earn',     unread: false, text: 'You earned 50 coins from yesterday’s stake', t: '5h', icon: 'coin', accent: 'celebration' },
    { kind: 'shield',   unread: false, text: 'Streak Shield saved your streak last week', t: '2d', icon: 'shield' },
    { kind: 'window',   unread: false, text: 'PROVE Window opens in 1 hour', t: '2d', icon: 'bell' },
    { kind: 'back',     unread: false, user: 'tomas.lin', text: 'backed your proof', meta: '+25 coins', t: '3d', icon: 'coin' },
  ];

  return (
    <PageShell width={width} height={height} active="notifications">
      <div style={{ padding: 32 }}>
        <PageHeader
          section="§ 03 / inbox"
          title="Notifications"
          sub="4 unread · only PROVE-related notifications. No noise."
          actions={<GhostButton size="sm" onClick={() => alert('All notifications marked as read.')}>Mark all read</GhostButton>}
        />

        <div style={{
          background: 'linear-gradient(180deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.02) 100%)',
          border: '1px solid var(--border)',
          borderRadius: 'var(--radius-card)',
          overflow: 'hidden',
        }}>
          {items.map((it, i) => <NotifRow key={i} item={it} />)}
        </div>
      </div>
    </PageShell>
  );
}

function NotifRow({ item }) {
  const D = window.PROVE_DATA;
  const u = item.user ? D.byHandle[item.user] : null;
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 14,
      minHeight: 64, padding: '0 20px',
      background: item.unread ? 'rgba(255,97,85,0.04)' : 'transparent',
      borderLeft: item.unread ? '2px solid var(--coral)' : '2px solid transparent',
      borderTop: '1px solid var(--border)',
      transition: 'background 0.12s',
    }}>
      {/* 48px icon container */}
      <div style={{
        width: 48, height: 48, flexShrink: 0,
      }}>
        {u ? (
          <Avatar user={u} size={48} />
        ) : (
          <div style={{
            width: 40, height: 40, borderRadius: '50%',
            background: 'rgba(255,255,255,0.06)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            margin: 4,
          }}>
            {Icon[item.icon] && Icon[item.icon]({ size: 18, stroke: item.accent === 'celebration' || item.accent === 'urgent' || item.accent === 'coral' ? 'var(--coral)' : 'var(--text-2)' })}
          </div>
        )}
      </div>
      {/* text block */}
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14, color: '#fff', lineHeight: 1.5 }}>
          {u && <span style={{ fontWeight: 700 }}>{u.handle} </span>}
          {item.text}
          {item.meta && <span style={{
            color: item.accent === 'celebration' || item.accent === 'coral' ? 'var(--coral)' : 'var(--text-2)',
            marginLeft: 6,
            fontFamily: item.meta.startsWith('+') || item.meta.startsWith('-') ? 'var(--mono)' : 'inherit',
            fontWeight: 600,
          }}>{item.meta}</span>}
        </div>
      </div>
      <MonoNum size={12} color="var(--text-3)" weight={500}>{item.t}</MonoNum>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// ACTIVITY PAGE
// ────────────────────────────────────────────────────────────────────────
function ActivityPage({ width = 1280, height = 1100 }) {
  const [tab, setTab] = useStateP('all');
  const D = window.PROVE_DATA;
  const tabs = [
    { id: 'all', label: 'All' },
    { id: 'stakes', label: 'Stakes' },
    { id: 'proofs', label: 'Proofs' },
    { id: 'followers', label: 'Followers' },
  ];
  const rows = [
    { type: 'milestone', title: 'Day 30 streak unlocked', meta: '+200 coins', t: '1d', highlight: true },
    { type: 'stake', side: 'back', target: 'priya_s', proof: 'reading day 92', amount: 50, result: 'won', payout: 75, t: '1d' },
    { type: 'proof', user: 'maya.k', habit: 'lifting', day: 47, status: 'verified', t: '2d' },
    { type: 'stake', side: 'doubt', target: 'jordan.b', proof: 'meditate day 3', amount: 25, result: 'won', payout: 41, t: '2d' },
    { type: 'follower', target: 'sasha.m', action: 'followed you', t: '3d' },
    { type: 'stake', side: 'back', target: 'devon.r', proof: 'running day 12', amount: 50, result: 'lost', payout: 0, t: '3d' },
    { type: 'proof', user: 'maya.k', habit: 'lifting', day: 46, status: 'verified', t: '3d' },
    { type: 'milestone', title: 'Day 7 streak unlocked', meta: '+50 coins', t: '40d', highlight: true },
  ];

  return (
    <PageShell width={width} height={height} active="activity">
      <div style={{ padding: 32 }}>
        <PageHeader
          section="§ 05 / log"
          title="Activity"
          sub="Everything you and your stakes are up to."
          actions={<FilterTabs tabs={tabs} value={tab} onChange={setTab} />}
        />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {rows.map((r, i) => <ActivityRow key={i} row={r} />)}
        </div>
      </div>
    </PageShell>
  );
}

function ActivityRow({ row }) {
  const D = window.PROVE_DATA;

  if (row.type === 'milestone') {
    return (
      <div style={{
        padding: '16px 20px',
        background: 'rgba(255,97,85,0.06)',
        border: '1px solid rgba(255,97,85,0.25)',
        borderRadius: 'var(--radius-card)',
        display: 'flex', alignItems: 'center', gap: 14,
      }}>
        <div style={{ width: 36, height: 36, borderRadius: '50%', background: 'rgba(255,97,85,0.15)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          {Icon.flame({ size: 18, stroke: 'var(--coral)' })}
        </div>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 14, color: '#fff', fontWeight: 600 }}>{row.title}</div>
        </div>
        <MonoNum size={16} weight={700} color="var(--coral)">{row.meta}</MonoNum>
        <MonoNum size={11} color="var(--text-3)">{row.t}</MonoNum>
      </div>
    );
  }

  if (row.type === 'stake') {
    const isBack = row.side === 'back';
    const won = row.result === 'won';
    const u = D.byHandle[row.target];
    return (
      <div style={{
        display: 'grid', gridTemplateColumns: '40px 1fr 90px 100px 70px',
        gap: 14, alignItems: 'center',
        padding: '12px 18px',
        background: 'var(--surface)',
        border: '1px solid var(--border)',
        borderRadius: 'var(--radius-card)',
      }}>
        <div style={{ width: 36, height: 36, borderRadius: '50%', background: 'var(--surface)', border: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          {Icon.coin({ size: 14, stroke: isBack ? 'var(--coral)' : 'var(--text-2)' })}
        </div>
        <div>
          <div style={{ fontSize: 13, color: '#fff' }}>
            <span style={{ color: isBack ? 'var(--coral)' : 'var(--text-2)', fontWeight: 700, textTransform: 'uppercase', fontSize: 11, letterSpacing: 0.06 + 'em' }}>{isBack ? 'Backed' : 'Doubted'}</span>
            {' '}
            <span style={{ fontWeight: 600 }}>{u.handle}</span>
            <span style={{ color: 'var(--text-2)' }}> · {row.proof}</span>
          </div>
        </div>
        <MonoNum size={13} color="var(--text-2)" style={{ textAlign: 'right' }}>{row.amount} coins</MonoNum>
        <div style={{ textAlign: 'right' }}>
          <span style={{
            fontSize: 10, fontWeight: 700, letterSpacing: 0.08 + 'em', textTransform: 'uppercase',
            color: won ? 'var(--coral)' : 'var(--text-3)',
          }}>{won ? 'Won' : 'Lost'}</span>
          <div>
            <MonoNum size={13} weight={600} color={won ? 'var(--coral)' : 'var(--text-3)'}>
              {won ? `+${row.payout}` : `-${row.amount}`}
            </MonoNum>
          </div>
        </div>
        <MonoNum size={11} color="var(--text-3)" style={{ textAlign: 'right' }}>{row.t}</MonoNum>
      </div>
    );
  }

  if (row.type === 'proof') {
    const h = D.habits[row.habit];
    return (
      <div style={{
        display: 'grid', gridTemplateColumns: '48px 1fr auto',
        gap: 14, alignItems: 'center',
        padding: '10px 18px 10px 10px',
        background: 'var(--surface)',
        border: '1px solid var(--border)',
        borderRadius: 'var(--radius-card)',
      }}>
        <div style={{ width: 48, aspectRatio: '1/1', borderRadius: 6, overflow: 'hidden', position: 'relative' }}>
          <BlurTile hue={h.hue} seed={row.day} aspect="1/1" />
        </div>
        <div>
          <div style={{ fontSize: 13, color: '#fff', display: 'flex', gap: 8, alignItems: 'center' }}>
            <span style={{ fontWeight: 600 }}>Posted proof · day {row.day}</span>
            <HabitPill habit={h} size="xs" />
          </div>
          <div style={{ fontSize: 11, color: 'var(--text-2)', marginTop: 4, display: 'flex', alignItems: 'center', gap: 6 }}>
            {Icon.check({ size: 11, stroke: 'var(--coral)', strokeWidth: 2.2 })}
            <span>Verified · streak alive</span>
          </div>
        </div>
        <MonoNum size={11} color="var(--text-3)">{row.t}</MonoNum>
      </div>
    );
  }

  if (row.type === 'follower') {
    const u = D.byHandle[row.target];
    return (
      <div style={{
        display: 'grid', gridTemplateColumns: '40px 1fr auto auto',
        gap: 14, alignItems: 'center',
        padding: '12px 18px',
        background: 'var(--surface)',
        border: '1px solid var(--border)',
        borderRadius: 'var(--radius-card)',
      }}>
        <Avatar user={u} size={36} />
        <div style={{ fontSize: 13, color: '#fff' }}>
          <span style={{ fontWeight: 600 }}>{u.handle}</span> {row.action}
        </div>
        <GhostButton size="md" onClick={() => alert('Followed.')}>Follow back</GhostButton>
        <MonoNum size={11} color="var(--text-3)">{row.t}</MonoNum>
      </div>
    );
  }
  return null;
}

// ────────────────────────────────────────────────────────────────────────
// COINS PAGE
// ────────────────────────────────────────────────────────────────────────
function CoinsPage({ width = 1280, height = 1300 }) {
  const tx = [
    { label: 'Stake won · backed priya_s',     amount: +75,  t: '1d' },
    { label: 'Proof verified · day 47',         amount: +10,  t: '1d' },
    { label: 'Streak milestone · day 30',       amount: +200, t: '17d', highlight: true },
    { label: 'Stake lost · backed devon.r',     amount: -50,  t: '3d' },
    { label: 'Proof verified · day 46',         amount: +10,  t: '3d' },
    { label: 'Stake won · doubted jordan.b',    amount: +41,  t: '4d' },
    { label: 'Referred kev.do posted proof',   amount: +25,  t: '6d' },
    { label: 'Streak milestone · day 7',        amount: +50,  t: '40d', highlight: true },
    { label: 'Opening coin allotment',          amount: +100, t: '47d' },
  ];

  return (
    <PageShell width={width} height={height} active="coins">
      <div style={{ padding: '32px' }}>
        <PageHeader
          section="§ 06 / economy"
          title="Coins"
          sub="Earn coins by proving + winning stakes. Spend them to back others."
        />

        {/* Hero balance — centered, glowing */}
        <div style={{
          background: 'linear-gradient(180deg, rgba(255,97,85,0.10), rgba(255,97,85,0.02))',
          border: '1px solid rgba(255,97,85,0.25)',
          borderRadius: 'var(--radius-card)',
          padding: '52px 32px 44px',
          marginBottom: 32,
          display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center',
          position: 'relative', overflow: 'hidden',
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 20, marginBottom: 8 }}>
            <div style={{
              width: 56, height: 56, borderRadius: '50%',
              background: 'var(--coral)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              filter: 'drop-shadow(0 0 20px rgba(255,97,85,0.5))',
            }}>
              {Icon.coin({ size: 30, stroke: '#0D0D0D', strokeWidth: 2 })}
            </div>
            <MonoNum size={72} weight={700} color="var(--coral)" style={{
              letterSpacing: '-0.04em', lineHeight: 1,
              filter: 'drop-shadow(0 0 20px rgba(255,97,85,0.3))',
            }}>2,840</MonoNum>
          </div>
          <div style={{ fontSize: 14, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: 0.12 + 'em', marginTop: 4, fontFamily: 'var(--mono)' }}>
            coins
          </div>
          <div style={{ display: 'flex', gap: 32, marginTop: 28, paddingTop: 22, borderTop: '1px solid rgba(255,255,255,0.06)' }}>
            <div>
              <MonoNum size={18} weight={700} color="var(--coral)">+450</MonoNum>
              <span style={{ fontSize: 12, color: 'var(--text-2)', marginLeft: 8 }}>earned this week</span>
            </div>
            <div>
              <MonoNum size={18} weight={700} color="var(--text-2)">−180</MonoNum>
              <span style={{ fontSize: 12, color: 'var(--text-2)', marginLeft: 8 }}>staked this week</span>
            </div>
          </div>
        </div>

        {/* Earn methods */}
        <h2 style={subTitleStyle}>Ways to earn</h2>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginBottom: 32 }}>
          {[
            { icon: 'camera', title: 'Post proof daily', body: 'Verified by AI + community', amount: '+10' },
            { icon: 'coin',   title: 'Win a Back stake', body: 'Payout multiplied by odds', amount: '×N' },
            { icon: 'coin',   title: 'Win a Doubt stake', body: 'Payout multiplied by odds', amount: '×N' },
            { icon: 'flame',  title: 'Day 7 milestone', body: 'First small streak bonus', amount: '+50' },
            { icon: 'flame',  title: 'Day 30 milestone', body: 'You’ve outlasted most.', amount: '+200' },
            { icon: 'user',   title: 'Refer a friend', body: 'When they post their first proof', amount: '+25' },
          ].map((m) => (
            <div key={m.title} style={{
              background: 'var(--surface)',
              border: '1px solid var(--border)',
              borderRadius: 'var(--radius-card)',
              padding: 18,
              display: 'flex', alignItems: 'flex-start', gap: 12,
            }}>
              <div style={{ width: 36, height: 36, borderRadius: '50%', background: 'rgba(255,97,85,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                {Icon[m.icon]({ size: 16, stroke: 'var(--coral)' })}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 600, color: '#fff', marginBottom: 4 }}>{m.title}</div>
                <div style={{ fontSize: 11, color: 'var(--text-2)', lineHeight: 1.4, marginBottom: 6 }}>{m.body}</div>
                <MonoNum size={13} weight={700} color="var(--coral)">{m.amount} coins</MonoNum>
              </div>
            </div>
          ))}
        </div>

        {/* Transaction history */}
        <h2 style={subTitleStyle}>Recent activity</h2>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          {tx.map((t, i) => (
            <div key={i} style={{
              display: 'grid', gridTemplateColumns: '32px 1fr auto auto',
              gap: 14, alignItems: 'center',
              padding: '14px 18px',
              borderBottom: '1px solid var(--border)',
              background: t.highlight ? 'rgba(255,97,85,0.04)' : 'transparent',
            }}>
              <div style={{
                width: 28, height: 28, borderRadius: '50%',
                background: t.amount > 0 ? 'rgba(255,97,85,0.1)' : 'rgba(255,255,255,0.05)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: 'var(--mono)', fontSize: 14, fontWeight: 700,
                color: t.amount > 0 ? 'var(--coral)' : 'var(--text-3)',
              }}>{t.amount > 0 ? '+' : '−'}</div>
              <div style={{ fontSize: 13, color: '#fff' }}>{t.label}</div>
              <MonoNum size={14} weight={700} color={t.amount > 0 ? 'var(--coral)' : 'var(--text-3)'}>
                {t.amount > 0 ? `+${t.amount}` : t.amount}
              </MonoNum>
              <MonoNum size={11} color="var(--text-3)">{t.t}</MonoNum>
            </div>
          ))}
        </div>
      </div>
    </PageShell>
  );
}
const subTitleStyle = {
  fontFamily: 'var(--display)', fontSize: 18, fontWeight: 700,
  letterSpacing: '-0.02em', textTransform: 'uppercase',
  color: '#fff', margin: '0 0 14px',
};

// ────────────────────────────────────────────────────────────────────────
// PRO PAGE
// ────────────────────────────────────────────────────────────────────────
function ProPage({ width = 1280, height = 1100 }) {
  const features = [
    { icon: 'shield', title: 'Streak Shield', body: 'One free miss per month. Streak lives.' },
    { icon: 'coin',   title: 'Enhanced Staking', body: 'Stake up to 500 coins per proof.' },
    { icon: 'star',   title: 'Pro Badge', body: 'Coral REP badge. Everyone sees it.' },
  ];

  return (
    <PageShell width={width} height={height} active="profile">
      <div style={{ height: '100%', overflow: 'auto' }}>
        <div style={{ maxWidth: 900, margin: '0 auto', padding: '60px 32px' }}>

          <div style={{ textAlign: 'center', marginBottom: 36 }}>
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 6,
              padding: '4px 12px',
              background: 'rgba(255,97,85,0.1)',
              border: '1px solid rgba(255,97,85,0.4)',
              borderRadius: 999,
              fontSize: 10, fontWeight: 700,
              letterSpacing: 0.12 + 'em', textTransform: 'uppercase',
              color: 'var(--coral)', fontFamily: 'var(--mono)',
              marginBottom: 18,
            }}>Founding member · locked in forever</span>
            <h1 style={{
              fontFamily: 'var(--display)', fontSize: 96, fontWeight: 900,
              letterSpacing: '-0.05em', margin: 0,
              textTransform: 'uppercase', color: '#fff', lineHeight: 0.92,
            }}>PROVE <span style={{ color: 'var(--coral)' }}>PRO</span></h1>
            <p style={{ fontSize: 17, color: 'var(--text-2)', maxWidth: 480, margin: '20px auto 0', lineHeight: 1.5 }}>
              Better streak insurance. Bigger stakes. A badge that says you mean it.
            </p>
          </div>

          {/* Price block */}
          <div style={{
            background: 'var(--surface)',
            border: '1px solid var(--border)',
            borderRadius: 'var(--radius-card)',
            padding: 28,
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            marginBottom: 28,
          }}>
            <div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
                <MonoNum size={56} weight={700} color="var(--coral)" style={{ letterSpacing: '-0.04em', lineHeight: 1 }}>$2.99</MonoNum>
                <span style={{ fontSize: 14, color: 'var(--text-2)', textDecoration: 'line-through', fontFamily: 'var(--mono)' }}>$4.99</span>
                <span style={{ fontSize: 14, color: 'var(--text-2)' }}>/ month</span>
              </div>
              <div style={{ fontSize: 12, color: 'var(--text-3)', marginTop: 6, fontFamily: 'var(--mono)' }}>
                Cancel anytime · billed monthly · no hidden costs
              </div>
            </div>
            <CoralButton size="lg" icon="apple" onClick={() => alert('Open the iOS app to manage your PROVE Pro subscription.')}>Upgrade on iOS</CoralButton>
          </div>

          {/* Features */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14 }}>
            {features.map((f) => (
              <div key={f.title} style={{
                background: 'var(--surface)',
                border: '1px solid var(--border)',
                borderRadius: 'var(--radius-card)',
                padding: 24,
                display: 'flex', flexDirection: 'column', gap: 14,
              }}>
                <div style={{
                  width: 44, height: 44, borderRadius: 10,
                  background: 'rgba(255,97,85,0.1)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>
                  {Icon[f.icon]({ size: 20, stroke: 'var(--coral)' })}
                </div>
                <div>
                  <h3 style={{
                    fontFamily: 'var(--display)', fontSize: 18, fontWeight: 700,
                    letterSpacing: '-0.02em', textTransform: 'uppercase',
                    color: '#fff', margin: '0 0 6px',
                  }}>{f.title}</h3>
                  <p style={{ fontSize: 14, color: 'var(--text-2)', margin: 0, lineHeight: 1.5 }}>{f.body}</p>
                </div>
              </div>
            ))}
          </div>

          <div style={{ textAlign: 'center', fontSize: 12, color: 'var(--text-3)', marginTop: 32, fontFamily: 'var(--mono)' }}>
            Web cannot process payment. Manage subscription in the app.
          </div>
        </div>
      </div>
    </PageShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// STREAK SHIELD PAYWALL (contextual)
// ────────────────────────────────────────────────────────────────────────
function StreakShieldPage({ width = 1280, height = 900 }) {
  return (
    <PageShell width={width} height={height} active="feed" windowState="closing">
      <div style={{ height: '100%', overflow: 'hidden', position: 'relative' }}>
        {/* dimmed feed behind */}
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(6px)', zIndex: 5 }} />
        {/* Faint feed cards behind */}
        <div style={{ padding: '24px 28px', filter: 'blur(2px)', opacity: 0.4 }}>
          <h1 style={pageTitleStyle}>The Feed</h1>
        </div>

        <div style={{
          position: 'absolute', inset: 0, zIndex: 10,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <div style={{
            width: 520,
            background: '#161616',
            border: '1px solid var(--border)',
            borderRadius: 'var(--radius-modal)',
            padding: '32px 28px',
            textAlign: 'center',
          }}>
            <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 14 }}>
              <div style={{ width: 32, height: 4, borderRadius: 999, background: 'var(--coral)' }} />
            </div>

            <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 18 }}>
              <StreakRing day={47} target={48} size={140} stroke={9} animate={false} />
            </div>

            <h2 style={{
              fontFamily: 'var(--display)', fontSize: 32, fontWeight: 800,
              letterSpacing: '-0.03em', margin: '0 0 12px',
              textTransform: 'uppercase', color: '#fff',
            }}>Your 47-day streak<br/>is on the line.</h2>
            <p style={{ fontSize: 14, color: 'var(--text-2)', margin: '0 0 22px', lineHeight: 1.5 }}>
              Window closes in <MonoNum size={14} color="var(--coral)" weight={700}>00:34:12</MonoNum>.
              Activate Streak Shield to keep your streak alive even if you miss tonight.
            </p>

            <div style={{
              background: 'rgba(255,97,85,0.06)',
              border: '1px solid rgba(255,97,85,0.25)',
              borderRadius: 10,
              padding: '14px 18px',
              display: 'flex', alignItems: 'center', gap: 12,
              marginBottom: 18,
            }}>
              {Icon.shield({ size: 22, stroke: 'var(--coral)' })}
              <div style={{ textAlign: 'left', flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 700, color: '#fff' }}>Streak Shield</div>
                <div style={{ fontSize: 12, color: 'var(--text-2)' }}>One free miss per month. Available with PROVE PRO.</div>
              </div>
            </div>

            <CoralButton full size="lg" icon="apple" onClick={() => alert('Open the iOS app to use a Streak Shield.')}>Protect my streak → Open app</CoralButton>
            <div style={{ marginTop: 10, fontSize: 11, color: 'var(--text-3)' }}>
              Or post proof inside the next 34 minutes — no Shield needed.
            </div>
          </div>
        </div>
      </div>
    </PageShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// SETTINGS
// ────────────────────────────────────────────────────────────────────────
function SettingsPage({ width = 1280, height = 1100 }) {
  const sections = [
    { id: 'account',       label: 'Account',           sub: 'Email, password, connected accounts',  icon: 'user' },
    { id: 'notifications', label: 'Notifications',     sub: 'Window warnings, social pings',        icon: 'bell' },
    { id: 'privacy',       label: 'Privacy',           sub: 'Public profile, staking permissions',  icon: 'lock' },
    { id: 'subscription',  label: 'Subscription',      sub: 'PROVE PRO membership · App store',     icon: 'star' },
    { id: 'help',          label: 'Help & Support',    sub: 'FAQs, contact, status',                icon: 'chat' },
    { id: 'about',         label: 'About PROVE',       sub: 'Version, terms, manifesto',            icon: 'flame' },
  ];

  return (
    <PageShell width={width} height={height} active="profile">
      <div style={{ padding: 32 }}>
        <div style={{ maxWidth: 760, margin: '0 auto' }}>
          <span style={sectionLabelStyle}>§ 09 / account</span>
          <h1 style={{ ...pageTitleStyle, marginTop: 6 }}>Settings</h1>
          <p style={{ fontSize: 14, color: 'var(--text-2)', margin: '8px 0 28px', lineHeight: 1.6 }}>
            Manage your PROVE account.
          </p>

          <div style={{
            background: 'var(--surface)',
            border: '1px solid var(--border)',
            borderRadius: 'var(--radius-card)',
            overflow: 'hidden',
            marginBottom: 32,
          }}>
            {sections.map((s, i) => (
              <button key={s.id}
                onClick={() => {
                  if (s.id === 'notifications') window.location.hash = '/settings/notifications';
                  else if (s.id === 'subscription') window.location.hash = '/pro';
                  else if (s.id === 'help') window.location.href = 'mailto:support@tryproveit.app';
                  else alert(s.label + ' — coming soon on web. Use the iOS app for now.');
                }}
                style={{
                display: 'flex', alignItems: 'center', gap: 16,
                minHeight: 64, padding: '0 20px',
                background: 'transparent',
                border: 'none',
                borderTop: i > 0 ? '1px solid var(--border)' : 'none',
                cursor: 'pointer', fontFamily: 'inherit',
                textAlign: 'left', width: '100%',
                transition: 'background 0.12s',
              }}
              onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(255,255,255,0.03)'}
              onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
              >
                <div style={{ width: 40, height: 40, borderRadius: '50%', background: 'rgba(255,97,85,0.08)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                  {Icon[s.icon]({ size: 18, stroke: 'var(--coral)' })}
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 15, fontWeight: 600, color: '#fff' }}>{s.label}</div>
                  <div style={{ fontSize: 12, color: 'var(--text-2)', marginTop: 3 }}>{s.sub}</div>
                </div>
                {Icon.chevronR({ size: 16, stroke: 'var(--text-3)' })}
              </button>
            ))}
          </div>

          <div style={{
            border: '1px solid rgba(255,97,85,0.2)',
            borderRadius: 'var(--radius-card)',
            padding: 20,
          }}>
            <div style={{ fontSize: 11, color: 'var(--coral)', letterSpacing: 0.12 + 'em', textTransform: 'uppercase', fontWeight: 700, marginBottom: 14, fontFamily: 'var(--mono)' }}>
              Danger zone
            </div>
            <div style={{ display: 'flex', gap: 10 }}>
              <GhostButton danger onClick={async () => {
                try { await window.proveSupabase.auth.signOut(); } catch (e) {}
                window.location.hash = '/login';
              }}>Sign out</GhostButton>
              <GhostButton danger onClick={() => {
                if (window.confirm('Delete account? This cannot be undone.')) {
                  window.location.href = 'mailto:support@tryproveit.app?subject=Account%20deletion%20request';
                }
              }}>Delete account</GhostButton>
            </div>
          </div>
        </div>
      </div>
    </PageShell>
  );
}

// SETTINGS — notifications sub-page (sample detail page)
function SettingsNotificationsPage({ width = 1280, height = 1000 }) {
  const toggles = [
    { id: 'open',       label: 'PROVE Window opens',    sub: '1 hour warning before 6 AM', def: true },
    { id: 'close',      label: 'PROVE Window closes',   sub: '30 minute warning before 11:59 PM', def: true },
    { id: 'backed',     label: 'Someone backed your proof', sub: 'Every new Back stake', def: true },
    { id: 'doubted',    label: 'Someone doubted your proof', sub: 'Every new Doubt stake', def: false },
    { id: 'follow',     label: 'New follower',           sub: 'When someone follows you', def: true },
    { id: 'milestone',  label: 'Streak milestone reached', sub: 'Day 7, 30, 100, 365…', def: true },
    { id: 'recap',      label: 'Weekly recap email',     sub: 'Sundays at 9 AM local', def: false },
  ];
  const [vals, setVals] = useStateP(Object.fromEntries(toggles.map((t) => [t.id, t.def])));

  return (
    <PageShell width={width} height={height} active="profile">
      <div style={{ padding: 32 }}>
        <div style={{ maxWidth: 760, margin: '0 auto' }}>
          <div style={{ fontSize: 12, color: 'var(--text-3)', fontFamily: 'var(--mono)', marginBottom: 12 }}>
            ← Settings / Notifications
          </div>
          <h1 style={pageTitleStyle}>Notification preferences</h1>
          <p style={{ fontSize: 14, color: 'var(--text-2)', margin: '8px 0 28px', lineHeight: 1.6 }}>
            We only ping you for things you actually want to know.
          </p>

          <div style={{
            background: 'var(--surface)',
            border: '1px solid var(--border)',
            borderRadius: 'var(--radius-card)',
            overflow: 'hidden',
          }}>
            {toggles.map((t, i) => (
              <div key={t.id} style={{
                display: 'flex', alignItems: 'center', gap: 16,
                minHeight: 64, padding: '14px 20px',
                borderTop: i > 0 ? '1px solid var(--border)' : 'none',
              }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 600, color: '#fff' }}>{t.label}</div>
                  <div style={{ fontSize: 12, color: 'var(--text-2)', marginTop: 4 }}>{t.sub}</div>
                </div>
                <Toggle on={vals[t.id]} onChange={(v) => setVals((vs) => ({ ...vs, [t.id]: v }))} />
              </div>
            ))}
          </div>
        </div>
      </div>
    </PageShell>
  );
}

function Toggle({ on, onChange }) {
  return (
    <button onClick={() => onChange && onChange(!on)}
      style={{
        width: 44, height: 26,
        background: on ? 'var(--coral)' : 'rgba(255,255,255,0.12)',
        border: 'none', borderRadius: 999,
        cursor: 'pointer', position: 'relative',
        transition: 'background 0.18s',
        padding: 0,
      }}>
      <div style={{
        position: 'absolute', top: 3, left: on ? 21 : 3,
        width: 20, height: 20, borderRadius: '50%',
        background: '#fff',
        transition: 'left 0.18s cubic-bezier(.2,.7,.3,1)',
        boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
      }} />
    </button>
  );
}

// ────────────────────────────────────────────────────────────────────────
// POST FLOW (Upload → Preview → Success → Closed)
// ────────────────────────────────────────────────────────────────────────
function PostFlowPage({ width = 1280, height = 900, step = 'upload' }) {
  return (
    <PageShell width={width} height={height} active="feed" windowState={step === 'closed' ? 'closed' : 'closing'}>
      <div style={{
        height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: 32,
      }}>
        {step === 'upload' && <PostUploadCard />}
        {step === 'preview' && <PostPreviewCard />}
        {step === 'success' && <PostSuccessCard />}
        {step === 'closed' && <PostClosedCard />}
      </div>
    </PageShell>
  );
}

function PostUploadCard() {
  const fileRef = React.useRef(null);
  const onPick = (e) => {
    const f = e.target.files?.[0];
    if (f) window.location.hash = '/post/preview';
  };
  return (
    <div style={{ width: 560, textAlign: 'center' }}>
      <input ref={fileRef} type="file" accept="video/*" style={{ display: 'none' }} onChange={onPick} />
      <div style={{ fontSize: 12, color: 'var(--text-3)', fontFamily: 'var(--mono)', marginBottom: 6 }}>
        Step 01 / 02
      </div>
      <h1 style={{
        fontFamily: 'var(--display)', fontSize: 40, fontWeight: 800,
        letterSpacing: '-0.03em', margin: '0 0 8px',
        textTransform: 'uppercase', color: '#fff', lineHeight: 1.02,
      }}>Post your proof.</h1>
      <p style={{ fontSize: 14, color: 'var(--text-2)', margin: '0 0 24px' }}>
        Inside the PROVE Window. Sixty seconds. Raw.
      </p>
      <div
        onClick={() => fileRef.current?.click()}
        style={{
        border: '2px dashed rgba(255,97,85,0.5)',
        borderRadius: 'var(--radius-card)',
        padding: '60px 20px',
        background: 'rgba(255,97,85,0.03)',
        cursor: 'pointer',
      }}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 18 }}>
          {Icon.cameraBig({ size: 48, stroke: 'var(--coral)' })}
        </div>
        <div style={{ fontSize: 18, fontWeight: 700, color: '#fff', marginBottom: 6 }}>
          Drop your proof video here
        </div>
        <div style={{ fontSize: 13, color: 'var(--text-2)' }}>
          or <a style={{ color: 'var(--coral)', fontWeight: 600, cursor: 'pointer' }}
            onClick={(e) => { e.stopPropagation(); fileRef.current?.click(); }}
          >browse files</a>
        </div>
        <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 18, fontFamily: 'var(--mono)' }}>
          MP4 or MOV · max 60 seconds · 200MB
        </div>
      </div>
      <div style={{ marginTop: 22 }}>
        <FormField label="Caption (optional)" placeholder="What you proved today…" />
      </div>
      <div style={{ marginTop: 16 }}>
        <CoralButton full size="lg" icon="upload" onClick={() => (window.location.hash = '/post/preview')}>Post proof</CoralButton>
      </div>
    </div>
  );
}

function PostPreviewCard() {
  const D = window.PROVE_DATA;
  return (
    <div style={{ width: 560 }}>
      <div style={{ textAlign: 'center', marginBottom: 14 }}>
        <div style={{ fontSize: 12, color: 'var(--text-3)', fontFamily: 'var(--mono)' }}>Step 02 / 02</div>
        <h1 style={{
          fontFamily: 'var(--display)', fontSize: 36, fontWeight: 800,
          letterSpacing: '-0.03em', margin: '6px 0 0',
          textTransform: 'uppercase', color: '#fff',
        }}>Confirm & post.</h1>
      </div>

      <div style={{
        position: 'relative', aspectRatio: '16/9',
        borderRadius: 'var(--radius-card)', overflow: 'hidden',
        marginBottom: 14, border: '1px solid var(--border)',
      }}>
        <BlurTile hue={18} seed={3} aspect="auto" style={{ position: 'absolute', inset: 0, aspectRatio: 'auto' }} />
        <PlayOverlay size={56} />
        <div style={{
          position: 'absolute', top: 12, left: 12,
          background: 'var(--coral)', color: '#0D0D0D',
          fontSize: 10, fontWeight: 800, padding: '5px 10px',
          letterSpacing: 0.12 + 'em', textTransform: 'uppercase',
          borderRadius: 4,
          display: 'inline-flex', alignItems: 'center', gap: 6,
        }}>
          {Icon.check({ size: 11, stroke: '#0D0D0D', strokeWidth: 2.4 })}
          Auto-verified
        </div>
        <div style={{
          position: 'absolute', top: 12, right: 12,
          fontFamily: 'var(--mono)', fontSize: 11, color: '#fff',
          background: 'rgba(0,0,0,0.7)', padding: '4px 10px', borderRadius: 999,
        }}>day 48</div>
      </div>

      <div style={{
        background: 'var(--surface)', border: '1px solid var(--border)',
        borderRadius: 'var(--radius-card)', padding: 16, marginBottom: 16,
      }}>
        <div style={{ fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.1 + 'em', marginBottom: 6 }}>Caption</div>
        <div style={{ fontSize: 14, color: '#fff' }}>Front squat PR. Sleep was trash.</div>
      </div>

      <div style={{ display: 'flex', gap: 10 }}>
        <GhostButton full onClick={() => (window.location.hash = '/post')}>Re-upload</GhostButton>
        <CoralButton full size="lg" icon="check" onClick={() => (window.location.hash = '/post/success')}>Confirm & post</CoralButton>
      </div>
    </div>
  );
}

function PostSuccessCard() {
  return (
    <div style={{
      width: 480, textAlign: 'center', position: 'relative',
    }}>
      {/* confetti dots */}
      <div style={{ position: 'absolute', inset: -100, pointerEvents: 'none' }}>
        {Array.from({ length: 28 }).map((_, i) => {
          const a = (i / 28) * Math.PI * 2;
          const r = 180 + (i % 3) * 30;
          const x = Math.cos(a) * r;
          const y = Math.sin(a) * r;
          const isCoral = i % 3 === 0;
          return (
            <div key={i} style={{
              position: 'absolute', left: '50%', top: '50%',
              transform: `translate(${x}px, ${y}px) rotate(${i * 27}deg)`,
              width: 6, height: i % 2 ? 6 : 14,
              background: isCoral ? 'var(--coral)' : '#fff',
              borderRadius: 1,
              opacity: 0.7,
            }} />
          );
        })}
      </div>

      <div style={{
        width: 96, height: 96, borderRadius: '50%',
        background: 'var(--coral)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        margin: '0 auto 22px',
        boxShadow: '0 20px 60px rgba(255,97,85,0.4)',
      }}>
        {Icon.check({ size: 44, stroke: '#0D0D0D', strokeWidth: 2.4 })}
      </div>

      <h1 style={{
        fontFamily: 'var(--display)', fontSize: 48, fontWeight: 900,
        letterSpacing: '-0.04em', margin: '0 0 8px',
        textTransform: 'uppercase', color: '#fff', lineHeight: 1,
      }}>Day 48 posted.</h1>
      <p style={{ fontSize: 16, color: 'var(--text-2)', margin: '0 0 22px' }}>
        Streak alive. Backers notified.
      </p>

      <div style={{
        background: 'rgba(255,97,85,0.08)',
        border: '1px solid rgba(255,97,85,0.3)',
        borderRadius: 'var(--radius-card)',
        padding: '20px 28px',
        display: 'inline-flex', alignItems: 'center', gap: 14,
        marginBottom: 28,
      }}>
        {Icon.coin({ size: 28, stroke: 'var(--coral)' })}
        <MonoNum size={42} weight={700} color="var(--coral)" style={{ letterSpacing: '-0.02em', lineHeight: 1 }}>+10</MonoNum>
        <div style={{ textAlign: 'left' }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: '#fff' }}>coins earned</div>
          <div style={{ fontSize: 11, color: 'var(--text-2)', fontFamily: 'var(--mono)' }}>12 backers notified</div>
        </div>
      </div>

      <div>
        <CoralButton size="lg" icon="chevronR" onClick={() => (window.location.hash = '/feed')}>View in feed</CoralButton>
      </div>
    </div>
  );
}

function PostClosedCard() {
  return (
    <div style={{ width: 480, textAlign: 'center' }}>
      <div style={{
        width: 88, height: 88, borderRadius: 'var(--radius-card)',
        border: '1.5px solid rgba(255,97,85,0.4)',
        background: 'rgba(255,97,85,0.04)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        margin: '0 auto 22px',
      }}>
        {Icon.vault({ size: 44, stroke: 'var(--coral)' })}
      </div>

      <h1 style={{
        fontFamily: 'var(--display)', fontSize: 48, fontWeight: 900,
        letterSpacing: '-0.04em', margin: '0 0 12px',
        textTransform: 'uppercase', color: '#fff', lineHeight: 1.02,
      }}>The window is closed.</h1>
      <p style={{ fontSize: 15, color: 'var(--text-2)', margin: '0 0 28px', lineHeight: 1.5 }}>
        Posts are locked until 6:00 AM tomorrow. Don’t take it personally — that’s the rule.
      </p>

      <div style={{
        background: 'var(--surface)',
        border: '1px solid var(--border)',
        borderRadius: 'var(--radius-card)',
        padding: '22px 28px',
        marginBottom: 22,
      }}>
        <div style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.12 + 'em', marginBottom: 6, fontFamily: 'var(--mono)' }}>
          Opens in
        </div>
        <MonoNum size={48} weight={700} color="var(--coral)" style={{ letterSpacing: '0.01em' }}>06:14:22</MonoNum>
      </div>

      <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
        <GhostButton icon="bell" onClick={() => alert('Reminder set — we will ping you when the window opens.')}>Set a reminder</GhostButton>
        <CoralButton onClick={() => (window.location.hash = '/feed')}>Back to feed</CoralButton>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// SEARCH
// ────────────────────────────────────────────────────────────────────────
function SearchPage({ width = 1280, height = 1000 }) {
  const [q, setQ] = useStateP('priya');
  const [tab, setTab] = useStateP('people');
  const D = window.PROVE_DATA;
  const tabs = [
    { id: 'people', label: 'People', count: 3 },
    { id: 'proofs', label: 'Proofs', count: 12 },
    { id: 'rooms',  label: 'Rooms',  count: 4 },
  ];

  return (
    <PageShell width={width} height={height} active="explore">
      <div style={{ height: '100%', overflow: 'auto', padding: '24px 28px' }}>
        <h1 style={pageTitleStyle}>Search</h1>

        <div style={{ position: 'relative', marginTop: 16, marginBottom: 20 }}>
          <div style={{ position: 'absolute', left: 16, top: '50%', transform: 'translateY(-50%)' }}>
            {Icon.search({ size: 16, stroke: 'var(--text-2)' })}
          </div>
          <input
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder="People, proofs, rooms…"
            style={{
              width: '100%', padding: '14px 44px 14px 46px',
              background: 'var(--surface)',
              border: '1px solid var(--coral)',
              borderRadius: 999,
              color: '#fff', fontFamily: 'inherit', fontSize: 15,
              outline: 'none',
              boxSizing: 'border-box',
            }}
          />
          <button onClick={() => setQ('')} style={{
            position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)',
            background: 'rgba(255,255,255,0.1)', border: 'none', borderRadius: '50%',
            width: 22, height: 22, cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {Icon.x({ size: 11, stroke: '#fff' })}
          </button>
        </div>

        <FilterTabs tabs={tabs} value={tab} onChange={setTab} />

        {tab === 'people' && (
          <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 8 }}>
            {D.users.slice(0, 6).map((u, i) => (
              <div key={u.handle} style={{
                display: 'grid', gridTemplateColumns: '44px 1fr auto auto',
                gap: 14, alignItems: 'center',
                padding: '12px 18px',
                background: 'var(--surface)', border: '1px solid var(--border)',
                borderRadius: 'var(--radius-card)',
              }}>
                <Avatar user={u} size={40} />
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 600, color: '#fff', display: 'flex', alignItems: 'center', gap: 8 }}>
                    {u.handle}
                    <REPBadge score={D.leaderboard[i]?.rep || 1000} inline />
                  </div>
                  <div style={{ fontSize: 12, color: 'var(--text-2)' }}>{u.name}</div>
                </div>
                <MonoNum size={13} color="var(--text-2)">{D.leaderboard[i]?.streak || 0}d streak</MonoNum>
                <GhostButton size="md" onClick={() => alert('Followed.')}>Follow</GhostButton>
              </div>
            ))}
          </div>
        )}
        {tab === 'proofs' && (
          <div style={{ marginTop: 18, display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 14 }}>
            {D.proofs.slice(0, 4).map((p) => <ProofCard key={p.id} proof={p} />)}
          </div>
        )}
        {tab === 'rooms' && (
          <div style={{ marginTop: 18, display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 14 }}>
            {SAMPLE_ROOMS.slice(0, 4).map((r) => <RoomCard key={r.id} room={r} />)}
          </div>
        )}
      </div>
    </PageShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// ROOMS (Challenges)
// ────────────────────────────────────────────────────────────────────────
const SAMPLE_ROOMS = [
  { id: 'r1', name: 'Iron Mile Club', habit: 'running', members: 142, leader: 'devon.r', desc: 'Run every day. No exceptions. No excuses.' },
  { id: 'r2', name: '5AM Stoics',    habit: 'meditate', members: 87,  leader: 'priya_s', desc: 'Twenty minutes silent before the sun.' },
  { id: 'r3', name: 'Read Or Die',   habit: 'reading',  members: 311, leader: 'priya_s', desc: 'A page a day. A book a month. Every month.' },
  { id: 'r4', name: 'Cold Cult',     habit: 'cold',     members: 64,  leader: 'kev.do',  desc: 'Below 50°F. Below the comfort line.' },
  { id: 'r5', name: 'Drylanders',    habit: 'sobriety', members: 198, leader: 'sasha.m', desc: 'Day by day. Six months in.' },
  { id: 'r6', name: 'Iron Pen',      habit: 'writing',  members: 73,  leader: 'nico_w',  desc: '500 words. Bad ones count.' },
];

function RoomsPage({ width = 1280, height = 1100 }) {
  const [tab, setTab] = useStateP('discover');
  const tabs = [{ id: 'discover', label: 'Discover' }, { id: 'mine', label: 'My rooms', count: 2 }];
  return (
    <PageShell width={width} height={height} active="rooms">
      <div style={{ height: '100%', overflow: 'auto', padding: '24px 28px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end' }}>
          <div>
            <h1 style={pageTitleStyle}>Rooms</h1>
            <p style={{ fontSize: 14, color: 'var(--text-2)', margin: '6px 0 18px' }}>
              Small accountability pods. More eyes on you. More coins on the line.
            </p>
          </div>
          <CoralButton icon="plus" onClick={() => alert('Create a room from the mobile app for now.')}>Create room</CoralButton>
        </div>
        <FilterTabs tabs={tabs} value={tab} onChange={setTab} />

        <div style={{ marginTop: 22, display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 14 }}>
          {SAMPLE_ROOMS.map((r) => <RoomCard key={r.id} room={r} />)}
        </div>
      </div>
    </PageShell>
  );
}

function RoomCard({ room }) {
  const D = window.PROVE_DATA;
  const h = D.habits[room.habit];
  const leader = D.byHandle[room.leader];
  return (
    <div
      onClick={() => (window.location.hash = '/rooms/' + room.id)}
      style={{
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-card)',
      padding: 18,
      cursor: 'pointer',
      transition: 'border-color 0.12s',
    }}
    onMouseEnter={(e) => e.currentTarget.style.borderColor = 'var(--border-hi)'}
    onMouseLeave={(e) => e.currentTarget.style.borderColor = 'var(--border)'}
    >
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 12 }}>
        <div>
          <h3 style={{
            fontFamily: 'var(--display)', fontSize: 20, fontWeight: 700,
            letterSpacing: '-0.02em', textTransform: 'uppercase',
            color: '#fff', margin: '0 0 6px',
          }}>{room.name}</h3>
          <HabitPill habit={h} size="sm" />
        </div>
        <MonoNum size={11} color="var(--text-3)" style={{ marginTop: 4 }}>#{room.id}</MonoNum>
      </div>
      <p style={{ fontSize: 13, color: 'var(--text-2)', margin: '0 0 16px', lineHeight: 1.5, minHeight: 36 }}>
        {room.desc}
      </p>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <Avatar user={leader} size={24} />
        <span style={{ fontSize: 12, color: 'var(--text-2)' }}>{leader.handle} leads</span>
        <span style={{ marginLeft: 'auto', display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 12, color: 'var(--text-2)' }}>
          {Icon.user({ size: 12, stroke: 'var(--text-2)' })}
          <MonoNum size={12} color="#fff" weight={600}>{room.members}</MonoNum>
        </span>
      </div>
    </div>
  );
}

function RoomDetailPage({ width = 1280, height = 1200 }) {
  const D = window.PROVE_DATA;
  const room = SAMPLE_ROOMS[0];
  const h = D.habits[room.habit];
  const memberLeaderboard = D.leaderboard.slice(0, 6).map((r, i) => ({ ...r, rank: i + 1 }));
  const roomProofs = D.proofs.slice(0, 4);
  return (
    <PageShell width={width} height={height} active="rooms">
      <div style={{ height: '100%', overflow: 'auto', padding: '24px 28px 40px' }}>
        <div style={{ fontSize: 12, color: 'var(--text-3)', fontFamily: 'var(--mono)', marginBottom: 12 }}>
          ← Rooms / {room.name}
        </div>

        <div style={{
          background: 'var(--surface)', border: '1px solid var(--border)',
          borderRadius: 'var(--radius-card)', padding: 28, marginBottom: 24,
          display: 'flex', alignItems: 'flex-end', gap: 24,
        }}>
          <div style={{ flex: 1 }}>
            <HabitPill habit={h} dark />
            <h1 style={{
              fontFamily: 'var(--display)', fontSize: 48, fontWeight: 800,
              letterSpacing: '-0.04em', margin: '12px 0 6px',
              textTransform: 'uppercase', color: '#fff', lineHeight: 1,
            }}>{room.name}</h1>
            <p style={{ fontSize: 15, color: 'var(--text-2)', margin: 0 }}>{room.desc}</p>
            <div style={{ marginTop: 16, display: 'flex', gap: 24 }}>
              <div>
                <div style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.12 + 'em' }}>Members</div>
                <MonoNum size={24} weight={700} color="#fff">{room.members}</MonoNum>
              </div>
              <div>
                <div style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.12 + 'em' }}>Leader streak</div>
                <MonoNum size={24} weight={700} color="var(--coral)">184d</MonoNum>
              </div>
              <div>
                <div style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.12 + 'em' }}>Total proofs</div>
                <MonoNum size={24} weight={700} color="#fff">4,128</MonoNum>
              </div>
            </div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            <CoralButton onClick={() => alert('Joined! Track this room from the mobile app.')}>Join room</CoralButton>
            <GhostButton size="md" onClick={() => {
              const url = window.location.href.replace(/#.*$/, '#' + window.location.hash);
              if (navigator.share) navigator.share({ title: 'PROVE room', url }).catch(() => {});
              else { navigator.clipboard?.writeText(url); alert('Link copied!'); }
            }}>Invite</GhostButton>
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 20 }}>
          <div>
            <h2 style={subTitleStyle}>Room leaderboard</h2>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {memberLeaderboard.map((row) => <LeaderRow key={row.rank} row={row} compact />)}
            </div>
          </div>
          <div>
            <h2 style={subTitleStyle}>Member proofs</h2>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              {roomProofs.map((p) => <ProofCard key={p.id} proof={p} />)}
            </div>
          </div>
        </div>
      </div>
    </PageShell>
  );
}

// ────────────────────────────────────────────────────────────────────────
// STAKES HISTORY
// ────────────────────────────────────────────────────────────────────────
function StakesHistoryPage({ width = 1280, height = 1100 }) {
  const [tab, setTab] = useStateP('all');
  const D = window.PROVE_DATA;
  const tabs = [{ id: 'active', label: 'Active', count: 6 }, { id: 'settled', label: 'Settled', count: 24 }, { id: 'all', label: 'All', count: 30 }];

  const stakes = [
    { user: 'priya_s',  side: 'back',  proof: 'reading day 92', amount: 50, status: 'won',     payout: 75 },
    { user: 'jordan.b', side: 'doubt', proof: 'meditate day 3', amount: 25, status: 'pending', payout: null },
    { user: 'devon.r',  side: 'back',  proof: 'running day 12', amount: 50, status: 'lost',    payout: 0 },
    { user: 'sasha.m',  side: 'back',  proof: 'sobriety day 184', amount: 100, status: 'pending', payout: null },
    { user: 'tomas.lin', side: 'back', proof: 'cooking day 28', amount: 25, status: 'won',     payout: 38 },
    { user: 'kev.do',   side: 'doubt', proof: 'cold day 8',     amount: 25, status: 'pending', payout: null },
    { user: 'amara_o',  side: 'back',  proof: 'spanish day 34', amount: 50, status: 'won',     payout: 62 },
  ];

  return (
    <PageShell width={width} height={height} active="activity">
      <div style={{ padding: 32 }}>
        <PageHeader
          section="§ 07 / stakes"
          title="Stakes"
          sub="Every coin you’ve put on someone’s streak."
        />

        {/* Summary row */}
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12,
          marginBottom: 22,
        }}>
          {[
            { label: 'Total staked', value: '1,820', sub: 'lifetime', color: '#fff' },
            { label: 'Total earned', value: '+2,140', sub: 'from won stakes', color: 'var(--coral)' },
            { label: 'Win rate',     value: '67%',   sub: '20 of 30',         color: '#fff' },
            { label: 'Currently riding', value: '275', sub: 'on 6 active proofs', color: '#fff' },
          ].map((s) => (
            <div key={s.label} style={{
              background: 'var(--surface)', border: '1px solid var(--border)',
              borderRadius: 'var(--radius-card)', padding: 18,
            }}>
              <div style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.1 + 'em' }}>{s.label}</div>
              <MonoNum size={26} weight={700} color={s.color} style={{ display: 'block', margin: '6px 0 4px', lineHeight: 1 }}>{s.value}</MonoNum>
              <div style={{ fontSize: 11, color: 'var(--text-2)' }}>{s.sub}</div>
            </div>
          ))}
        </div>

        <FilterTabs tabs={tabs} value={tab} onChange={setTab} />

        <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 6 }}>
          {stakes.map((s, i) => <StakeRow key={i} row={s} />)}
        </div>
      </div>
    </PageShell>
  );
}

function StakeRow({ row }) {
  const D = window.PROVE_DATA;
  const u = D.byHandle[row.user];
  const isBack = row.side === 'back';
  const wonColor = row.status === 'won' ? 'var(--coral)' : row.status === 'lost' ? 'var(--text-3)' : 'var(--text-2)';
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '48px 1fr 90px 110px 110px',
      gap: 14, alignItems: 'center',
      padding: '12px 18px 12px 12px',
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-card)',
    }}>
      <Avatar user={u} size={36} />
      <div>
        <div style={{ fontSize: 13, color: '#fff', fontWeight: 600 }}>{u.handle}</div>
        <div style={{ fontSize: 11, color: 'var(--text-2)' }}>{row.proof}</div>
      </div>
      <span style={{
        padding: '4px 10px',
        background: isBack ? 'var(--coral)' : 'rgba(255,255,255,0.12)',
        color: isBack ? '#0D0D0D' : '#fff',
        borderRadius: 999, fontSize: 10, fontWeight: 700,
        letterSpacing: 0.08 + 'em', textTransform: 'uppercase',
        textAlign: 'center',
      }}>{row.side}</span>
      <MonoNum size={14} weight={600} color="#fff" style={{ textAlign: 'right' }}>{row.amount} coins</MonoNum>
      <div style={{ textAlign: 'right' }}>
        <div style={{ fontSize: 10, color: wonColor, textTransform: 'uppercase', letterSpacing: 0.1 + 'em', fontWeight: 700 }}>
          {row.status}
        </div>
        <MonoNum size={14} weight={700} color={wonColor}>
          {row.status === 'won' ? `+${row.payout}` : row.status === 'lost' ? `-${row.amount}` : '—'}
        </MonoNum>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// MILESTONE OVERLAY (Day 7 + Day 30)
// ────────────────────────────────────────────────────────────────────────
function MilestonePage({ width = 1280, height = 900, day = 7 }) {
  const isThirty = day === 30;
  const reward = isThirty ? 200 : 50;

  return (
    <div style={{
      width, height, color: '#fff',
      position: 'relative', overflow: 'hidden',
      fontFamily: 'var(--body)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: 'radial-gradient(ellipse 80% 50% at 50% -10%, rgba(255,97,85,0.06) 0%, transparent 60%), #0D0D0D',
      borderTop: '3px solid var(--coral)',
    }}>
      {/* Huge day watermark */}
      <span style={{
        position: 'absolute', top: '50%', left: '50%',
        transform: 'translate(-50%, -50%)',
        fontFamily: 'var(--display)',
        fontSize: 'min(64vw, 900px)', fontWeight: 900,
        letterSpacing: '-0.06em',
        color: isThirty ? 'rgba(255,180,40,0.06)' : 'rgba(255,255,255,0.035)',
        lineHeight: 0.85, pointerEvents: 'none',
        userSelect: 'none',
      }}>{day}</span>

      {/* Confetti — 24 particles falling */}
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden' }}>
        {Array.from({ length: 28 }).map((_, i) => {
          const startX = (Math.sin(i * 7.13) + 1) * 50;
          const drift = (Math.cos(i * 11.17)) * 80;
          const delay = (i % 8) * 0.25;
          const dur = 2.6 + (i % 4) * 0.4;
          const isCoral = i % 3 !== 0;
          const isCircle = i % 4 === 0;
          return (
            <div key={i} style={{
              position: 'absolute', top: '-10%', left: startX + '%',
              width: 6 + (i % 3) * 2,
              height: isCircle ? 6 + (i % 3) * 2 : 12 + (i % 3) * 3,
              background: isCoral ? 'var(--coral)' : (isThirty ? 'rgb(255,180,40)' : '#fff'),
              borderRadius: isCircle ? '50%' : 1,
              animation: `prove-confetti-drop ${dur}s ease-in ${delay}s infinite`,
              '--cx': drift + 'px',
              opacity: 0.85,
            }} />
          );
        })}
      </div>

      {/* Amber radial glow for Day 30 */}
      {isThirty && (
        <div style={{
          position: 'absolute', top: '50%', left: '50%',
          width: 800, height: 800,
          transform: 'translate(-50%, -50%)',
          background: 'radial-gradient(circle, rgba(255,180,40,0.18), transparent 60%)',
          pointerEvents: 'none',
        }} />
      )}

      <div style={{ position: 'relative', zIndex: 2, textAlign: 'center', maxWidth: 600, padding: 32 }}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 22 }}>
          {isThirty ? (
            <div style={{
              width: 120, height: 120, borderRadius: '50%',
              background: 'rgba(255,180,40,0.1)',
              border: '2px solid rgba(255,180,40,0.4)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              {Icon.trophy({ size: 80, stroke: 'rgb(255,180,40)', strokeWidth: 1.6 })}
            </div>
          ) : (
            <StreakRing day={day} target={day} size={130} stroke={8} animate />
          )}
        </div>

        <span style={{ fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--coral)', letterSpacing: 0.16 + 'em', textTransform: 'uppercase', fontWeight: 700 }}>
          Milestone unlocked
        </span>

        <h1 style={{
          fontFamily: 'var(--display)', fontSize: isThirty ? 88 : 72, fontWeight: 900,
          letterSpacing: '-0.045em', margin: '14px 0 16px',
          textTransform: 'uppercase', color: '#fff', lineHeight: 0.96,
        }}>Day {day}.</h1>
        <p style={{ fontSize: 19, color: 'var(--text-2)', margin: '0 0 32px', lineHeight: 1.45 }}>
          {isThirty
            ? 'Most people quit by now. You’re past it.'
            : 'You’re in the top 40%. Keep showing up.'}
        </p>

        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 18,
          padding: '22px 32px',
          background: 'linear-gradient(135deg, rgba(255,97,85,0.12), rgba(255,97,85,0.02))',
          border: '1px solid rgba(255,97,85,0.3)',
          borderRadius: 'var(--radius-card)',
          marginBottom: 32,
          boxShadow: '0 0 60px rgba(255,97,85,0.15)',
        }}>
          {Icon.coin({ size: 32, stroke: 'var(--coral)' })}
          <MonoNum size={64} weight={700} color="var(--coral)" style={{
            letterSpacing: '-0.04em', lineHeight: 1,
            animation: isThirty ? 'prove-breathe 2.4s ease-in-out infinite' : 'none',
            display: 'inline-block',
          }}>+{reward}</MonoNum>
          <div style={{ textAlign: 'left' }}>
            <div style={{ fontSize: 14, fontWeight: 600 }}>coins added</div>
            <div style={{ fontSize: 11, color: 'var(--text-2)', fontFamily: 'var(--mono)' }}>balance: 2,840 + {reward}</div>
          </div>
        </div>

        <div>
          <CoralButton size="lg" icon="chevronR" onClick={() => (window.location.hash = '/feed')}>Keep going</CoralButton>
        </div>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// ERROR STATES (offline + 404 + crash) — combined montage
// ────────────────────────────────────────────────────────────────────────
function ErrorStatesPage({ width = 1280, height = 900, state = 'offline' }) {
  return (
    <div style={{ width, height, background: 'var(--bg)', color: '#fff', fontFamily: 'var(--body)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 32 }}>
      <div style={{ width: 480, textAlign: 'center' }}>
        {state === 'offline' && <ErrorBlock icon="wifiOff" title="You’re offline."     body="PROVE needs a connection to load proofs." cta="Retry" />}
        {state === '404'     && <ErrorBlock icon="lock"    title="This proof was removed." body="It may have been deleted by its author or flagged by moderation." cta="Back to feed" />}
        {state === 'error'   && <ErrorBlock icon="x"       title="Something went wrong." body={<>Error ID <MonoNum size={12} color="var(--text-3)" style={{ background: 'rgba(255,255,255,0.06)', padding: '2px 6px', borderRadius: 4 }}>e_8d3f9c</MonoNum> · share with support if it persists.</>} cta="Reload page" secondary="Contact support" />}
      </div>
    </div>
  );
}

function ErrorBlock({ icon, title, body, cta, secondary }) {
  return (
    <>
      <div style={{
        width: 88, height: 88, borderRadius: '50%',
        background: 'rgba(255,97,85,0.08)',
        border: '1px solid rgba(255,97,85,0.3)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        margin: '0 auto 22px',
      }}>
        {Icon[icon]({ size: 40, stroke: 'var(--coral)' })}
      </div>
      <h1 style={{
        fontFamily: 'var(--display)', fontSize: 36, fontWeight: 800,
        letterSpacing: '-0.03em', margin: '0 0 12px',
        textTransform: 'uppercase', color: '#fff',
      }}>{title}</h1>
      <p style={{ fontSize: 15, color: 'var(--text-2)', margin: '0 0 26px', lineHeight: 1.5 }}>{body}</p>
      <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
        {secondary && <GhostButton>{secondary}</GhostButton>}
        <CoralButton size="lg">{cta}</CoralButton>
      </div>
    </>
  );
}

// ────────────────────────────────────────────────────────────────────────
// MODAL DEMO ARTBOARDS — show each modal standalone on a dimmed feed
// ────────────────────────────────────────────────────────────────────────
function ModalArtboard({ width = 800, height = 700, type = 'stake' }) {
  const D = window.PROVE_DATA;
  return (
    <div style={{
      width, height, background: 'var(--bg)', color: '#fff',
      position: 'relative', overflow: 'hidden', fontFamily: 'var(--body)',
    }}>
      {/* faint backdrop content */}
      <div style={{ padding: 28, opacity: 0.4, filter: 'blur(2px)' }}>
        <h1 style={pageTitleStyle}>The Feed</h1>
        <div style={{ marginTop: 18, display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 14 }}>
          {D.proofs.slice(0, 2).map((p) => <ProofCard key={p.id} proof={p} />)}
        </div>
      </div>
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.6)', backdropFilter: 'blur(6px)' }} />

      <div style={{
        position: 'absolute', inset: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        zIndex: 10,
      }}>
        {type === 'stake'    && <StakeModalInline proof={D.proofs[0]} />}
        {type === 'comments' && <CommentsModalInline proof={D.proofs[0]} />}
        {type === 'reactions'&& <ReactionsModalInline />}
      </div>
    </div>
  );
}

// "Inline" wrappers that render the modal contents without the overlay
// (so they fit cleanly inside the modal-showcase artboard).
function StakeModalInline({ proof }) {
  return <StakeModal open={true} onClose={() => {}} proof={proof} initialSide="back" onConfirm={() => {}} />;
}
function CommentsModalInline({ proof }) {
  return <CommentsModal open={true} onClose={() => {}} proof={proof} />;
}
function ReactionsModalInline() {
  return <ReactionsModal open={true} onClose={() => {}} />;
}

Object.assign(window, {
  LoginPage, SignupPage, ForgotPasswordPage,
  OnboardingHabitPage, OnboardingStakePage,
  NotificationsPage, ActivityPage,
  CoinsPage, ProPage, StreakShieldPage,
  SettingsPage, SettingsNotificationsPage,
  PostFlowPage, SearchPage,
  RoomsPage, RoomDetailPage, RoomCard, SAMPLE_ROOMS,
  StakesHistoryPage,
  MilestonePage, ErrorStatesPage,
  ModalArtboard,
});
