// FRZN — sections (i18n aware) const { useState, useEffect, useRef } = React; // Scroll reveal hook const useReveal = (stagger = false) => { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) { el.classList.add('in'); io.unobserve(el); } }, { threshold: 0.15 }); el.classList.add(stagger ? 'reveal-stagger' : 'reveal'); io.observe(el); return () => io.disconnect(); }, []); return ref; }; const Reveal = ({ children, stagger, as: As = 'div', ...rest }) => { const ref = useReveal(stagger); return {children}; }; // render array headline with italic accent words const renderTitle = (arr, accentIdx = [1]) => arr.map((w, i) => accentIdx.includes(i) ? {w}{' '} : {w}{' '} ); // ------------ HERO ------------ const Hero = ({ t, copyKey, onWaitlist }) => { const [waterTemp, setWaterTemp] = useState(4); useEffect(() => { const id = setInterval(() => { setWaterTemp(x => Math.max(1.5, Math.min(6.5, x + (Math.random() - 0.5) * 0.4))); }, 1600); return () => clearInterval(id); }, []); const h = t.hero.headline[copyKey]; const eyebrow = t.hero.eyebrow[copyKey]; const sub = t.hero.sub[copyKey]; const markerPos = `${Math.min(100, Math.max(0, (waterTemp / 30) * 100))}%`; const accentIdx = copyKey === 'thermal' ? 1 : copyKey === 'vitality' ? 5 : 1; return (
{t.hero.metaSpec}{t.hero.metaSpecV}
{t.hero.metaCond}{t.hero.metaCondV}
{t.hero.metaTarget}{t.hero.metaTargetV}
{t.hero.metaRelease}{t.hero.metaReleaseV}
{eyebrow}

{h.map((w, i) => { if (i === accentIdx) return {w} ; if (i === 4 && copyKey === 'thermal') return {w} ; return {w} ; })}

{sub}

{t.hero.prop1Title}

{t.hero.prop1}

{t.hero.prop2Title}

{t.hero.prop2}

FR-001 / SHORTS
THERMAL CAPTURE · 3.2 μm
REV 04
{waterTemp.toFixed(1)}°C AMB
{t.liveLabel} · THERMAL READ{waterTemp.toFixed(1)}°C · CLASS III
0°C10°C20°C30°C
); }; // ------------ SECTION HEAD ------------ const SectionHead = ({ num, label, title, accentIdx = [1] }) => (
§ {num}{label}

{renderTitle(title, accentIdx)}

); // ------------ SCIENCE ------------ const Science = ({ t }) => (
{t.science.cards.map((c, i) => (
{c.stat[0]}{c.stat.slice(1)}
{c.title}

{c.copy}

{c.cite}
))}
); // ------------ MECHANISM ------------ const Mechanism = ({ t }) => { const [active, setActive] = useState(3); return (
{t.mech.layers.map((l, i) => (
setActive(i)}> {l[0]}
{l[1]}
{l[2]}
))}
); }; // ------------ PRODUCT CARD ------------ const ProductCard = ({ product, onAdd, lang, t }) => { const [size, setSize] = useState(product.sizes.find(s => !product.unavailable.includes(s))); const [added, setAdded] = useState(false); const Thermal = window[product.visual]; const handleAdd = () => { onAdd({ ...product, size }); setAdded(true); setTimeout(() => setAdded(false), 1200); }; const title = product.name; const tagline = product.tagline[lang] || product.tagline.en; const desc = product.desc[lang] || product.desc.en; return (
{product.id} · REV 04
{product.thermal} · {product.gsm}
{tagline}{product.lat}

{title}

{desc}

{product.sizes.map(s => ( ))}
{product.was && €{product.was}}€{product.price}
{t.products.stock}
); }; // ------------ PRODUCTS ------------ const Products = ({ t, lang, onAdd }) => { const top3 = CATALOG.slice(0, 3); return (
{top3.map(p => )}
{t.products.refillTitle}

{t.products.refill}

{t.products.provTitle}

{t.products.prov}

{t.products.supplyMap}
); }; // ------------ RITUAL ------------ const Ritual = ({ t }) => (
{t.ritual.phases.map((p, i) => (
{t.ritual.phase} {p[0]}
{p[2]}C
{p[1]}
{p[4]}

{p[3]}

))}
); // ------------ AMBASSADORS ------------ const Ambassadors = ({ t }) => (
{t.field.quotes.map((q, i) => (

{q[0]}

{q[1]}{q[2]}
))}
{['Men\u2019s Health','GQ','Monocle','WIRED','Kinfolk','Hypebeast'].map(n => ({n}))}
); // ------------ GUARANTEE ------------ const Guarantee = ({ t }) => (
§ 06{t.guarantee.title.toUpperCase()}

{t.guarantee.title}

{t.guarantee.items.map((g, i) => (
{['60','∞','↻','−CO₂'][i]}
{g[0]}

{g[1]}

))}
); // ------------ SPECS ------------ const Specs = ({ t }) => (
{t.specs.rows.map((r, i) => (
{r[0]}
{r[1]}
{r[2]}
{r[3]}
))}
); // ------------ FAQ ------------ const FAQ = ({ t }) => { const [open, setOpen] = useState(0); return (
{t.faq.items.map((it, i) => (
{it[1]}
))}
); }; // ------------ WAITLIST ------------ const Waitlist = ({ t, onSubmit }) => { const [email, setEmail] = useState(''); return (

{renderTitle(t.waitlist.title, [1])}

{t.waitlist.sub}

{ e.preventDefault(); onSubmit(email); setEmail(''); }}> setEmail(e.target.value)} />
{t.waitlist.reserved}{t.waitlist.left}
); }; // ------------ FOOTER ------------ const Footer = ({ t }) => ( ); Object.assign(window, { Hero, Science, Mechanism, Products, Ritual, Ambassadors, Guarantee, Specs, FAQ, Waitlist, Footer, ProductCard, useReveal, Reveal, renderTitle, SectionHead });