>
);
};
const GOALS = [
{ id: "muscle", icon: "◆", label: "Build muscle", sub: "Train harder. Recover faster." },
{ id: "weight", icon: "▼", label: "Lose weight", sub: "Quiet cravings. Move the scale." },
{ id: "skin", icon: "✿", label: "Fix your skin", sub: "Calm redness. Smooth texture." },
{ id: "hair", icon: "❋", label: "Grow your hair", sub: "Wake sleeping follicles." },
{ id: "energy", icon: "✦", label: "More energy", sub: "Stop needing the second coffee." },
{ id: "sleep", icon: "☾", label: "Sleep deeper", sub: "Wake up actually rested." },
{ id: "brain", icon: "▲", label: "Think smarter", sub: "Sharper focus. Calmer mood." },
{ id: "longevity", icon: "∞", label: "Age slower", sub: "Look 30 at 40." },
{ id: "libido", icon: "♥", label: "More drive", sub: "Reignite the spark." },
];
const StepGoals = ({ value = [], onChange }) => {
const toggle = (id) => onChange(value.includes(id) ? value.filter(v => v !== id) : [...value, id].slice(-3));
return (
<>
02 / 08 · Pick up to 3
What do you want different in 90 days?
No wrong answers — just your honest list.
{GOALS.map(g => (
toggle(g.id)}>
{g.icon}
{g.label}
{g.sub}
))}
>
);
};
const StepSelfie = ({ value, onChange }) => {
const [scanning, setScanning] = React.useState(false);
const [done, setDone] = React.useState(!!value);
const start = () => {
setScanning(true);
setTimeout(() => { setScanning(false); setDone(true); onChange({ captured: true }); }, 2400);
};
return (
<>
03 / 08 · Optional · Not stored
Snap a selfie.
A soft-light read of skin, eye area, and vitality cues. We use it as a fun visual signal — not a diagnostic. Skip if you'd rather not.
{scanning &&
}
RGB · 24-BIT
● REC
{done ? "✓ ANALYZED" : scanning ? "SCANNING…" : "ALIGN FACE"}
{done ? "✓ Captured" : scanning ? "Scanning…" : "Capture"}
{ setDone(true); onChange({ skipped: true }); }}>
Skip
>
);
};
const FEEL = [
{ id: "energy", label: "Energy day-to-day", low: "Drained", high: "Wired" },
{ id: "sleep", label: "Sleep quality", low: "Wrecked", high: "Restorative" },
{ id: "recovery", label: "Post-workout recovery", low: "Days", high: "Hours" },
{ id: "mood", label: "Mood & focus", low: "Foggy", high: "Locked-in" },
{ id: "drive", label: "Drive / libido", low: "Flat", high: "Roaring" },
];
const StepFeel = ({ value = {}, onChange }) => {
const get = (id) => value[id] ?? 5;
return (
<>
04 / 08 · Be honest
How do you feel right now?
1 = ground floor. 10 = peak. We calibrate from here.
{FEEL.map(f => {
const v = get(f.id);
return (
);
})}
>
);
};
const TRAIN = [
{ id: "elite", mark: "◆", label: "Elite", sub: "5+ days, programmed" },
{ id: "regular", mark: "▲", label: "Regular", sub: "3–4 days a week" },
{ id: "casual", mark: "●", label: "Casual", sub: "1–2 days, mixed" },
{ id: "none", mark: "○", label: "Just walking", sub: "Building back up" },
];
const StepTraining = ({ value, onChange }) => (
<>
05 / 08 · Movement profile
How are you training?
Stack intensity scales to your load.
{TRAIN.map(o => (
onChange(o.id)}>
{o.mark}
))}
>
);
const VICES = [
{ id: "drink", icon: "◇", label: "Alcohol", sub: "More than I'd like" },
{ id: "screen", icon: "▢", label: "Late screens", sub: "Scrolling past midnight" },
{ id: "stress", icon: "≈", label: "Chronic stress", sub: "Always wired" },
{ id: "sugar", icon: "✕", label: "Sugar / refined", sub: "Cravings rule" },
{ id: "smoke", icon: "~", label: "Nicotine", sub: "Vape, smoke, pouch" },
{ id: "sedentary", icon: "—", label: "Mostly sitting", sub: "Desk-bound days" },
];
const StepVices = ({ value = [], onChange }) => {
const toggle = (id) => onChange(value.includes(id) ? value.filter(v => v !== id) : [...value, id]);
return (
<>
06 / 08 · No judgment
What's blocking your peak?
Pick everything that applies. We adjust the protocol around it.
{VICES.map(v => (
toggle(v.id)}>
{v.icon}
{v.label}
{v.sub}
))}
>
);
};
const StepBasics = ({ value = {}, onChange }) => {
const sex = value.sex;
const age = value.age ?? 32;
return (
<>
07 / 08 · Calibration data
A few basics.
Sex and age shape baseline hormone curves.
Sex assigned at birth
{["female", "male", "intersex"].map(s => (
onChange({ ...value, sex: s })}>
{s}
))}
>
);
};
const StepEmail = ({ value = "", onChange }) => (
<>
08 / 08 · Where to send your blueprint
Reveal the protocol.
We'll email a copy of your stack + 12-week timeline. No spam, ever.
onChange(e.target.value)}
style={{
width: "100%", boxSizing: "border-box", padding: "18px 20px",
background: "var(--paper-2)", border: "1.5px solid var(--paper-3)",
borderRadius: "var(--r-md)", fontSize: 16, fontFamily: "inherit", color: "var(--ink)",
marginTop: 8,
}}
/>
✓
I understand BioReveal is a fit-finder, not medical advice. A licensed clinician reviews every order before fulfillment.
>
);
// StepSelfie is the legacy fake-scan; StepVitals (in bioreveal-vitals.jsx) is the real rPPG one.
window.BR_STEPS = window.BR_STEPS || {};
Object.assign(window.BR_STEPS, { StepIntro, StepGoals, StepSelfie, StepFeel, StepTraining, StepVices, StepBasics, StepEmail });