/* results.jsx — interactive before/after slider */ const CASES = [ { id: 1, title: "Acné severo", meta: "Protocolo médico · varias sesiones", before: "rose", after: "champagne", beforeSrc: "assets/acne-antes.jpeg", afterSrc: "assets/acne-despues.jpeg", desc: "Tratamiento médico del acné severo y sus secuelas con un protocolo personalizado: control de los brotes, regulación de la piel y mejora visible de la textura y las marcas. Recuperamos una piel más sana, uniforme y luminosa." }, { id: 2, title: "Tricología", meta: "Plan personalizado · seguimiento", before: "bone", after: "rose", beforeSrc: "assets/tricologia-antes.jpg", afterSrc: "assets/tricologia-despues.jpeg", desc: "Diagnóstico clínico y tratamiento de la caída del cabello. Con un plan a la medida frenamos la pérdida, recuperamos densidad y devolvemos fuerza y salud al cuero cabelludo, con resultados visibles y progresivos." }, { id: 3, title: "Rinomodelación", meta: "Sesión única · cada año", before: "mocha", after: "bone", beforeSrc: "assets/rinomodelacion-antes.jpeg", afterSrc: "assets/rinomodelacion-despues.jpeg", desc: "Armonización no quirúrgica del perfil nasal con ácido hialurónico. Corrige asimetrías y refina la proyección de la nariz sin cirugía ni tiempos de recuperación." }, { id: 4, title: "Diseño de labios", meta: "Sesión única · cada 8 meses", before: "bone", after: "rose", beforeSrc: "assets/labios-antes.jpeg", afterSrc: "assets/labios-despues.jpeg", desc: "Hidratación, contorno y volumen sutil con técnica de capas finas. Realzamos la forma natural de los labios buscando proporción y un acabado armónico." }, { id: 5, title: "Toxina botulínica", meta: "Sesión única · cada 6 meses", before: "champagne", after: "bone", beforeSrc: "assets/botox-antes.jpeg", afterSrc: "assets/botox-despues.jpeg", desc: "Aplicación de toxina botulínica con dosis personalizada para suavizar líneas de expresión. Una mirada descansada que conserva la naturalidad de tus gestos." }, ]; function Results() { const [active, setActive] = useState(0); const [pos, setPos] = useState(50); const [animating, setAnimating] = useState(false); const stageRef = useRef(null); const draggingRef = useRef(false); const animTimers = useRef([]); const c = CASES[active]; const clearAnim = useCallback(() => { animTimers.current.forEach(clearTimeout); animTimers.current = []; }, []); const setFromClient = useCallback((clientX) => { const r = stageRef.current?.getBoundingClientRect(); if (!r) return; const x = Math.max(0, Math.min(1, (clientX - r.left) / r.width)); setPos(x * 100); }, []); useEffect(() => { const onMove = (e) => { if (!draggingRef.current) return; const cx = e.touches ? e.touches[0].clientX : e.clientX; setFromClient(cx); }; const onUp = () => { draggingRef.current = false; }; window.addEventListener("mousemove", onMove); window.addEventListener("touchmove", onMove, { passive: true }); window.addEventListener("mouseup", onUp); window.addEventListener("touchend", onUp); return () => { window.removeEventListener("mousemove", onMove); window.removeEventListener("touchmove", onMove); window.removeEventListener("mouseup", onUp); window.removeEventListener("touchend", onUp); }; }, [setFromClient]); // Auto-animate on case change: glide slowly left↔right a couple of times, // then settle in the center. The CSS transition (gated by .ba-animating) // makes each move smooth instead of teleporting. useEffect(() => { clearAnim(); setAnimating(true); setPos(18); animTimers.current = [ setTimeout(() => setPos(82), 650), setTimeout(() => setPos(18), 1300), setTimeout(() => setPos(82), 1950), setTimeout(() => setPos(50), 2600), setTimeout(() => setAnimating(false), 3250), ]; return clearAnim; }, [active, clearAnim]); const startDrag = (e) => { clearAnim(); setAnimating(false); draggingRef.current = true; const cx = e.touches ? e.touches[0].clientX : e.clientX; setFromClient(cx); }; return (
Antes & Después

Resultados
en pacientes reales.

Arrastra el círculo para deslizar entre el antes y el después. Casos publicados con autorización expresa de las pacientes.

Caso #{String(c.id).padStart(2, "0")}

{c.title}

{c.desc}

{CASES.map((cc, i) => (
setActive(i)} > {cc.title} {cc.meta}
))}
Antes Después
); } Object.assign(window, { Results });