// Screens: Onboarding, Upload, Scoring animation function OnboardingScreen({ platform, onNext, score }) { return (
{/* aura blobs bg */}
RESUME ✦ AURA
hi, I'm Auri
I'll read your resume and tell you what's working, what's not, and what to fix — in 30 seconds flat.
content, not looks no visual judgments honest feedback
Read my resume
); } function UploadScreen({ platform, onNext }) { const [hovered, setHovered] = React.useState(false); return (
{}}/>
drop your resume
PDF, DOCX, or paste the text.
{/* upload area */}
tap to browse files
or drop from Files / Drive
or
{/* Source options */}
{[ { label: 'iCloud', bg: '#4dd6ff' }, { label: 'Drive', bg: '#fae14b' }, { label: 'Dropbox', bg: '#8a5cf6' }, { label: 'Paste text', bg: '#b7f0cd' }, ].map(s => ( ))}
{/* Recent */}
recently scored
{[70, 90, 50, 80, 40].map((w, i) =>
)}
Jordan_Resume_v4.pdf
2 days ago · score 68
analyze
); } function ScanningScreen({ platform, onDone }) { const [step, setStep] = React.useState(0); const steps = [ 'reading the words...', 'checking action verbs...', 'hunting for buzzwords...', 'measuring impact...', 'computing aura...', ]; React.useEffect(() => { if (step < steps.length - 1) { const t = setTimeout(() => setStep(s => s + 1), 650); return () => clearTimeout(t); } else { const t = setTimeout(onDone, 800); return () => clearTimeout(t); } }, [step]); return (
reading...
{steps[step]}
{/* progress bar */}
); } function ScoreRevealScreen({ platform, onEdit, onShare, onExport, score, variant }) { const [showContent, setShowContent] = React.useState(false); React.useEffect(() => { const t = setTimeout(() => setShowContent(true), 800); return () => clearTimeout(t); }, []); const verdict = score >= 85 ? 'legendary' : score >= 70 ? 'strong' : score >= 50 ? 'mid' : score >= 30 ? 'rough' : 'cooked'; const verdictCopy = { legendary: { title: 'legendary aura', sub: 'chef\'s kiss. Some bullets need seasoning, but this slaps.', color: '#fae14b' }, strong: { title: 'strong vibes', sub: 'real bones here. A few buzzwords and we\'re cooking.', color: '#b7f0cd' }, mid: { title: 'mid aura', sub: 'solid base, but the metrics are ghosting us.', color: '#4dd6ff' }, rough: { title: 'rough patch', sub: 'lots to fix — but that\'s why I\'m here.', color: '#ff8a7a' }, cooked: { title: 'cooked', sub: 'deep breaths. we\'re rebuilding from the bullets up.', color: '#ff4db8' }, }[verdict]; const breakdown = [ { label: 'action verbs', val: Math.max(20, score - 15), max: 100 }, { label: 'quantified impact', val: Math.max(15, score - 28), max: 100 }, { label: 'clarity', val: Math.min(95, score + 8), max: 100 }, { label: 'completeness', val: Math.min(90, score + 3), max: 100 }, ]; const issueCount = allIssues().length; return (
{}} dark right={} />
{showContent && (
{verdictCopy.title}
{verdictCopy.sub}
)}
{/* issues counter */}
{issueCount}
issues to fix
each one drops your aura
{/* issue type breakdown */}
{['verb', 'metric', 'passive', 'vague', 'tense', 'missing'].map(t => { const n = allIssues().filter(i => i.type === t).length; if (!n) return null; return
{ISSUE_META[t].label} {n}
; })}
{/* breakdown */}
breakdown
{breakdown.map(b => (
{b.label}
= 70 ? 'linear-gradient(90deg, #b7f0cd, #5ac77f)' : b.val >= 40 ? 'linear-gradient(90deg, #fae14b, #e5c71a)' : 'linear-gradient(90deg, #ff8a7a, #ff4db8)', transition: 'width 1s' }}/>
{b.val}
))}
{/* actions */}
fix my resume
export share rescan
); } Object.assign(window, { OnboardingScreen, UploadScreen, ScanningScreen, ScoreRevealScreen });