// CircadianClock — interactive 24h MTC clock with real-time needle
// Same logic as WuClock Landing.html clock, restyled with liquid-glass.
const { useEffect: clkUseEffect, useRef: clkUseRef, useState: clkUseState } = React;
const { motion: clkMotion } = window.Motion;
// MTC organs assigned to even-hour 2-hour blocks, starting at midnight (top), clockwise.
const MTC_DATA = [
{ start: 0, organ: 'Hígado', element: 'Madera', color: '#4CAF50',
body: 'El hígado detoxifica la sangre — momento más crítico del día.',
todo: 'Dormí. Despertarse con tensión a esta hora sugiere hígado sobrecargado.' },
{ start: 2, organ: 'Pulmón', element: 'Metal', color: '#9E9E9E',
body: 'El pulmón reparte oxígeno y energía a todo el cuerpo.',
todo: 'Sueño profundo. Si te despertás triste a esta hora, tu pulmón pide aire.' },
{ start: 4, organ: 'Intestino Grueso', element: 'Metal', color: '#9E9E9E',
body: 'Eliminás lo que tu cuerpo ya no necesita.',
todo: 'Vaso de agua tibia al levantarte. Ir al baño tranquilo.' },
{ start: 6, organ: 'Estómago', element: 'Tierra', color: '#FF9800',
body: 'Tu estómago está en pico de energía digestiva.',
todo: 'Desayuno tibio y nutritivo. La comida más importante de tu día.' },
{ start: 8, organ: 'Bazo', element: 'Tierra', color: '#FF9800',
body: 'El bazo transforma lo que comiste en energía utilizable.',
todo: 'Trabajo concentrado. Tu mente está afilada para tareas complejas.' },
{ start: 10, organ: 'Corazón', element: 'Fuego', color: '#F44336',
body: 'Tu corazón irriga al máximo — pico de claridad mental.',
todo: 'Decisiones importantes, conversaciones difíciles, movimiento social.' },
{ start: 12, organ: 'Intestino Delgado', element: 'Fuego', color: '#F44336',
body: 'Separás lo nutritivo de lo que va a descartarse.',
todo: 'Almuerzo principal. Después, evitá decisiones grandes — bajada natural.' },
{ start: 14, organ: 'Vejiga', element: 'Agua', color: '#2196F3',
body: 'Tu cuerpo procesa líquidos y elimina toxinas residuales.',
todo: 'Hidratarte bien. Buen momento para movimiento moderado o estudio.' },
{ start: 16, organ: 'Riñón', element: 'Agua', color: '#2196F3',
body: 'El riñón restaura tu reserva energética profunda.',
todo: 'Bajar el ritmo. Cena temprana, conversación tranquila.' },
{ start: 18, organ: 'Pericardio', element: 'Fuego', color: '#F44336',
body: 'Protege tu corazón — energía emocional al frente.',
todo: 'Tiempo con personas que querés. Intimidad. Sin pantallas si podés.' },
{ start: 20, organ: 'Triple Calentador', element: 'Fuego', color: '#F44336',
body: 'Tu cuerpo regula temperatura y se prepara para dormir.',
todo: 'Bajá la luz, té tibio, respiración. Estás cerrando el día.' },
{ start: 22, organ: 'Vesícula Biliar', element: 'Madera', color: '#4CAF50',
body: 'Tu cuerpo descompone grasas y procesa decisiones del día.',
todo: 'Dormí profundo. Cenar temprano y luz tenue ayudan a regenerar.' },
];
function polar(angDeg, r) {
const a = (angDeg - 90) * Math.PI / 180;
return { x: r * Math.cos(a), y: r * Math.sin(a) };
}
function arcPath(startDeg, endDeg, rIn, rOut) {
const p1 = polar(startDeg, rOut);
const p2 = polar(endDeg, rOut);
const p3 = polar(endDeg, rIn);
const p4 = polar(startDeg, rIn);
const large = (endDeg - startDeg) > 180 ? 1 : 0;
return [
`M ${p1.x} ${p1.y}`,
`A ${rOut} ${rOut} 0 ${large} 1 ${p2.x} ${p2.y}`,
`L ${p3.x} ${p3.y}`,
`A ${rIn} ${rIn} 0 ${large} 0 ${p4.x} ${p4.y}`,
'Z',
].join(' ');
}
function getCurrentIdx(now = new Date()) {
const h = now.getHours();
for (let i = 0; i < MTC_DATA.length; i++) {
const s = MTC_DATA[i].start;
const e = (s + 2) % 24;
if (s > e) {
if (h >= s || h < e) return i;
} else {
if (h >= s && h < e) return i;
}
}
return 0;
}
function fmtTime(d) {
return String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');
}
const R_OUTER = 180;
const R_INNER = 115;
function CircadianClock() {
const [now, setNow] = clkUseState(() => new Date());
const [hoverIdx, setHoverIdx] = clkUseState(null);
clkUseEffect(() => {
const tick = () => setNow(new Date());
const id = setInterval(tick, 1000);
return () => clearInterval(id);
}, []);
const currentIdx = getCurrentIdx(now);
const shownIdx = hoverIdx !== null ? hoverIdx : currentIdx;
const shown = MTC_DATA[shownIdx];
// User's exact formula: angle measured with 0° = east (3 o'clock),
// -90° puts midnight at the top. Drive the needle endpoint via cos/sin
// so the math matches the formula 1-to-1 (no SVG rotate offset).
const totalHoras = now.getHours() + now.getMinutes() / 60 + now.getSeconds() / 3600;
const angulo = (totalHoras / 24) * 360 - 90;
const aRad = angulo * Math.PI / 180;
const needleLen = R_OUTER - 32;
const needleX = needleLen * Math.cos(aRad);
const needleY = needleLen * Math.sin(aRad);
// Tail (opposite side, very short) for the back of the needle
const tailLen = 6;
const tailX = -tailLen * Math.cos(aRad);
const tailY = -tailLen * Math.sin(aRad);
const [secRef, secShown] = useInViewOnce(0.15);
// Build hour ticks
const hourTicks = [];
for (let h = 0; h < 24; h++) {
const deg = h * 15;
const major = h % 6 === 0;
const p1 = polar(deg, R_INNER - 4);
const p2 = polar(deg, R_INNER - (major ? 14 : 8));
hourTicks.push(
// Reloj circadiano
{shown.body}
{shown.todo}
WuClock lo traduce.
{shown.organ}