);
}
function SplitLine({ text, className = "", delayOffset = 0 }) {
// wrap each char in a span with .split-line for animation
const chars = [...text];
return (
{chars.map((c, i) =>
{c === " " ? " " : c}
)}
);
}
function PlayIcon({ size = 18 }) {
return (
);
}
function ArrowIcon() {
return (
);
}
// Generic cinematic placeholder for project videos
function VideoStill({ label, timecode = "00:00:14:21", duration = "00:18", tone = 0, aspect = "16/10" }) {
// tone shifts hue slightly so cards feel different
const hueShift = [0, -8, 6, -14, 12, 0][tone % 6];
const baseStyle = {
aspectRatio: aspect,
filter: `hue-rotate(${hueShift}deg)`
};
return (
{label &&
REC ● {label}
}
{timecode}
);
}
function SpinBadge({ text = "QUE MARA! • QUE MARA! • ", size = 140, color = "var(--color-dark)" }) {
// svg with text on circle
const radius = size / 2 - 12;
const id = "tp-" + Math.random().toString(36).slice(2, 8);
return (
);
}
function Footer() {
const [tc, setTc] = useState("00:00:00:00");
useEffect(() => {
// marca o início da sessão (persiste entre navegações até fechar a aba)
let start = Number(sessionStorage.getItem("mara-session-start"));
if (!start) {
start = Date.now();
sessionStorage.setItem("mara-session-start", String(start));
}
const tick = () => {
const elapsed = Date.now() - start;
const totalSec = Math.floor(elapsed / 1000);
const hh = String(Math.floor(totalSec / 3600)).padStart(2, "0");
const mm = String(Math.floor((totalSec % 3600) / 60)).padStart(2, "0");
const ss = String(totalSec % 60).padStart(2, "0");
const ff = String(Math.floor((elapsed % 1000) / 1000 * 24)).padStart(2, "0"); // 24fps
setTc(`${hh}:${mm}:${ss}:${ff}`);
};
tick();
const id = setInterval(tick, 1000 / 12); // 12hz suficiente pro frame piscar
return () => clearInterval(id);
}, []);
return (
);
}
function IntroOverlay({ onDone }) {
const [gone, setGone] = useState(false);
useEffect(() => {
// only on first visit per session
if (sessionStorage.getItem("mara-intro-played")) {
setGone(true);
onDone && onDone();
return;
}
const t = setTimeout(() => {
setGone(true);
sessionStorage.setItem("mara-intro-played", "1");
onDone && onDone();
}, 2400);
return () => clearTimeout(t);
}, []);
return (
MARA
);
}
// scroll-trigger fade-up for elements with .fade-up
function useFadeUp() {
useEffect(() => {
const els = document.querySelectorAll(".fade-up");
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {if (e.isIntersecting) e.target.classList.add("in");});
}, { threshold: 0.15 });
els.forEach((el) => io.observe(el));
return () => io.disconnect();
}, []);
}
Object.assign(window, {
Grain, Nav, Footer, IntroOverlay,
SplitLine, PlayIcon, ArrowIcon, VideoStill, SpinBadge,
useFadeUp
});