/* global React */
const { useState, useEffect, useRef } = React;
// =============== HERO ===============
function Hero({ t, photos }) {
const [activeIdx, setActiveIdx] = useState(0);
const [progress, setProgress] = useState(0);
const [timecode, setTimecode] = useState("00:00:00:00");
// Pool of photo indices we use as the rotating "video" tiles
const pool = [0, 4, 7, 12, 18, 22, 25, 9, 15];
const tiles = [pool[activeIdx % pool.length], pool[(activeIdx+1) % pool.length], pool[(activeIdx+2) % pool.length]];
useEffect(() => {
const start = Date.now();
const id = setInterval(() => {
const elapsed = (Date.now() - start) / 1000;
const cycle = elapsed % 4;
setProgress((cycle / 4) * 100);
const totalFrames = Math.floor(elapsed * 24);
const f = totalFrames % 24;
const s = Math.floor(elapsed) % 60;
const m = Math.floor(elapsed / 60) % 60;
const h = Math.floor(elapsed / 3600);
setTimecode(
`${String(h).padStart(2,"0")}:${String(m).padStart(2,"0")}:${String(s).padStart(2,"0")}:${String(f).padStart(2,"0")}`
);
}, 42);
return () => clearInterval(id);
}, []);
useEffect(() => {
const id = setInterval(() => setActiveIdx(i => i + 1), 4000);
return () => clearInterval(id);
}, []);
return (
{t.hero.eyebrow}
· {t.hero.tag2}
{t.hero.headline1}
{t.hero.headline2} {t.hero.headline3}
);
}
// =============== MARQUEE ===============
function Marquee({ t }) {
const items = ["CINEMATIC FILM", "BRAND STORYTELLING", "REELS · VERTICAL", "COLOR & POST", "EDITORIAL PHOTOGRAPHY", "ZURICH · BERN · WORLDWIDE"];
return (
{[...items, ...items, ...items].map((it, i) => {it})}
);
}
// =============== WORK ===============
function Work({ t, photos, work }) {
return (
{t.work.eyebrow}
{t.work.title} {t.work.titleOutline}
{t.work.meta.map((m,i)=>
{m}
)}
{work.map((w,i) => (
{w.tag}
{w.title}
{w.meta}
{w.duration}
))}
);
}
// =============== SERVICES ===============
function Services({ t }) {
return (
{t.services.eyebrow}
{t.services.title} {t.services.titleOutline}
05 · CAPABILITIES
ALL INCLUDED
{t.services.list.map((s,i) => (
0{i+1} /
{s.name}
{s.desc}
{s.tags.map((tg,j)=> {tg})}
→
))}
);
}
// =============== ABOUT ===============
function About({ t, photos }) {
return (
{t.about.tag}
{t.about.eyebrow}
{t.about.title}
{t.about.titleAccent}
{t.about.p1}
{t.about.p2}
{t.about.stats.map((s,i) => (
{s.num.includes("+") ? <>{s.num.replace("+","")}+> : {s.num}}
{s.label}
))}
);
}
// =============== PROCESS ===============
function Process({ t }) {
return (
{t.process.eyebrow}
{t.process.title} {t.process.titleOutline}
04 · STEPS
FROM BRIEF TO FINAL CUT
{t.process.steps.map((s,i) => (
{s.num}
{s.h}
{s.p}
{s.icon}
))}
);
}
// =============== CLIENTS + TESTIMONIALS ===============
function Clients({ t }) {
return (
{t.clients.eyebrow}
{t.clients.title} {t.clients.titleOutline}
12 · PARTNERS
2024 — 2026
{t.clients.logos.map((l,i) =>
{l}
)}
{t.clients.testimonials.map((tt,i) => (
))}
);
}
// =============== CTA ===============
function CTA({ t }) {
return (
{t.cta.bgText}
{t.cta.eyebrow}
{t.cta.headline1}
{t.cta.headline2} {t.cta.headlineAccent}
{t.cta.sub}
{t.cta.contact.map((c,i) => (
))}
);
}
// =============== FOOTER ===============
function Footer({ t }) {
return (
);
}
// =============== NAV ===============
function Nav({ t, lang, setLang, theme, setTheme }) {
return (
);
}
Object.assign(window, { Hero, Marquee, Work, Services, About, Process, Clients, CTA, Footer, Nav });