// site-home.jsx — hi-fi V2 homepage. // Award colours by strand const AWARD_COLORS = { Fiction: "var(--pink)", Documentary: "var(--purple)", Animation: "var(--yellow)", Experimental: "var(--cyan)", Audience: "#F0EEE9" }; const AWARD_TEXT = { Fiction: "#fff", Documentary: "#fff", Animation: "#16151a", Experimental: "#16151a", Audience: "#16151a" }; const STRAND_ORDER = ["Fiction", "Documentary", "Animation", "Experimental"]; // Abbreviate director names: "Charlie Ledwidge, Harley Hunt" → "C. Ledwidge, H. Hunt" const abbrevName = (n) => { const p = n.trim().split(/\s+/); return p.length <= 1 ? n.trim() : p[0][0] + ". " + p.slice(1).join(" "); }; const abbrevDirectors = (str) => { if (!str) return ""; return str.split(/,\s*|\s+and\s+/).map(abbrevName).join(", "); }; function fmtFilmRuntime(film) { const m = parseInt(film.runtime) || 0; const s = parseInt(film.runtimeSecs) || 0; if (!m && !s) return ""; return s ? m + "′" + String(s).padStart(2, "0") + "″" : m + "′"; } function Home({ navigate }) { const d = useSite(); const f = d.festival; const films = usePublishedFilms(); const news = usePublishedNews(); const schedule = d.schedule || []; // Winners derived from prize field on current-edition films const currentFilms = films.filter(film => film.year === f.year); const audienceWinner = currentFilms.find(film => film.prize === "Audience"); const strandWinners = STRAND_ORDER .map(strand => currentFilms.find(film => film.prize === "Jury" && film.strand === strand)) .filter(Boolean); // Homepage copy with graceful fallbacks for older data const quote = f.quote || "Short film is the cinema of attention — what you can hold, completely, in twenty minutes."; const winnersHeading = f.pastWinnersHeading || "Past Winners."; const awardsDesc = f.awardsDesc || "The Paper Bird Awards honour the best short films across five categories — Fiction, Documentary, Animation, Experimental, and Audience Choice. Each winner receives a handmade Paper Bird trophy, colour-coded to their strand, created by artist Dave Treadwell."; const ctaTickets = { enabled: true, eyebrow: "For audiences", title: "Reserve your seat.", body: "All eight nights are free with RSVP. Awards Night at SCALE is ticketed.", cta: "Get tickets", ...(f.ctaTickets || {}) }; const ctaSubmit = { enabled: true, eyebrow: "For filmmakers", title: "Submit for Edition VII.", body: "We accept short films across all four strands from students at film schools worldwide.", cta: "Submission guidelines", ...(f.ctaSubmit || {}) }; return ( {/* ── HERO — full-bleed video, text overlaid ── */}
{/* ── VOTING BANNER ── shown only when voting is open */} {f.votingOpen && (
{/* pixel texture overlay */}
)} {/* ── SIX NIGHTS ── */}

The schedule.

{f.ticketsEnabled !== false && navigate("/tickets")}>Venues & tickets }
{schedule.map((day, i) => { const isOff = day.strand === "Off-night"; const accent = { Opening: "var(--yellow)", Documentary: "var(--purple)", Animation: "var(--yellow)", Experimental: "var(--cyan)", Fiction: "var(--pink)", Awards: "var(--pink)" }[day.strand] || "var(--ink)"; return (
{day.date}
{day.title}
{!isOff &&
{day.time} · {day.strand}
}
); })}
{/* ── EDITION TRAILER ── */} {f.trailerYouTube &&
{f.trailerSectionLabel || "Sixth Edition · Official Trailer"}
{f.trailerEyebrow || "LJMUMASFF · 2026"}

{f.trailerHeading || "Watch the trailer."}

{f.trailerBody || "Four strands. Forty-one films. Six nights across Liverpool. The sixth edition of the LJMU MA Short Film Festival."}

} {/* ── PAST WINNERS ── */}
Paper Bird Award Sixth Edition

{winnersHeading}

navigate("/programme")} style={{ color: "var(--paper)" }}>All {films.length} films
{audienceWinner &&
{/* Audience Award — large card */}
navigate("/film/" + audienceWinner.id)}>
Audience Award Winner
Audience Award Winner {fmtFilmRuntime(audienceWinner)}
{audienceWinner.title}
{audienceWinner.directors} · {audienceWinner.country}
{/* Awards description block */}

{awardsDesc}

{/* Strand winners — grid */}
{strandWinners.map((film, i) =>
navigate("/film/" + film.id)}>
{film.strand
{film.strand} Winner {fmtFilmRuntime(film)}
{film.title}
{film.directors} · {film.country}
)}
}
{/* ── EDITORIAL QUOTE ── */}
From the Journal

"{quote}"

{news.slice(0, 3).map((n) => { const coverImg = (n.cover) || (window.firstBlockImage && window.firstBlockImage(n)); return (
navigate("/news/" + n.id)} style={{ cursor: "pointer" }}> {coverImg ?
{n.title}
: }
{n.category}{fmtDate(n.date)}
{n.title}
By {n.author}
); })}
{/* ── CTA ── */} {((f.ticketsEnabled !== false && ctaTickets.enabled !== false) || ctaSubmit.enabled !== false) && (
{f.ticketsEnabled !== false && ctaTickets.enabled !== false && navigate("/tickets")} bg={ctaTickets.bg || f.accentColor || "var(--pink)"} />} {ctaSubmit.enabled !== false && navigate("/submit")} bg={ctaSubmit.bg || f.accentColor2 || "var(--purple)"} />}
)}
); } function CtaCard({ eyebrow, title, body, cta, onClick, solid, bg }) { const fill = bg || (solid ? "var(--pink)" : null); return (
{eyebrow}
{title}

{body}

); } function fmtDate(s) { if (!s) return ""; const [y, m, dd] = s.split("-"); const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; return `${dd} ${months[(+m || 1) - 1]} ${y}`; } Object.assign(window, { Home, CtaCard, fmtDate });