/* All HiredAF screens. Each accepts { go, setState, state } and returns JSX. */

// Mutable theme objects. The host page mutates these via Tweaks then
// re-renders App, so all screens read the new values at render time.
const COLOR = {
  bg: '#0a0a09',
  ink: '#f4efe1',
  acid: '#d4ff3a',
  red: '#ff3528',
  smoke: '#1a1916',
  ash:  '#26241f',
  dim:  '#8a8779',
};

const fonts = {
  display: '"Bricolage Grotesque", system-ui, sans-serif',
  displayWeight: 800,
  displayStyle: 'normal',
  displayTracking: '-0.045em',
  body:    '"Space Grotesk", system-ui, sans-serif',
  mono:    '"JetBrains Mono", ui-monospace, monospace',
  serif:   '"Instrument Serif", Georgia, serif',
};

const VOICE = {
  heroAccent: 'is mid.',
  ctaHero: 'Roast me. →',
  pasteAccent: 'evidence.',
  ctaPaste: 'COOK IT 🔥',
  scoreLabel: '“needs help.”',
  ctaFix: 'Fix this trash →',
};

const PALETTES = {
  ACID:     { bg:'#0a0a09', ink:'#f4efe1', acid:'#d4ff3a', red:'#ff3528', smoke:'#1a1916', ash:'#26241f', dim:'#8a8779' },
  INFERNO:  { bg:'#0c0604', ink:'#ffeadd', acid:'#ff7a1a', red:'#ff2d6a', smoke:'#1c0d05', ash:'#2c1a0b', dim:'#8a6a52' },
  Y2K:      { bg:'#070220', ink:'#ecddff', acid:'#4dffff', red:'#ff3df7', smoke:'#14082e', ash:'#221248', dim:'#7a6aaa' },
  TERMINAL: { bg:'#050a05', ink:'#b8ffb8', acid:'#2bff5d', red:'#ffaa00', smoke:'#0a160a', ash:'#14241a', dim:'#4a8a55' },
};

const FONT_THEMES = {
  CHUNKY:    { display: '"Bricolage Grotesque", system-ui, sans-serif', displayWeight: 800, displayStyle: 'normal', displayTracking: '-0.045em' },
  EDITORIAL: { display: '"Instrument Serif", Georgia, serif',           displayWeight: 400, displayStyle: 'italic', displayTracking: '-0.025em' },
  TERMINAL:  { display: '"JetBrains Mono", ui-monospace, monospace',    displayWeight: 700, displayStyle: 'normal', displayTracking: '-0.04em' },
};

const VOICE_PRESETS = {
  SHARP: {
    heroAccent: 'is mid.',
    ctaHero: 'Roast me. →',
    pasteAccent: 'evidence.',
    ctaPaste: 'COOK IT 🔥',
    scoreLabel: '“needs help.”',
    ctaFix: 'Fix this trash →',
  },
  HONEST: {
    heroAccent: 'needs work.',
    ctaHero: 'Review me. →',
    pasteAccent: 'details.',
    ctaPaste: 'ANALYZE IT 🔍',
    scoreLabel: '“room to grow.”',
    ctaFix: 'Rebuild it →',
  },
  KIND: {
    heroAccent: 'has potential.',
    ctaHero: 'Coach me. →',
    pasteAccent: 'story.',
    ctaPaste: 'POLISH IT ✨',
    scoreLabel: '“so close.”',
    ctaFix: 'Make it shine →',
  },
};

// ─── shared bits ────────────────────────────────────────────────────────────
function NoiseBg({ children, color = COLOR.bg }) {
  return (
    <div style={{
      width: '100%', minHeight: '100%', background: color, color: COLOR.ink,
      fontFamily: fonts.body, position: 'relative',
    }}>
      <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none', opacity: 0.5,
        backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.96  0 0 0 0 0.94  0 0 0 0 0.88  0 0 0 0.06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")`,
        mixBlendMode: 'overlay',
      }}/>
      {children}
    </div>
  );
}

function MarqueeStrip({ items, color = COLOR.acid, speed = 28, dark = true }) {
  return (
    <div style={{
      background: dark ? COLOR.ink : COLOR.bg,
      color: dark ? COLOR.bg : COLOR.ink,
      borderTop: `1px solid ${COLOR.ash}`,
      borderBottom: `1px solid ${COLOR.ash}`,
      overflow: 'hidden', position: 'relative',
    }}>
      <div style={{
        display: 'flex', gap: 24, padding: '10px 0', whiteSpace: 'nowrap',
        animation: `marquee ${speed}s linear infinite`,
        fontFamily: fonts.display, fontWeight: 700, fontSize: 14,
        letterSpacing: '-0.01em', textTransform: 'uppercase',
      }}>
        {[...Array(2)].map((_,i)=>(
          <React.Fragment key={i}>
            {items.map((t,j)=>(
              <React.Fragment key={j}>
                <span>{t}</span>
                <span style={{ color: color, fontFamily: fonts.body }}>✦</span>
              </React.Fragment>
            ))}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

// ─── 1. HERO ─────────────────────────────────────────────────────────────────
function ScreenHero({ go }) {
  const [count, setCount] = React.useState(1247892);
  React.useEffect(() => {
    const id = setInterval(() => setCount(c => c + Math.floor(Math.random()*3+1)), 1400);
    return () => clearInterval(id);
  }, []);

  return (
    <NoiseBg>
      {/* top tag */}
      <div style={{
        padding: '54px 20px 0', display: 'flex', justifyContent: 'space-between',
        alignItems: 'center', fontFamily: fonts.mono, fontSize: 11,
        color: COLOR.dim, letterSpacing: '0.08em', textTransform: 'uppercase',
      }}>
        <span>● hiredAF.ai</span>
        <span style={{ color: COLOR.acid }}>free tool</span>
      </div>

      {/* hero stack */}
      <div style={{ padding: '32px 20px 0' }}>
        <div style={{
          fontFamily: fonts.mono, fontSize: 11, color: COLOR.dim,
          marginBottom: 16, letterSpacing: '0.1em', textTransform: 'uppercase',
        }}>
          [ free tool · zero signup ]
        </div>
        <h1 style={{
          fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle,
          fontSize: 76, lineHeight: 0.86, letterSpacing: '-0.045em',
          margin: 0, color: COLOR.ink,
        }}>
          your<br/>
          resume<br/>
          <span style={{ fontFamily: fonts.serif, fontWeight: 400, fontStyle: 'italic', color: COLOR.acid }}>
            {VOICE.heroAccent}
          </span>
        </h1>
        <p style={{
          marginTop: 22, fontSize: 16, lineHeight: 1.35, color: '#cfcbbc',
          maxWidth: 320,
        }}>
          Paste it in. We'll roast it raw, then build you one that <em style={{ fontFamily: fonts.serif }}>actually</em> gets opened.
        </p>
      </div>

      {/* CTA card */}
      <div style={{ padding: '28px 20px 0' }}>
        <button onClick={() => go('paste')} style={{
          width: '100%', padding: '20px 22px', border: 'none', cursor: 'pointer',
          background: COLOR.acid, color: COLOR.bg, borderRadius: 18,
          fontFamily: fonts.display, fontWeight: 700, fontSize: 22,
          letterSpacing: '-0.02em', textAlign: 'left',
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          boxShadow: `0 0 0 1px ${COLOR.ash}, 0 24px 40px -16px ${COLOR.acid}88`,
        }}>
          {VOICE.ctaHero}
          <span style={{ fontFamily: fonts.mono, fontSize: 11, opacity: 0.7 }}>FREE</span>
        </button>
        <div style={{
          marginTop: 12, fontFamily: fonts.mono, fontSize: 11,
          color: COLOR.dim, display: 'flex', justifyContent: 'space-between',
        }}>
          <span>⏱ avg roast time: 6.2s</span>
          <span>🔥 brutal mode on</span>
        </div>
      </div>

      {/* live counter */}
      <div style={{ padding: '34px 20px 18px' }}>
        <div style={{
          borderTop: `1px dashed ${COLOR.ash}`, paddingTop: 14,
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
        }}>
          <span style={{ fontFamily: fonts.mono, fontSize: 10, color: COLOR.dim, letterSpacing: '0.1em', textTransform: 'uppercase' }}>
            roasts served →
          </span>
          <span style={{ fontFamily: fonts.display, fontSize: 24, fontWeight: 700, color: COLOR.ink, letterSpacing: '-0.02em' }}>
            {count.toLocaleString()}
          </span>
        </div>
      </div>

      <MarqueeStrip items={[
        'TIKTOK MADE ME DO IT', 'POV: YOUR RESUME IS COOKED', '$4.99 < ONE COFFEE',
        'ATS-PROOF', 'CEASE THE COPIUM', 'BUILT BY EX-FAANG RECRUITERS',
      ]} />

      {/* social proof tiles */}
      <div style={{ padding: '20px 20px 100px', display: 'grid', gap: 10 }}>
        <TestimonialCard
          handle="@maddyhellgate"
          stars={5}
          body="bro i was sobbing it told me my hobby section &quot;reads like a hostage note&quot; 😭"
          plat="tt"
        />
        <TestimonialCard
          handle="@jpegjayden"
          stars={5}
          body="got the roast. got the rewrite. got the callback in 9 days. unreal."
          plat="ig"
        />
        <TestimonialCard
          handle="@notyourintern"
          stars={4}
          body="cried. healed. landed the bag. would recommend to my worst enemy."
          plat="tt"
        />
      </div>
    </NoiseBg>
  );
}

function TestimonialCard({ handle, body, stars, plat }) {
  return (
    <div style={{
      background: COLOR.smoke, border: `1px solid ${COLOR.ash}`,
      padding: 14, borderRadius: 14,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{
            width: 22, height: 22, borderRadius: '50%',
            background: `linear-gradient(135deg, ${COLOR.acid}, ${COLOR.red})`,
          }}/>
          <span style={{ fontFamily: fonts.body, fontWeight: 600, fontSize: 13, color: COLOR.ink }}>
            {handle}
          </span>
          <span style={{
            fontFamily: fonts.mono, fontSize: 9, padding: '2px 5px',
            background: COLOR.ash, color: COLOR.dim, borderRadius: 4,
            textTransform: 'uppercase',
          }}>{plat}</span>
        </div>
        <span style={{ color: COLOR.acid, fontSize: 11, letterSpacing: 1 }}>
          {'★'.repeat(stars)}{'☆'.repeat(5-stars)}
        </span>
      </div>
      <p style={{ margin: 0, fontSize: 13, lineHeight: 1.4, color: '#d2cebe' }}>{body}</p>
    </div>
  );
}

// ─── 2. PASTE ────────────────────────────────────────────────────────────────
function ScreenPaste({ go, state, setState }) {
  const [text, setText] = React.useState(state.resume || '');
  const [file, setFile] = React.useState(state.file || null);
  const [dragOver, setDragOver] = React.useState(false);
  const fileInputRef = React.useRef(null);

  const acceptFile = (f) => {
    if (!f) return;
    const name = (f.name || '').toLowerCase();
    if (f.type === 'application/pdf' || name.endsWith('.pdf') ||
        f.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
        name.endsWith('.docx') || name.endsWith('.doc')) {
      setFile(f);
      setText('');
    }
  };

  const ready = file ? true : text.length >= 30;

  return (
    <NoiseBg>
      <div style={{ padding: '54px 20px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <button onClick={() => go('hero')} style={{
          background: 'none', border: `1px solid ${COLOR.ash}`,
          color: COLOR.ink, fontFamily: fonts.mono, fontSize: 11, padding: '6px 10px',
          borderRadius: 8, letterSpacing: '0.06em', cursor: 'pointer',
        }}>← BACK</button>
        <span style={{ fontFamily: fonts.mono, fontSize: 11, color: COLOR.dim, letterSpacing: '0.08em' }}>
          STEP 01 / 02
        </span>
      </div>

      <div style={{ padding: '20px 20px 0' }}>
        <h2 style={{
          fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 44,
          lineHeight: 0.9, letterSpacing: '-0.04em', margin: 0,
        }}>
          drop the<br/>
          <span style={{ fontFamily: fonts.serif, fontStyle: 'italic', fontWeight: 400, color: COLOR.acid }}>{VOICE.pasteAccent}</span>
        </h2>
        <p style={{ marginTop: 14, fontSize: 14, color: COLOR.dim, lineHeight: 1.4 }}>
          Paste your resume below, or drop a PDF / DOCX.
        </p>
      </div>

      <div style={{ padding: '16px 20px 0' }}>
        <div
          onDragOver={e => { e.preventDefault(); setDragOver(true); }}
          onDragLeave={e => { if (!e.currentTarget.contains(e.relatedTarget)) setDragOver(false); }}
          onDrop={e => { e.preventDefault(); setDragOver(false); acceptFile(e.dataTransfer.files[0]); }}
          style={{
            background: dragOver ? COLOR.ash : COLOR.smoke,
            border: `1px dashed ${dragOver ? COLOR.acid : COLOR.ash}`,
            borderRadius: 14, padding: 14, position: 'relative',
            transition: 'background 0.15s, border-color 0.15s',
          }}
        >
          {file ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, minHeight: 80, padding: '8px 0' }}>
              <span style={{ fontSize: 28, flexShrink: 0 }}>
                {file.name.toLowerCase().endsWith('.pdf') ? '📄' : '📝'}
              </span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontFamily: fonts.mono, fontSize: 12, color: COLOR.ink,
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{file.name}</div>
                <div style={{ fontFamily: fonts.mono, fontSize: 10, color: COLOR.dim, marginTop: 3 }}>
                  {(file.size / 1024).toFixed(0)} KB · ready to roast
                </div>
              </div>
              <button onClick={() => setFile(null)} style={{
                background: 'none', border: `1px solid ${COLOR.ash}`, color: COLOR.dim,
                fontFamily: fonts.mono, fontSize: 10, padding: '4px 8px',
                borderRadius: 6, cursor: 'pointer', flexShrink: 0,
              }}>✕</button>
            </div>
          ) : (
            <textarea
              value={text}
              onChange={e => setText(e.target.value)}
              placeholder="JANE DOE&#10;Marketing Coordinator&#10;&#10;EXPERIENCE&#10;Marketing Intern, Big Corp Inc.&#10;• Responsible for managing social media accounts&#10;• Helped with campaigns and assisted the team&#10;• Utilized various tools to facilitate workflows..."
              style={{
                width: '100%', boxSizing: 'border-box', minHeight: 200,
                background: 'transparent', border: 'none', resize: 'none', outline: 'none',
                color: COLOR.ink, fontFamily: fonts.mono, fontSize: 11.5, lineHeight: 1.55,
              }}
            />
          )}

          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            paddingTop: 8, borderTop: `1px solid ${COLOR.ash}`,
            fontFamily: fonts.mono, fontSize: 10, color: COLOR.dim, letterSpacing: '0.06em',
          }}>
            <span>{file ? file.name.split('.').pop().toUpperCase() + ' attached' : `${text.length} chars`}</span>
            <button
              onClick={() => fileInputRef.current && fileInputRef.current.click()}
              style={{ background: 'none', border: 'none', color: COLOR.dim, cursor: 'pointer',
                fontFamily: fonts.mono, fontSize: 10, padding: 0 }}
            >
              📎 upload .pdf / .docx
            </button>
          </div>
        </div>

        <input
          ref={fileInputRef}
          type="file"
          accept=".pdf,.docx,.doc"
          style={{ display: 'none' }}
          onChange={e => acceptFile(e.target.files[0])}
        />

        <div style={{ display: 'flex', gap: 8, marginTop: 10 }}>
          {['BRUTAL', 'HONEST', 'KIND'].map((m,i)=>(
            <button key={m} onClick={()=>setState(s=>({...s, mode: m}))} style={{
              flex: 1, padding: '10px 0',
              background: state.mode === m ? COLOR.red : COLOR.smoke,
              color: state.mode === m ? COLOR.ink : COLOR.dim,
              border: `1px solid ${state.mode === m ? COLOR.red : COLOR.ash}`,
              borderRadius: 10, fontFamily: fonts.display, fontWeight: 700, fontSize: 12,
              letterSpacing: '0.04em', cursor: 'pointer',
            }}>
              {i === 0 && '🔥 '}{i === 1 && '🎯 '}{i === 2 && '🌸 '}{m}
            </button>
          ))}
        </div>
      </div>

      <div style={{ padding: '22px 20px' }}>
        <button
          onClick={() => { setState(s=>({...s, resume: text, file: file})); go('roasting'); }}
          disabled={!ready}
          style={{
            width: '100%', padding: '20px', border: 'none',
            background: !ready ? COLOR.ash : COLOR.red,
            color: !ready ? COLOR.dim : COLOR.ink,
            borderRadius: 18, cursor: !ready ? 'not-allowed' : 'pointer',
            fontFamily: fonts.display, fontWeight: 700, fontSize: 20,
            letterSpacing: '-0.02em',
            boxShadow: !ready ? 'none' : `0 20px 40px -16px ${COLOR.red}aa`,
          }}>
          {!ready ? (file ? 'processing…' : 'paste at least 30 chars…') : VOICE.ctaPaste}
        </button>
        <p style={{
          textAlign: 'center', marginTop: 10, fontFamily: fonts.mono,
          fontSize: 10, color: COLOR.dim, letterSpacing: '0.05em',
        }}>
          we never sell your data. we will however clown on it.
        </p>
      </div>
    </NoiseBg>
  );
}

// ─── 3. ROASTING (loading) ───────────────────────────────────────────────────
function ScreenRoasting({ go, state, setState }) {
  const lines = [
    'parsing your tragedy…',
    'counting buzzwords…',
    'flagging "responsible for"…',
    'detecting recruiter eye-rolls…',
    'measuring vibe deficit…',
    'forging your reality check…',
  ];
  const [i, setI] = React.useState(0);
  const [pct, setPct] = React.useState(0);
  const calledRef = React.useRef(false);
  // Always hold the latest go so the async callback doesn't capture a stale closure
  const goRef = React.useRef(go);
  goRef.current = go;

  React.useEffect(() => {
    const id = setInterval(() => setI(x => (x+1) % lines.length), 900);
    return () => clearInterval(id);
  }, []);

  React.useEffect(() => {
    const id = setInterval(() => setPct(p => p >= 95 ? 95 : p + 2.5), 130);
    return () => clearInterval(id);
  }, []);

  // Call the API once; navigate directly from the callback — no effect chain
  React.useEffect(() => {
    if (calledRef.current) return;
    calledRef.current = true;

    const finish = (roastText) => {
      setState(s => ({ ...s, roast: roastText }));
      setPct(100);
      setTimeout(() => goRef.current('email'), 500);
    };

    const fallback = setTimeout(() => {
      finish("Our roast engine timed out. Your resume's mediocrity broke the internet.");
    }, 30000);

    let fetchBody, fetchHeaders;
    if (state.file) {
      const fd = new FormData();
      fd.append('resume', state.file);
      fd.append('mode', state.mode || 'BRUTAL');
      fetchBody = fd;
      fetchHeaders = {}; // let browser set Content-Type with boundary
    } else {
      fetchBody = JSON.stringify({ resumeText: state.resume, mode: state.mode || 'BRUTAL' });
      fetchHeaders = { 'Content-Type': 'application/json' };
    }

    fetch('/api/resume/roast', {
      method: 'POST',
      headers: fetchHeaders,
      body: fetchBody,
    })
      .then(r => r.json())
      .then(json => {
        clearTimeout(fallback);
        finish(json.success
          ? json.data.roast
          : 'The roast engine hit a snag — but your resume probably needed the break.');
      })
      .catch(() => {
        clearTimeout(fallback);
        finish('Something went sideways. Your resume was so mid it broke the server.');
      });

    return () => clearTimeout(fallback);
  }, []);

  return (
    <NoiseBg color="#0a0a09">
      <div style={{
        height: '100%', display: 'flex', flexDirection: 'column',
        justifyContent: 'center', padding: 26, paddingTop: 60,
      }}>
        <div style={{
          fontFamily: fonts.mono, fontSize: 11, color: COLOR.acid,
          letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 24,
        }}>
          ▌ROAST ENGINE RUNNING
        </div>

        <div style={{
          fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 56,
          lineHeight: 0.9, letterSpacing: '-0.045em', color: COLOR.ink,
        }}>
          cooking<br/>
          <span style={{ color: COLOR.red }}>your</span><br/>
          <span style={{ fontFamily: fonts.serif, fontStyle: 'italic', fontWeight: 400 }}>résumé.</span>
        </div>

        <div style={{ marginTop: 38 }}>
          <div style={{ height: 4, background: COLOR.ash, borderRadius: 999, overflow: 'hidden' }}>
            <div style={{
              height: '100%', width: `${pct}%`, background: COLOR.acid,
              transition: 'width 0.13s linear',
            }}/>
          </div>
          <div style={{
            marginTop: 12, fontFamily: fonts.mono, fontSize: 12,
            color: COLOR.dim, display: 'flex', justifyContent: 'space-between',
          }}>
            <span key={i} style={{ animation: 'flick 0.4s' }}>› {lines[i]}</span>
            <span>{pct.toFixed(0)}%</span>
          </div>
        </div>

        <div style={{ marginTop: 48, fontFamily: fonts.mono, fontSize: 10, color: COLOR.dim, lineHeight: 1.7 }}>
          <div>{'>'} resume.txt ✓</div>
          <div>{'>'} llm: llama-3.1-8b ✓</div>
          <div>{'>'} tone: {state.mode || 'BRUTAL'}</div>
          <div>{'>'} max_sympathy: 0.04</div>
          <div style={{ color: COLOR.acid }}>{'>'} status: SEND IT</div>
        </div>
      </div>
    </NoiseBg>
  );
}

// ─── 4. EMAIL GATE ───────────────────────────────────────────────────────────
function ScreenEmail({ go }) {
  const [email, setEmail] = React.useState('');
  const ok = /\S+@\S+\.\S+/.test(email);
  return (
    <NoiseBg>
      <div style={{ padding: '54px 20px 0' }}>
        <div style={{
          fontFamily: fonts.mono, fontSize: 11, color: COLOR.acid,
          letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 14,
        }}>
          ▌ROAST READY
        </div>
        <h2 style={{
          fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 50,
          lineHeight: 0.88, letterSpacing: '-0.045em', margin: 0,
        }}>
          one last<br/>
          thing.
        </h2>
        <p style={{ marginTop: 16, fontSize: 15, lineHeight: 1.4, color: '#cfcbbc' }}>
          Where should we send your <em style={{ fontFamily: fonts.serif }}>reality check?</em>
          <br/>
          <span style={{ color: COLOR.dim, fontSize: 13 }}>(We'll also email the roast so you can cry about it later.)</span>
        </p>
      </div>

      <div style={{ padding: '24px 20px 0' }}>
        <div style={{
          background: COLOR.smoke, border: `1px solid ${COLOR.ash}`,
          borderRadius: 14, padding: '4px 14px',
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <span style={{ fontFamily: fonts.mono, color: COLOR.acid, fontSize: 14 }}>@</span>
          <input
            value={email} onChange={e => setEmail(e.target.value)}
            placeholder="you@aboutto.cry"
            style={{
              flex: 1, padding: '16px 0', background: 'transparent',
              border: 'none', outline: 'none', color: COLOR.ink,
              fontFamily: fonts.body, fontSize: 16,
            }}
          />
        </div>

        <button
          onClick={() => ok && go('roast')}
          disabled={!ok}
          style={{
            width: '100%', marginTop: 14, padding: 20, border: 'none',
            background: ok ? COLOR.acid : COLOR.ash,
            color: ok ? COLOR.bg : COLOR.dim,
            borderRadius: 18, cursor: ok ? 'pointer' : 'not-allowed',
            fontFamily: fonts.display, fontWeight: 700, fontSize: 20,
            boxShadow: ok ? `0 18px 40px -18px ${COLOR.acid}aa` : 'none',
          }}>
          show me the damage →
        </button>
        <p style={{
          marginTop: 10, fontFamily: fonts.mono, fontSize: 10,
          color: COLOR.dim, lineHeight: 1.6, textAlign: 'center',
        }}>
          no spam. no recruiters. just one email when you<br/>
          inevitably come back for the rewrite.
        </p>
      </div>

      <div style={{ padding: '28px 20px', marginTop: 20 }}>
        <div style={{
          border: `1px dashed ${COLOR.ash}`, padding: 14, borderRadius: 12,
          display: 'flex', gap: 12, alignItems: 'center',
        }}>
          <div style={{
            width: 38, height: 38, borderRadius: 10, flexShrink: 0,
            background: COLOR.red, display: 'flex', alignItems: 'center',
            justifyContent: 'center', fontSize: 18,
          }}>🔒</div>
          <div style={{ fontSize: 12, color: COLOR.dim, lineHeight: 1.45 }}>
            Your resume is encrypted, never trained on, and deleted after 30 days.
            <br/>The trauma, however, is forever.
          </div>
        </div>
      </div>
    </NoiseBg>
  );
}

// ─── 5. ROAST REVEAL ─────────────────────────────────────────────────────────
function splitRoast(text) {
  if (!text) return [];
  const parts = text.split(/\n\n+/).filter(p => p.trim());
  if (parts.length >= 2) return parts;
  const sentences = text.match(/[^.!?]+[.!?]+\s*/g) || [text];
  const third = Math.ceil(sentences.length / 3);
  return [
    sentences.slice(0, third).join(''),
    sentences.slice(third, third * 2).join(''),
    sentences.slice(third * 2).join(''),
  ].filter(p => p.trim());
}

function ScreenRoast({ go, state }) {
  const roastText = (state && state.roast) || '';
  const parasRef = React.useRef([]);
  const paras = React.useMemo(() => {
    const result = splitRoast(roastText);
    parasRef.current = result;
    return result;
  }, [roastText]);

  const [revealed, setRevealed] = React.useState([0, 0, 0]);

  React.useEffect(() => {
    if (!parasRef.current.length) return;
    setRevealed(Array(parasRef.current.length).fill(0));
    const tick = (i) => {
      const p = parasRef.current;
      if (!p[i]) return;
      setRevealed(r => {
        if (r[i] >= p[i].length) {
          if (i < p.length - 1) setTimeout(() => tick(i + 1), 250);
          return r;
        }
        const next = [...r];
        next[i] = Math.min(p[i].length, r[i] + 6);
        setTimeout(() => tick(i), 14);
        return next;
      });
    };
    tick(0);
  }, [roastText]);

  const score = roastText ? 20 + (roastText.length % 36) : 31;
  return (
    <NoiseBg>
      <div style={{ padding: '54px 20px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span style={{ fontFamily: fonts.mono, fontSize: 11, color: COLOR.red, letterSpacing: '0.1em' }}>
          ▌YOUR ROAST
        </span>
        <span style={{ fontFamily: fonts.mono, fontSize: 11, color: COLOR.dim }}>
          shareable ↗
        </span>
      </div>

      {/* score brick */}
      <div style={{ padding: '16px 20px 0' }}>
        <div style={{
          background: COLOR.red, color: COLOR.ink, padding: '18px 20px',
          borderRadius: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
          boxShadow: `0 20px 50px -22px ${COLOR.red}`,
        }}>
          <div>
            <div style={{ fontFamily: fonts.mono, fontSize: 10, opacity: 0.8, letterSpacing: '0.1em', textTransform: 'uppercase' }}>
              HiredAF score
            </div>
            <div style={{
              fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 64,
              lineHeight: 0.9, letterSpacing: '-0.05em', marginTop: 4,
            }}>
              {score}<span style={{ fontSize: 28, opacity: 0.6 }}>/100</span>
            </div>
          </div>
          <div style={{ textAlign: 'right', fontFamily: fonts.serif, fontStyle: 'italic', fontSize: 22, opacity: 0.95 }}>
            {VOICE.scoreLabel}
          </div>
        </div>
      </div>

      {/* paragraphs */}
      <div style={{ padding: '20px 20px 0' }}>
        {paras.length === 0 ? (
          <div style={{ padding: 16, background: COLOR.smoke, border: `1px solid ${COLOR.ash}`, borderRadius: 14 }}>
            <div style={{ fontFamily: fonts.mono, fontSize: 12, color: COLOR.acid, letterSpacing: '0.1em' }}>loading roast...</div>
          </div>
        ) : paras.map((p, i) => (
          <div key={i} style={{
            marginBottom: 14, padding: 16,
            background: COLOR.smoke, border: `1px solid ${COLOR.ash}`,
            borderRadius: 14,
          }}>
            <div style={{
              fontFamily: fonts.mono, fontSize: 10, color: COLOR.acid,
              letterSpacing: '0.1em', marginBottom: 8,
            }}>
              › PARAGRAPH 0{i+1}
            </div>
            <p style={{
              margin: 0, fontFamily: fonts.serif, fontSize: 18,
              lineHeight: 1.32, color: COLOR.ink, fontWeight: 400,
              minHeight: 80,
            }}>
              {p.slice(0, revealed[i] || 0)}
              {(revealed[i] || 0) < p.length && <span style={{ color: COLOR.acid }}>▍</span>}
            </p>
          </div>
        ))}
      </div>

      {/* sticky CTA */}
      <div style={{ padding: '8px 20px 100px' }}>
        <div style={{
          background: `linear-gradient(180deg, transparent, ${COLOR.bg} 30%)`,
          paddingTop: 20,
        }}>
          <button onClick={() => go('paywall')} style={{
            width: '100%', padding: '22px', border: 'none',
            background: COLOR.acid, color: COLOR.bg, borderRadius: 18,
            fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 22,
            letterSpacing: '-0.02em', cursor: 'pointer',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            boxShadow: `0 24px 50px -20px ${COLOR.acid}`,
          }}>
            <span>{VOICE.ctaFix}</span>
            <span style={{ fontFamily: fonts.mono, fontSize: 11, background: COLOR.bg, color: COLOR.acid, padding: '4px 8px', borderRadius: 6 }}>
              $4.99
            </span>
          </button>
          <div style={{ display: 'flex', gap: 6, marginTop: 10, justifyContent: 'center' }}>
            <ShareChip icon="↗" label="share roast" />
            <ShareChip icon="↻" label="roast again" />
          </div>
        </div>
      </div>
    </NoiseBg>
  );
}

function ShareChip({ icon, label }) {
  return (
    <button style={{
      background: 'transparent', border: `1px solid ${COLOR.ash}`,
      color: COLOR.dim, padding: '8px 12px', borderRadius: 999,
      fontFamily: fonts.mono, fontSize: 11, letterSpacing: '0.05em',
      cursor: 'pointer', display: 'flex', gap: 6, alignItems: 'center',
    }}>
      <span style={{ color: COLOR.acid }}>{icon}</span>{label}
    </button>
  );
}

// ─── 6. PAYWALL ──────────────────────────────────────────────────────────────
function ScreenPaywall({ go }) {
  return (
    <NoiseBg>
      <div style={{ padding: '54px 20px 0', display: 'flex', justifyContent: 'space-between' }}>
        <button onClick={() => go('roast')} style={{
          background: 'none', border: `1px solid ${COLOR.ash}`,
          color: COLOR.ink, fontFamily: fonts.mono, fontSize: 11, padding: '6px 10px',
          borderRadius: 8, letterSpacing: '0.06em', cursor: 'pointer',
        }}>← BACK</button>
        <span style={{ fontFamily: fonts.mono, fontSize: 11, color: COLOR.dim }}>
          checkout · 1 of 2
        </span>
      </div>

      <div style={{ padding: '20px 20px 0' }}>
        <h2 style={{
          fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 44,
          lineHeight: 0.9, letterSpacing: '-0.045em', margin: 0,
        }}>
          unlock the<br/>
          <span style={{ fontFamily: fonts.serif, fontStyle: 'italic', fontWeight: 400, color: COLOR.acid }}>
            real one.
          </span>
        </h2>
      </div>

      {/* blurred preview */}
      <div style={{ padding: '20px 20px 0', position: 'relative' }}>
        <div style={{
          background: COLOR.ink, color: COLOR.bg, padding: 18, borderRadius: 14,
          filter: 'blur(5px)', userSelect: 'none', pointerEvents: 'none',
          fontFamily: fonts.body, height: 220, overflow: 'hidden',
        }}>
          <div style={{ fontWeight: 700, fontSize: 18 }}>JANE DOE</div>
          <div style={{ fontSize: 11, color: '#555' }}>Senior Growth Marketing · jane@email.com</div>
          <hr style={{ margin: '10px 0', borderColor: '#bbb' }}/>
          <div style={{ fontWeight: 700, fontSize: 11 }}>EXPERIENCE</div>
          <div style={{ fontSize: 10, marginTop: 4 }}>Growth Lead, AcmeCo (2023–Pres.)</div>
          <div style={{ fontSize: 9 }}>• Drove 312% MoM signup growth via 14 paid+organic experiments</div>
          <div style={{ fontSize: 9 }}>• Cut CAC 47% by rebuilding attribution stack across 6 channels</div>
          <div style={{ fontSize: 9 }}>• Owned $1.2M quarterly budget; landed 18% under at 134% target</div>
          <div style={{ fontSize: 9 }}>• Shipped lifecycle program lifting D30 retention from 22% → 41%</div>
        </div>
        <div style={{
          position: 'absolute', inset: '20px 20px 0', display: 'flex',
          alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 8,
        }}>
          <div style={{
            background: COLOR.bg, border: `1px solid ${COLOR.ash}`,
            padding: '10px 14px', borderRadius: 999,
            fontFamily: fonts.mono, fontSize: 11, color: COLOR.acid, letterSpacing: '0.08em',
          }}>
            🔒 LOCKED
          </div>
          <div style={{ fontFamily: fonts.serif, fontStyle: 'italic', fontSize: 14, color: COLOR.dim }}>
            the version that actually gets you hired
          </div>
        </div>
      </div>

      {/* what you get */}
      <div style={{ padding: '20px 20px 0' }}>
        <div style={{
          background: COLOR.smoke, border: `1px solid ${COLOR.ash}`,
          borderRadius: 14, padding: 16,
        }}>
          {[
            ['6-question AI deep dive', 'extracts metrics you forgot you had'],
            ['ATS-optimized rewrite', 'parses cleanly in every tracker'],
            ['Styled PDF + plain text', 'paste-ready for any portal'],
            ['Unlimited tweaks for 7 days', 'change roles, change tone, redo'],
          ].map(([t,s],i)=>(
            <div key={i} style={{ display: 'flex', gap: 12, padding: '10px 0', borderBottom: i<3?`1px dashed ${COLOR.ash}`:'none' }}>
              <span style={{ color: COLOR.acid, fontFamily: fonts.mono, fontSize: 12, paddingTop: 2 }}>0{i+1}</span>
              <div>
                <div style={{ fontFamily: fonts.body, fontWeight: 600, fontSize: 14, color: COLOR.ink }}>{t}</div>
                <div style={{ fontSize: 12, color: COLOR.dim, marginTop: 2 }}>{s}</div>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* checkout */}
      <div style={{ padding: '20px 20px 100px' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 12 }}>
          <div style={{ fontFamily: fonts.display, fontWeight: fonts.displayWeight, fontStyle: fonts.displayStyle, fontSize: 44, letterSpacing: '-0.04em' }}>
            $4.99
          </div>
          <div style={{ textAlign: 'right' }}>
            <div style={{ fontFamily: fonts.mono, fontSize: 10, color: COLOR.dim, textDecoration: 'line-through' }}>
              $29 lifetime
            </div>
            <div style={{ fontFamily: fonts.mono, fontSize: 10, color: COLOR.acid, letterSpacing: '0.06em' }}>
              FOUNDERS PRICE · 312 LEFT
            </div>
          </div>
        </div>
        <button onClick={() => go('hero')} style={{
          width: '100%', padding: 22, border: 'none',
          background: COLOR.red, color: COLOR.ink, borderRadius: 18,
          fontFamily: fonts.display, fontWeight: 700, fontSize: 20,
          letterSpacing: '-0.02em', cursor: 'pointer',
          boxShadow: `0 24px 50px -20px ${COLOR.red}`,
        }}>
          Pay $4.99 · Build my resume
        </button>
        <div style={{
          marginTop: 10, display: 'flex', justifyContent: 'center', gap: 10,
          fontFamily: fonts.mono, fontSize: 10, color: COLOR.dim,
        }}>
          <span>🍎 Pay</span><span>·</span><span>G Pay</span><span>·</span><span>Card</span><span>·</span><span>Stripe</span>
        </div>
      </div>
    </NoiseBg>
  );
}

// expose
Object.assign(window, {
  ScreenHero, ScreenPaste, ScreenRoasting, ScreenEmail, ScreenRoast, ScreenPaywall,
  COLOR, fonts, VOICE, PALETTES, FONT_THEMES, VOICE_PRESETS,
});
