// HERO — key visual, title, CTA, character select
const { useState: useStateHe, useEffect: useEffectHe } = React;
const CHARACTERS = [
{
id: "neon",
codename: "GAIA LOVE",
kana: "ガイア・ラブ",
set: "TECHNO // EDM",
accent: "var(--magenta)",
tag: "HIGH BPM · CLUB CORE",
palette: "linear-gradient(135deg, oklch(0.4 0.25 340), oklch(0.25 0.2 300))",
bpm: 138,
stats: { Energy: 98, Hype: 94, Drop: 100, Aura: 88 },
},
{
id: "crimson",
codename: "CRIMSON GAIA",
kana: "クリムゾン・ガイア",
set: "ROCK // METAL",
accent: "var(--danger)",
tag: "RAW POWER · HEAVY",
palette: "linear-gradient(135deg, oklch(0.42 0.22 20), oklch(0.22 0.12 350))",
bpm: 156,
stats: { Energy: 100, Hype: 91, Drop: 96, Aura: 95 },
},
{
id: "sakura",
codename: "SAKURA GAIA",
kana: "サクラ・ガイア",
set: "J-POP // SYNTH",
accent: "var(--rose)",
tag: "DREAM · KAWAII CORE",
palette: "linear-gradient(135deg, oklch(0.55 0.18 10), oklch(0.35 0.16 320))",
bpm: 120,
stats: { Energy: 86, Hype: 99, Drop: 82, Aura: 100 },
},
];
function useMadridClock() {
const [t, setT] = useStateHe(() => new Date());
useEffectHe(() => {
const i = setInterval(() => setT(new Date()), 1000);
return () => clearInterval(i);
}, []);
// Eorzea-offset: Madrid time minus 2 hours
const shifted = new Date(t.getTime() - 2 * 60 * 60 * 1000);
const hm = shifted.toLocaleTimeString("en-GB", {
hour: "2-digit", minute: "2-digit",
hour12: false, timeZone: "Europe/Madrid",
});
return hm;
}
function Hero() {
const [charIx, setCharIx] = useStateHe(0);
const char = CHARACTERS[charIx];
const clock = useMadridClock();
return (
SYS.ONLINE · EORZEA TIME {clock}
{/* Title block */}
CHAPTER 01 · THE ANIME MADE DJ
アニメメイド · ディージェイ
DJ GAIA
WOAH!
//
WORLD
EORZEA TOUR · 2026
Half Romanian, half Japanese. Raised on Roblox decks and GTA radios, now spinning across every data center in Final Fantasy XIV. Techno, EDM, rock, metal — all made with heart, chaos and a lil' bit of pure anime energy. Woah!
{/* Inline music player — fills the gap under meta row */}
{window.HeroPlayer &&
}
{/* Key visual */}
{/* Character select */}
// SELECT SET
0{charIx + 1}/0{CHARACTERS.length}
{CHARACTERS.map((c, i) => (
setCharIx(i)}
style={{
...styles_hero.charBtn,
borderColor: i === charIx ? c.accent : "var(--panel-stroke)",
background: i === charIx ? c.palette : "oklch(0.1 0.04 300 / 0.5)",
boxShadow: i === charIx ? `0 0 24px ${c.accent}` : "none",
}}>
{c.codename.split(" ")[0]}
{c.set}
))}
);
}
function MetaCell({ label, value, kana }) {
return (
{label.toUpperCase()}
{value}
{kana}
);
}
function KeyVisual({ char }) {
return (
{/* Glow */}
{/* Art */}
{/* Radial rings */}
{/* Scanline overlay */}
{/* Gradient wash */}
{/* Kana across */}
UNIT 01
{char.codename}
{char.kana}
{/* Stat overlay bottom */}
{Object.entries(char.stats).map(([k, v]) => (
))}
);
}
const styles_hero = {
wrap: {
display: "grid",
gridTemplateColumns: "1.05fr 1fr",
gap: 64,
padding: "60px 0 40px",
position: "relative",
minHeight: "calc(100vh - 80px)",
},
floatTag: { position: "absolute", top: 20, right: 0 },
titleCol: { display: "flex", flexDirection: "column", justifyContent: "center", gap: 32 },
preTitle: {},
bigTitle: { display: "flex", flexDirection: "column", gap: 4 },
kanaTop: { fontSize: 14, color: "var(--cyan)", letterSpacing: "0.3em", marginBottom: 12 },
line1: { fontSize: "clamp(64px, 9vw, 140px)", lineHeight: 0.95, letterSpacing: "0.01em" },
line2: { fontSize: "clamp(40px, 5.5vw, 80px)", lineHeight: 1, letterSpacing: "0.02em" },
line3: { fontSize: "clamp(14px, 1.2vw, 18px)", marginTop: 18, color: "var(--ink-dim)" },
blurb: { fontSize: 17, lineHeight: 1.55, color: "var(--ink-dim)", maxWidth: 560, textWrap: "pretty" },
ctaRow: { display: "flex", gap: 16, flexWrap: "wrap" },
metaRow: { display: "flex", gap: 0, marginTop: 8, borderTop: "1px solid var(--panel-stroke)", paddingTop: 20 },
visualCol: { display: "flex", flexDirection: "column", gap: 24, justifyContent: "center" },
kvWrap: { position: "relative" },
selectRow: {},
charGrid: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12 },
charBtn: {
textAlign: "left",
padding: 10,
cursor: "pointer",
border: "1px solid var(--panel-stroke)",
color: "var(--ink)",
transition: "all .2s ease",
fontFamily: "inherit",
},
};
Object.assign(window, { Hero });