// desidium-sections-b.jsx — Roster, Cases, Contact, Footer const { useState: useStateB } = React; /* ---------------- ROSTER (gallery) ---------------- */ function Roster({ lang, motion, columns, onOpen }) { const r = I18N.roster; const [filter, setFilter] = useStateB("all"); const filters = [["all",r.filters.all],["twin",r.filters.twin],["soul",r.filters.soul]]; const shown = MODELS.filter((m) => filter==="all" ? true : m.div===filter); return (
{L(r.label,lang)}

{L(r.title,lang)}

{filters.map(([k,lab]) => ( ))}
{shown.map((m, i) => ( ))}
); } /* ---------------- CASES ---------------- */ function Cases({ lang, motion }) { const c = I18N.cases; return (
{L(c.label,lang)}

{L(c.title,lang)}

{CASES.map((cs, i) => (
{cs.no} {L(cs.client,lang)}

{L(cs.title,lang)}

{L(cs.body,lang)}

{cs.metric} {L(cs.metricLabel,lang)}
))}
); } /* ---------------- CONTACT ---------------- */ function Contact({ lang, motion }) { const k = I18N.contact; const [form, setForm] = useStateB({ name:"", brand:"", email:"", interest:"twin", msg:"" }); const [errors, setErrors] = useStateB({}); const [state, setState] = useStateB("idle"); // idle | sending | sent const set = (f) => (e) => setForm({ ...form, [f]: e.target.value }); const submit = (e) => { e.preventDefault(); const er = {}; ["name","email","msg"].forEach((f) => { if (!form[f].trim()) er[f] = true; }); if (form.email && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.email)) er.email = true; setErrors(er); if (Object.keys(er).length) return; setState("sending"); setTimeout(()=>setState("sent"), 1100); }; const opts = [["twin",k.opt_twin],["soul",k.opt_soul],["b2b",k.opt_b2b],["other",k.opt_other]]; return (
{L(k.label,lang)}

{L(k.title1,lang)}
{L(k.title2,lang)}

{L(k.sub,lang)}

{L(k.studio,lang)}
Calle Sintética 24
Madrid · 28004
studio@desidium.ai
{state==="sent" ? (

{L(k.sent_t,lang)}

{L(k.sent_d,lang)}

) : (
{errors.name && {L(k.err,lang)}}
{errors.email && {L(k.err,lang)}}
{opts.map(([v,lab]) => ( ))}
{errors.msg && {L(k.err,lang)}}
)}
); } /* ---------------- FOOTER ---------------- */ function Footer({ lang, setLang, go }) { const f = I18N.footer; const n = I18N.nav; return ( ); } Object.assign(window, { Roster, Cases, Contact, Footer });