"use client"; import React from "react"; import { vipnagorgialla } from "@/components/Vipnagorgialla"; import Image from "next/image"; import Link from "next/link"; import { useTranslations } from "next-intl"; import { useState } from "react"; import { developers, universities } from "@/data/expo"; /** Thick semi-transparent cyan rule that separates the full-bleed sections. */ const DIVIDER = "border-t-4 border-[rgba(0,163,224,0.5)]"; /** Horizontal padding used by the padded sections (64px at the design width). */ const GUTTER = "px-6 md:px-16"; /** Map Modal Component */ function MapModal({ onClose, imageSrc, label, rotateMessage }: { onClose: () => void; imageSrc: string; label: string; rotateMessage: string }) { return (
{/* Container for the map image - only shown in landscape */}
e.stopPropagation()}>
{label}
{/* Portrait warning with border - only shown in portrait on small screens */}
e.stopPropagation()}> {rotateMessage}
); } /** Client component for the maps section with modal functionality */ function MapsSection({ gutter }: { gutter: string }) { const t = useTranslations(); const [selectedMap, setSelectedMap] = useState<{ image: string; label: string } | null>(null); React.useEffect(() => { if (selectedMap) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = ""; } return () => { document.body.style.overflow = ""; }; }, [selectedMap]); const maps = [ { image: "/images/messiala/fuajee-kaart.svg", label: t("expo.mapFoyer") }, { image: "/images/messiala/tudengimaja-kaart.svg", label: t("expo.mapStudentHouse") }, ]; return ( <>
{maps.map((map) => ( ))}
{selectedMap && ( setSelectedMap(null)} imageSrc={selectedMap.image} label={selectedMap.label} rotateMessage={t("expo.rotateDevice")} /> )} ); } /** Venue map card: the map SVG rendered transparent over the page background. */ function MapCard({ image, label }: { image: string; label: string }) { return (
{label}
); } /** * Photo tile in the gallery band: the image is faded over the dark background * (as in the design) with a large caption. Caption alignment is configurable so * the middle tile can sit bottom-right like the mockup. */ function FadedPhoto({ image, caption, align = "left", valign = "center", }: { image: string; caption: string; align?: "left" | "right"; valign?: "center" | "bottom"; }) { return (

{caption}

); } /** Skewed section heading (no rule underneath — sections are split by DIVIDER). */ function SectionHeading({ children }: { children: React.ReactNode }) { return (

{children}

); } /** * One showcase card: a cyan-bordered logo box above a linked title and a * studio/team line. Logos render object-contain; screenshots (`cover`) fill the * box. Teams without a logo yet fall back to their name set inside the box. */ function GameCard({ image, title, subtitle, url, cover = false, }: { image?: string; title: string; subtitle: string; url?: string; cover?: boolean; }) { const titleEl = url ? ( {title} ) : ( {title} ); return (
{image ? ( {title} ) : ( {title} )}
{titleEl} {subtitle}
); } export default function Expo() { const t = useTranslations(); return (
{/* Page title */}

{t("expo.title")}

{/* Venue maps */} {/* Mini-tournaments feature (full-bleed) */}

{t("expo.miniTournaments.title")}

{t("expo.miniTournaments.description")}

{/* Photo gallery: two faded tiles left, one tall faded tile right, separated by thin cyan gaps (the band background shows through). */}
{/* Estonian game developers */}
{t("expo.developers")}
{developers.map((dev) => ( ))}
{/* Universities */}
{t("expo.universities")}
{universities.map((uni) => ( ))}
); }