// chrome.jsx — Y2K visual primitives: chrome orbs, iridescent blobs, stars, stickers const { useRef: __cr, useEffect: __ce, useState: __cs, useMemo: __cm } = React; /* ════════════════════════════════════════════════════════ CHROME ORB The signature element: a liquid metal 3D sphere ════════════════════════════════════════════════════════ */ function ChromeOrb({ size = 320, hue = 0, mouse, scrollOffset = 0, style = {}, kind = 'chrome' }) { const ref = __cr(null); const [rot, setRot] = __cs({ x: 0, y: 0 }); __ce(() => { let raf; let t = 0; const tick = () => { t += 0.4; if (mouse) { setRot({ x: (mouse.y - 0.5) * -30 + Math.sin(t * 0.01) * 4, y: (mouse.x - 0.5) * 40 + t * 0.3, }); } else { setRot({ x: Math.sin(t * 0.012) * 8, y: t * 0.2 }); } raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, [mouse]); const surfaces = { chrome: { conic: `conic-gradient(from ${rot.y}deg at 50% 50%, #1a1a24 0deg, #c8c4d8 25deg, #f8f4ff 60deg, #e8e0f0 90deg, #4a4458 130deg, #18141e 160deg, #8a8498 200deg, #f8f4ff 240deg, #b8b0c8 280deg, #2c2638 320deg, #1a1a24 360deg)`, glow: 'rgba(200, 200, 220, 0.4)', }, iridescent: { conic: `conic-gradient(from ${rot.y}deg at 50% 50%, #FF3EA5 0deg, #9D5BFF 45deg, #4361FF 90deg, #2DD4FF 135deg, #C8FF3E 180deg, #FFD93E 225deg, #FF6B1A 270deg, #FF3EA5 315deg, #FF3EA5 360deg)`, glow: 'rgba(255, 100, 200, 0.6)', }, warm: { conic: `conic-gradient(from ${rot.y}deg at 50% 50%, #3a2820 0deg, #d9b8a0 45deg, #fff5e8 90deg, #f0d4b8 130deg, #6b4838 180deg, #b08568 220deg, #fff5e8 270deg, #d9b8a0 315deg, #3a2820 360deg)`, glow: 'rgba(255, 180, 130, 0.5)', }, azure: { conic: `conic-gradient(from ${rot.y}deg at 50% 50%, #0a1a3a 0deg, #4361FF 45deg, #b8d0ff 90deg, #f0f8ff 130deg, #2DD4FF 180deg, #b8eeff 220deg, #4361FF 270deg, #0a1a3a 315deg, #0a1a3a 360deg)`, glow: 'rgba(67, 97, 255, 0.5)', }, lime: { conic: `conic-gradient(from ${rot.y}deg at 50% 50%, #1a2a0a 0deg, #C8FF3E 45deg, #f0ffb8 90deg, #fff8b8 130deg, #88c020 180deg, #d4f060 220deg, #C8FF3E 270deg, #1a2a0a 315deg, #1a2a0a 360deg)`, glow: 'rgba(200, 255, 60, 0.5)', }, }; const s = surfaces[kind] || surfaces.chrome; return (
{/* Outer glow */}
{/* Main orb */}
{/* Specular highlight 1 */}
{/* Specular highlight 2 — small bright */}
{/* Bottom shadow rim */}
); } /* ════════════════════════════════════════════════════════ IRIDESCENT BLOB — organic shape with hue-shift fill ════════════════════════════════════════════════════════ */ function IridescentBlob({ size = 200, style = {}, hue = 0 }) { // Asymmetric organic borderRadius const [phase, setPhase] = __cs(0); __ce(() => { let raf; let t = 0; const tick = () => { t += 0.5; setPhase(t); raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, []); const r1 = 50 + Math.sin(phase * 0.02) * 12; const r2 = 50 - Math.sin(phase * 0.02) * 12; const r3 = 50 + Math.cos(phase * 0.018) * 14; const r4 = 50 - Math.cos(phase * 0.018) * 14; return (
{/* Highlight */}
); } /* ════════════════════════════════════════════════════════ ROTATING STICKER (Y2K badge) ════════════════════════════════════════════════════════ */ function ChromeSticker({ text, size = 160, color = 'lime' }) { // Generate text along a circle const chars = text.split(''); const angleStep = 360 / chars.length; return (
{text + ' · ' + text + ' · '}
); } /* ════════════════════════════════════════════════════════ STARBURST — classic Y2K star ════════════════════════════════════════════════════════ */ function Star({ size = 40, color, style = {} }) { return ( ); } /* ════════════════════════════════════════════════════════ HOLO CARD — iridescent border + glassy fill ════════════════════════════════════════════════════════ */ function HoloCard({ children, style = {}, className = '' }) { return (
{children}
); } /* ════════════════════════════════════════════════════════ 3D MORPHING SHAPE — different per service ════════════════════════════════════════════════════════ */ function MorphShape({ kind = 'sphere', size = 200, mouse, hue = 0 }) { const [t, setT] = __cs(0); __ce(() => { let raf; let n = 0; const tick = () => { n += 0.5; setT(n); raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, []); if (kind === 'sphere') { return ; } if (kind === 'torus') { return (
); } if (kind === 'cube') { return (
{['front', 'back', 'right', 'left', 'top', 'bottom'].map((face, i) => { const half = size / 2; const transforms = { front: `translateZ(${half}px)`, back: `rotateY(180deg) translateZ(${half}px)`, right: `rotateY(90deg) translateZ(${half}px)`, left: `rotateY(-90deg) translateZ(${half}px)`, top: `rotateX(90deg) translateZ(${half}px)`, bottom: `rotateX(-90deg) translateZ(${half}px)`, }; return (
); })}
); } if (kind === 'blob') { return ; } if (kind === 'cylinder') { return (
); } return null; } /* ════════════════════════════════════════════════════════ ASTERISK BADGE — logo principal (versión 05) 8 brazos negros con núcleo iridiscente que gira suave. ════════════════════════════════════════════════════════ */ function AsteriskBadge({ size = 320, spin = true, animateCore = true, style = {}, strokeColor }) { const [phase, setPhase] = __cs(0); __ce(() => { if (!animateCore && !spin) return; let raf; let t = 0; const tick = () => { t += 0.4; setPhase(t); raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, [spin, animateCore]); const stroke = strokeColor || 'var(--ink)'; const armW = size * 0.085; const armL = size * 0.42; const coreR = size * 0.13; return (
{/* 8 brazos: 0°, 45°, 90°, 135° (cada uno cruza por el centro) */} {[0, 45, 90, 135].map(deg => ( ))} {/* Núcleo iridiscente */}
{/* Brillo especular del núcleo */}
); } /* ════════════════════════════════════════════════════════ ASTERISK MARK — versión compacta (nav / favicon / footer) Gira suave por defecto. ════════════════════════════════════════════════════════ */ function AsteriskMark({ size = 32, strokeColor, spin = true }) { const stroke = strokeColor || 'var(--ink)'; const sw = size * 0.16; const uid = __cm(() => Math.random().toString(36).slice(2, 8), []); return ( {[0, 45, 90, 135].map(deg => ( ))} ); } /* ════════════════════════════════════════════════════════ ASTERISK STICKER — asterisco + texto orbitando Reemplaza al ChromeSticker. Texto gira alrededor, asterisco independiente en el centro con núcleo iridiscente. ════════════════════════════════════════════════════════ */ /* ════════════════════════════════════════════════════════ Y2K BADGE — sticker circular giratorio (versión canónica 04) Anillo grueso oscuro, texto blanco orbitando, núcleo iridiscente ════════════════════════════════════════════════════════ */ function Y2KBadge({ text = 'MULTIPLES · MEDIOS · STUDIO · MMXXVI', size = 180, dark = true, className = '' }) { const uid = __cm(() => 'y2k-' + Math.random().toString(36).slice(2, 8), []); // Tamaño efectivo según viewport: todo (badge + esfera + halo) escala junto const [vw, setVw] = __cs(typeof window !== 'undefined' ? window.innerWidth : 1024); __ce(() => { const onResize = () => setVw(window.innerWidth); window.addEventListener('resize', onResize, { passive: true }); return () => window.removeEventListener('resize', onResize); }, []); const effSize = vw <= 360 ? Math.min(size, 84) : vw <= 480 ? Math.min(size, 100) : vw <= 720 ? Math.min(size, 124) : size; const ring = dark ? '#0E0B14' : '#FFF8EC'; const ink = dark ? '#FFF8EC' : '#0E0B14'; const coreSize = effSize * 0.30; // esfera = 30 % del badge, en todos los tamaños // Path circumference: 2π · 78 ≈ 490.088 en viewBox 200×200 // textLength=490 + lengthAdjust=spacingAndGlyphs estira el texto para // cubrir el anillo exactamente UNA vuelta, sin solapado "MULTIPLESMULTIPLES". return (
{text} {/* Esfera iridiscente al centro */}
); } /* Esfera iridiscente compacta para el Y2K badge */ function IridescentSphere({ size = 80 }) { const [phase, setPhase] = __cs(0); __ce(() => { let raf; let t = 0; const tick = () => { t += 0.6; setPhase(t); raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, []); return (
{/* Halo */}
{/* Esfera */}
{/* Brillo especular */}
); } function AsteriskSticker({ text = 'MULTIMEDIA · STUDIO · 2026 · ', size = 160, strokeColor }) { const uid = __cm(() => 'as-' + Math.random().toString(36).slice(2, 8), []); const stroke = strokeColor || 'var(--ink)'; return (
{/* Anillo + texto orbitando (rota) */} {text + text} {/* Asterisco en el centro (gira independiente) */}
); } /* ════════════════════════════════════════════════════════ STACKED MASSIVE — wordmark audaz (versión 06) "MULTIPLES" condensado negro encima de "medios." cursiva degradado azul→tangerine. Decorativo, no clickable. ════════════════════════════════════════════════════════ */ function StackedMassive({ size = 'clamp(80px, 14vw, 240px)', align = 'center', variant = 'light', // 'light' (ink sobre cream) | 'dark' (chrome sobre ink) animated = true, // anima el fondo iridiscente detrás style = {} }) { const isDark = variant === 'dark'; const topClass = isDark ? 'chrome-text' : ''; return (
{/* Fondo iridiscente animado sutil */} {animated && ( ); } Object.assign(window, { ChromeOrb, IridescentBlob, ChromeSticker, Star, HoloCard, MorphShape, AsteriskBadge, AsteriskMark, AsteriskSticker, StackedMassive, Y2KBadge, IridescentSphere });