// Sections for "VI. Bestiário" page — grimório / sketchbook spreads. // Data lives in bestiario-data.jsx (exposed as window.BESTIARY). const BESTIARY = window.BESTIARY; // ---------- Page Hero ---------- function BestiaryHero({ intensity }) { return (
Capítulo VI · As Criaturas

O Bestiário
O Legado do Fogo

Registro ilustrado das criaturas conhecidas que habitam — e ameaçam — o Grande Continente. Cada espécime foi observado em campo, capturado em esboço e descrito em linguagens antigas antes de ser arquivado neste volume.

Folheie o grimório com cautela. Algumas destas páginas foram lacradas por décadas — e por bons motivos. O que se segue não é um inventário: é um aviso.

Início / O Mundo / Bestiário
Abra o grimório
); } // ---------- Index of creatures ---------- function BestiaryIndex() { return (
Index Bestiarum {BESTIARY.length} espécimes catalogados
{BESTIARY.map((b, i) => ( { e.preventDefault(); window.dispatchEvent(new CustomEvent("bestiary:goto", { detail: { target: i } })); const el = document.getElementById("bestiary-book"); if (el) { const y = window.scrollY + el.getBoundingClientRect().top - 80; window.scrollTo({ top: y, behavior: "smooth" }); } }} > {b.numeral} {b.name} {b.epithet} ))}
); } // ---------- Slot primitive ---------- function ArtSlot({ shape = "tall", label, dropLabel = "ilustração", image, alt, fit = "cover" }) { if (image) { return (
{alt
{label && {label}}
); } return (
[ {dropLabel} ]
{label && {label}}
); } // ---------- Page halves (extracted so we can flip them independently) ---------- function CreatureLeftPage({ entry }) { const { figures, scene, sceneCaption } = entry; const figureCount = figures ? figures.length : 0; return (
); } function CreatureRightPage({ entry }) { const { anatomy } = entry; return (
); } // ---------- Book container: stacked spreads, small side arrows ---------- function BestiarySpread({ entry, index, total }) { return (
{entry.numeral} — FOLIO {String(index + 1).padStart(2, "0")} / {String(total).padStart(2, "0")} — {entry.name}
); } function BestiaryBook() { const total = BESTIARY.length; const [index, setIndex] = React.useState(0); const [animating, setAnimating] = React.useState(false); const animTimer = React.useRef(null); const go = React.useCallback((target) => { const clamped = Math.max(0, Math.min(total - 1, target)); if (clamped === index || animating) return; setIndex(clamped); setAnimating(true); if (animTimer.current) clearTimeout(animTimer.current); animTimer.current = setTimeout(() => setAnimating(false), 620); }, [index, total, animating]); React.useEffect(() => () => { if (animTimer.current) clearTimeout(animTimer.current); }, []); // keyboard nav when the book is on screen React.useEffect(() => { const onKey = (e) => { if (e.target && (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")) return; const book = document.getElementById("bestiary-book"); if (!book) return; const r = book.getBoundingClientRect(); const visible = r.bottom > 100 && r.top < window.innerHeight - 100; if (!visible) return; if (e.key === "ArrowRight") { e.preventDefault(); go(index + 1); } else if (e.key === "ArrowLeft") { e.preventDefault(); go(index - 1); } }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [go, index]); // jump from index cards React.useEffect(() => { const onJump = (e) => { const target = e.detail?.target; if (typeof target === "number") { go(target); const el = document.getElementById("bestiary-book"); if (el) { const y = window.scrollY + el.getBoundingClientRect().top - 70; window.scrollTo({ top: y, behavior: "smooth" }); } } }; window.addEventListener("bestiary:goto", onJump); return () => window.removeEventListener("bestiary:goto", onJump); }, [go]); return (
Liber Bestiarum · MMXXIV
{BESTIARY.map((entry, i) => (
))}
{/* Floating side arrows — small, do not overlap pages */}
); } // ---------- Outro ---------- function BestiaryOutro() { return (

“Conhecer a criatura é metade da espada. A outra metade — apenas a coragem forja.”

Liber Bestiarum · Epílogo
); } Object.assign(window, { BestiaryHero, BestiaryIndex, BestiaryBook, BestiaryOutro });