// ============================================================
// SECTION STORY — Scroll-driven 6-phase narrative
// • Photo + text alternating layouts (Bahan Alami / Multimanfaat / Praktis)
// • Hero certification reveal that morphs into "Yojea" + description
// • Final phase: photo slides left, purchase channels appear right
// • Background colors transition between phases via interpolation
// • SVG wave dividers replace flat horizontal section boundaries
// ============================================================
// ─── CircularSeal — a rotating "deal sticker" with curved text ──
// SVG textPath rides a hidden circle so the label loops; the
// outer wrapper spins via CSS using --spin (duration) and --dir.
function CircularSeal({ label, main, sub, style, color, bg }) {
const id = React.useId();
return (
{/* Top wave divider — organic transition from the previous section */}
{/* ─── Phases 1-3: photo + text alternating ─────────── */}
{ROWS.map((row, i) => {
const p = presence(i);
const local = phaseLocal(i);
// Direction: slide image in from its side, text from opposite
const imgFrom = row.side === 'left' ? -60 : 60;
const txtFrom = row.side === 'left' ? 60 : -60;
// Subtle parallax once peak presence is reached
const drift = (local - 0.5) * 20;
return (
0.5 ? 'auto' : 'none',
}}
aria-hidden={p < 0.5}
>
{row.kicker}
{row.kicker}
{row.title[0] && <>{row.title[0]}
>}
{row.title[1]}
{row.body}
);
})}
{/* ─── Phase 4-6: shared photo 5 that morphs ────────── */}
{(certPresence > 0 || buyPresence > 0 || cP > 0) && (
{/* Photo (stays mounted, transforms via inline style) */}

{/* Soft warm halo so the cut-out photo grounds in the bg */}
{/* Phase 4 — "Teruji & Tersertifikasi" overlay on LEFT while
the photo sits on the RIGHT. Fades out as cP crosses 0.5
(transition into the brand/buy phase). */}
04 · Kualitas
Teruji &
Tersertifikasi.
BPOM
Halal MUI
Lab Tested
{/* (Phase 5 brand block — "Yojea" + tagline — removed per spec) */}
{/* Phase 5 — Spinning certification seals overlay the photo */}
{/* Phase 5 — "Bingung Beli Yojea Dimana?" + buy channels */}
= 0.56 ? 'auto' : 'none',
}}
>
Beli Yojea
Bingung beli Yojea di mana?
Kamu bisa beli Yojea melalui distributor resmi dan platform e-commerce digital favorit kamu.
)}
{/* Phase rail — small indicator showing progress through 6 phases */}
{Array.from({ length: PHASE_COUNT }).map((_, i) => {
const active = progress >= i / PHASE_COUNT && progress < (i + 1) / PHASE_COUNT;
const passed = progress >= (i + 1) / PHASE_COUNT;
return (
{String(i + 1).padStart(2, '0')}
);
})}
{/* Bottom wave divider — into the next section */}
);
}
// ─── Helper: interpolate between two hex colors ───────────────
function mixHex(a, b, t) {
const pa = parseInt(a.slice(1), 16);
const pb = parseInt(b.slice(1), 16);
const ar = (pa >> 16) & 0xff, ag = (pa >> 8) & 0xff, ab = pa & 0xff;
const br = (pb >> 16) & 0xff, bg = (pb >> 8) & 0xff, bb = pb & 0xff;
const r = Math.round(ar + (br - ar) * t);
const g = Math.round(ag + (bg - ag) * t);
const b2 = Math.round(ab + (bb - ab) * t);
return '#' + ((1 << 24) | (r << 16) | (g << 8) | b2).toString(16).slice(1);
}
Object.assign(window, { SectionStory, CircularSeal });