// ── COMPONENTS ────────────────────────────────────────────────────────── const { useState, useEffect, useRef, useCallback } = React; // ── Custom cursor with glitch trail ──────────────────────────────────── function Cursor({ enabled }) { const dotRef = useRef(null); const trailRef = useRef(null); const [glitches, setGlitches] = useState([]); useEffect(() => { if (!enabled) return; document.body.classList.add('cursor-on'); let raf; const pos = { x: -100, y: -100 }; const trail = { x: -100, y: -100 }; const onMove = (e) => { pos.x = e.clientX;pos.y = e.clientY; const tgt = e.target; const link = tgt && tgt.closest && tgt.closest('a, button, [role="button"], .rel-card, .rel-row, .artist-card, .shop-item, .menu-list li'); if (dotRef.current) { dotRef.current.classList.toggle('over-link', !!link); } // sprinkle occasional glitch token if (Math.random() < 0.04) { const txt = ['x', '>', '//', 'err', '01', 'SOK', '▌', '░', '╳', '{}', '??', '!!', '◌'][Math.floor(Math.random() * 13)]; const id = Math.random().toString(36).slice(2); const dx = (Math.random() - 0.5) * 80; const dy = (Math.random() - 0.5) * 80; setGlitches((g) => [...g, { id, x: e.clientX + dx, y: e.clientY + dy, txt }]); setTimeout(() => setGlitches((g) => g.filter((it) => it.id !== id)), 380); } }; const tick = () => { trail.x += (pos.x - trail.x) * 0.18; trail.y += (pos.y - trail.y) * 0.18; if (dotRef.current) { dotRef.current.style.transform = `translate3d(${pos.x}px, ${pos.y}px, 0)`; } if (trailRef.current) { trailRef.current.style.transform = `translate3d(${trail.x}px, ${trail.y}px, 0)`; } raf = requestAnimationFrame(tick); }; window.addEventListener('mousemove', onMove); raf = requestAnimationFrame(tick); return () => { window.removeEventListener('mousemove', onMove); cancelAnimationFrame(raf); document.body.classList.remove('cursor-on'); }; }, [enabled]); if (!enabled) return null; return (
{glitches.map((g) =>
{g.txt}
)}
); } // ── Edge chrome (MENU, CONTACT, marker, etc.) ───────────────────────── function EdgeChrome({ page, setPage, openMenu, currentLabel }) { const isHome = page === 'home'; const [scrolled, setScrolled] = React.useState(false); React.useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 60); onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); return ( {!isHome &&
[ SHI O KIKU ]
internet label · krd · est 2024
}
{page === 'events' ? ( ) : ( )}
{isHome && (
demos
booking book@shiokiku.ru
)} {isHome && (
{currentLabel} / next show 20.06 · kazan
)}
); } // ── Marquee ──────────────────────────────────────────────────────────── function Marquee({ items, position = 'top' }) { const seq = [...items, ...items, ...items]; return (
{seq.map((it, i) => {it} / )}
); } // ── Menu overlay ────────────────────────────────────────────────────── function MenuOverlay({ open, onClose, page, setPage }) { useEffect(() => { const onKey = (e) => {if (e.key === 'Escape') onClose();}; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [onClose]); return (

// navigate

// the label

shi o kiku [ 死を聞く / "to hear death" ] is an internet label and community based in krasnodar, ru. we release trashwave, breakcore, sextrance and hypertrance — no genres are sacred, only the bpm is.

demos: demo@shiokiku.ru
booking: book@shiokiku.ru
tg: @shiokiku

mmxxiv — mmxxvi · all rights wrong

); } // ── Release modal ───────────────────────────────────────────────────── function ReleaseModal({ release, onClose }) { useEffect(() => { const onKey = (e) => {if (e.key === 'Escape') onClose();}; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [onClose]); if (!release) return null; return (
e.stopPropagation()}>
{release.glyph}
[ {release.cat} ] · {release.genre}

{release.title}

by {release.artists.join(' & ')}
release {release.date} format digital · vinyl tracks {release.tracks.length}
{release.tracks.map((tr, i) =>
{String(i + 1).padStart(2, '0')} {tr.t} {tr.d}
)}
); } // ── Tweaks panel (custom for this site) ─────────────────────────────── function SOKTweaks({ tweaks, setTweak }) { return ( setTweak('theme', v)} /> setTweak('cursor', v)} /> setTweak('grain', v)} /> setTweak('halftone', v)} /> ); } Object.assign(window, { Cursor, EdgeChrome, Marquee, MenuOverlay, ReleaseModal, SOKTweaks });