// ftue.jsx — First-time user experience (90s onboarding) const { useState, useEffect, useRef } = React; function FTUE({ onFinish }) { const [step, setStep] = useState(0); const [goal, setGoal] = useState(null); const [state, setState] = useState(null); const next = () => setStep(s => s + 1); // auto-advance splash useEffect(() => { if (step === 0) { const t = setTimeout(next, 2400); return () => clearTimeout(t); } }, [step]); const screens = [ , , , , , , , , ]; return screens[step]; } // Progress dots function Dots({ n, i }) { return (
{Array.from({ length: n }).map((_, k) => (
))}
); } // 0 — Splash function Splash({ onTap }) { return (
Fitbody
AVA
“오늘은 10초만 움직여도
시작이에요.”
탭하여 계속
); } // 1 — Product promise function PromiseScreen({ onNext }) { const rows = [ { icon: 'clock', t: '10초 ~ 2분', s: '하루 한 가지, 부담 없는 행동' }, { icon: 'camera_off', t: '카메라 없이도 가능', s: '복장도 공간도 필요 없어요' }, { icon: 'flame', t: '완료하면 XP와 Streak', s: '매일의 연결이 쌓여요' }, ]; return (

Ava가 매일 하나의
건강 Quest를 정해드려요

고를 필요 없어요. 오늘 할 행동 하나면 충분해요.

{rows.map((r, i) => (
{r.t}
{r.s}
))}
시작하기
); } // Floating bottom CTA wrapper function FloatCTA({ children, hint }) { return (
{hint &&
{hint}
} {children}
); } // 2 — Goal selection function Goal({ value, setValue, onNext }) { const opts = [ { id: 'habit', label: '운동 습관 만들기', icon: 'flame' }, { id: 'fit', label: '체력 올리기', icon: 'bolt' }, { id: 'posture', label: '자세 개선', icon: 'target' }, { id: 'fatigue', label: '피로 줄이기', icon: 'leaf' }, { id: 'weight', label: '체중 관리', icon: 'dumbbell' }, { id: 'sleep', label: '수면 루틴', icon: 'moon' }, ]; return (

지금 가장 원하는
변화는 무엇인가요?

{opts.map(o => ( setValue(o.id)}/> ))}
계속
); } function BigChoice({ icon, label, active, onClick, sub }) { return ( ); } // 3 — Current state function CurState({ value, setValue, onNext }) { const opts = [ { id: '10s', label: '10초만 가능', icon: 'clock' }, { id: '1m', label: '1분 가능', icon: 'bolt' }, { id: 'tired', label: '피곤해요', icon: 'moon' }, { id: 'seated', label: '앉아서만 가능', icon: 'seat' }, ]; return (

지금 바로 할 수 있는
상태인가요?

첫 Quest를 성공시키기 위한 질문이에요.

{opts.map(o => ( setValue(o.id)}/> ))}
계속
); } // 4 — Ava first quest function FirstQuest({ onStart }) { return (
좋아요. 첫날은 성공 확률을 높이기 위해 10초짜리로 시작할게요.
FIRST QUEST
어깨 리셋 10초
굳은 목·어깨를 가볍게 풀어요
}>지금 시작
); } // 5 — First quest player (10s) function FirstPlayer({ onDone }) { return ; } // 6 — First completion function FirstDone({ onNext, onHome }) { return ( ); } // 7 — Reminder setup function Reminder({ onFinish }) { const [pick, setPick] = useState(null); const opts = [ { id: 'am', label: '아침에 알려줘', sub: '하루를 가볍게 시작', icon: 'flame' }, { id: 'noon', label: '점심에 알려줘', sub: '오후 리셋 타이밍', icon: 'bolt' }, { id: 'pm', label: '저녁에 알려줘', sub: '하루를 정리하며', icon: 'moon' }, { id: 'later', label: '나중에 설정', sub: '설정에서 언제든 변경', icon: 'gear' }, ]; return (

내일도 Ava가 10초 Quest를
보내드릴까요?

매일 같은 시간에 가볍게 알려드려요.

{opts.map(o => ( setPick(o.id)}/> ))}
{pick === 'later' ? '건너뛰고 시작' : '알림 받고 시작'}
); } Object.assign(window, { FTUE, FloatCTA, BigChoice, Dots });