feat: kamp page

This commit is contained in:
2026-04-01 14:18:07 +02:00
parent 56942275b8
commit 7b3d5461ef
5 changed files with 632 additions and 329 deletions

View File

@@ -8,7 +8,10 @@ import { Header } from "./Header";
export function SiteHeader() {
const { data: session } = authClient.useSession();
const routerState = useRouterState();
const isHomepage = routerState.location.pathname === "/";
const pathname = routerState.location.pathname;
const isHomepage = pathname === "/";
if (pathname === "/kamp") return null;
const [isVisible, setIsVisible] = useState(false);

View File

@@ -12,8 +12,8 @@ import { Route as rootRouteImport } from './routes/__root'
import { Route as TermsRouteImport } from './routes/terms'
import { Route as ResetPasswordRouteImport } from './routes/reset-password'
import { Route as PrivacyRouteImport } from './routes/privacy'
import { Route as OpenMicRouteImport } from './routes/open-mic'
import { Route as LoginRouteImport } from './routes/login'
import { Route as KampRouteImport } from './routes/kamp'
import { Route as ForgotPasswordRouteImport } from './routes/forgot-password'
import { Route as DrinkkaartRouteImport } from './routes/drinkkaart'
import { Route as ContactRouteImport } from './routes/contact'
@@ -42,16 +42,16 @@ const PrivacyRoute = PrivacyRouteImport.update({
path: '/privacy',
getParentRoute: () => rootRouteImport,
} as any)
const OpenMicRoute = OpenMicRouteImport.update({
id: '/open-mic',
path: '/open-mic',
getParentRoute: () => rootRouteImport,
} as any)
const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => rootRouteImport,
} as any)
const KampRoute = KampRouteImport.update({
id: '/kamp',
path: '/kamp',
getParentRoute: () => rootRouteImport,
} as any)
const ForgotPasswordRoute = ForgotPasswordRouteImport.update({
id: '/forgot-password',
path: '/forgot-password',
@@ -119,8 +119,8 @@ export interface FileRoutesByFullPath {
'/contact': typeof ContactRoute
'/drinkkaart': typeof DrinkkaartRoute
'/forgot-password': typeof ForgotPasswordRoute
'/kamp': typeof KampRoute
'/login': typeof LoginRoute
'/open-mic': typeof OpenMicRoute
'/privacy': typeof PrivacyRoute
'/reset-password': typeof ResetPasswordRoute
'/terms': typeof TermsRoute
@@ -138,8 +138,8 @@ export interface FileRoutesByTo {
'/contact': typeof ContactRoute
'/drinkkaart': typeof DrinkkaartRoute
'/forgot-password': typeof ForgotPasswordRoute
'/kamp': typeof KampRoute
'/login': typeof LoginRoute
'/open-mic': typeof OpenMicRoute
'/privacy': typeof PrivacyRoute
'/reset-password': typeof ResetPasswordRoute
'/terms': typeof TermsRoute
@@ -158,8 +158,8 @@ export interface FileRoutesById {
'/contact': typeof ContactRoute
'/drinkkaart': typeof DrinkkaartRoute
'/forgot-password': typeof ForgotPasswordRoute
'/kamp': typeof KampRoute
'/login': typeof LoginRoute
'/open-mic': typeof OpenMicRoute
'/privacy': typeof PrivacyRoute
'/reset-password': typeof ResetPasswordRoute
'/terms': typeof TermsRoute
@@ -179,8 +179,8 @@ export interface FileRouteTypes {
| '/contact'
| '/drinkkaart'
| '/forgot-password'
| '/kamp'
| '/login'
| '/open-mic'
| '/privacy'
| '/reset-password'
| '/terms'
@@ -198,8 +198,8 @@ export interface FileRouteTypes {
| '/contact'
| '/drinkkaart'
| '/forgot-password'
| '/kamp'
| '/login'
| '/open-mic'
| '/privacy'
| '/reset-password'
| '/terms'
@@ -217,8 +217,8 @@ export interface FileRouteTypes {
| '/contact'
| '/drinkkaart'
| '/forgot-password'
| '/kamp'
| '/login'
| '/open-mic'
| '/privacy'
| '/reset-password'
| '/terms'
@@ -237,8 +237,8 @@ export interface RootRouteChildren {
ContactRoute: typeof ContactRoute
DrinkkaartRoute: typeof DrinkkaartRoute
ForgotPasswordRoute: typeof ForgotPasswordRoute
KampRoute: typeof KampRoute
LoginRoute: typeof LoginRoute
OpenMicRoute: typeof OpenMicRoute
PrivacyRoute: typeof PrivacyRoute
ResetPasswordRoute: typeof ResetPasswordRoute
TermsRoute: typeof TermsRoute
@@ -274,13 +274,6 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PrivacyRouteImport
parentRoute: typeof rootRouteImport
}
'/open-mic': {
id: '/open-mic'
path: '/open-mic'
fullPath: '/open-mic'
preLoaderRoute: typeof OpenMicRouteImport
parentRoute: typeof rootRouteImport
}
'/login': {
id: '/login'
path: '/login'
@@ -288,6 +281,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof LoginRouteImport
parentRoute: typeof rootRouteImport
}
'/kamp': {
id: '/kamp'
path: '/kamp'
fullPath: '/kamp'
preLoaderRoute: typeof KampRouteImport
parentRoute: typeof rootRouteImport
}
'/forgot-password': {
id: '/forgot-password'
path: '/forgot-password'
@@ -381,8 +381,8 @@ const rootRouteChildren: RootRouteChildren = {
ContactRoute: ContactRoute,
DrinkkaartRoute: DrinkkaartRoute,
ForgotPasswordRoute: ForgotPasswordRoute,
KampRoute: KampRoute,
LoginRoute: LoginRoute,
OpenMicRoute: OpenMicRoute,
PrivacyRoute: PrivacyRoute,
ResetPasswordRoute: ResetPasswordRoute,
TermsRoute: TermsRoute,

View File

@@ -1,318 +1,168 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import EventRegistrationForm from "@/components/homepage/EventRegistrationForm";
import Footer from "@/components/homepage/Footer";
import Hero from "@/components/homepage/Hero";
import HoeInschrijven from "@/components/homepage/HoeInschrijven";
import Info from "@/components/homepage/Info";
const KAMP_BANNER_KEY = "kk_kamp_banner_dismissed";
export const Route = createFileRoute("/")({
component: SelectorPage,
component: HomePage,
});
function SelectorPage() {
const [hovered, setHovered] = useState<"kamp" | "openmic" | null>(null);
const [mounted, setMounted] = useState(false);
const [isMobile, setIsMobile] = useState(false);
function KampBanner({ onDismiss }: { onDismiss: () => void }) {
const [visible, setVisible] = useState(false);
useEffect(() => {
const check = () => setIsMobile(window.innerWidth < 640);
check();
window.addEventListener("resize", check, { passive: true });
return () => window.removeEventListener("resize", check);
}, []);
useEffect(() => {
const t = setTimeout(() => setMounted(true), 60);
if (!document.getElementById("kamp-banner-font")) {
const el = document.createElement("link");
el.id = "kamp-banner-font";
el.rel = "stylesheet";
el.href =
"https://fonts.googleapis.com/css2?family=Special+Elite&display=swap";
document.head.appendChild(el);
}
const t = setTimeout(() => setVisible(true), 600);
return () => clearTimeout(t);
}, []);
const handleDismiss = () => {
setVisible(false);
setTimeout(onDismiss, 300);
};
return (
<div
className="flex h-[100dvh] w-full flex-col sm:flex-row"
style={{ gap: "6px", background: "#0a0a0a" }}
role="banner"
aria-label="Kunstenkamp inschrijvingen"
style={{
position: "fixed",
bottom: "1.25rem",
left: "50%",
transform: visible
? "translateX(-50%) translateY(0)"
: "translateX(-50%) translateY(120%)",
transition: "transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1)",
zIndex: 50,
width: "min(calc(100vw - 2rem), 480px)",
}}
>
{/* ── Kamp Inschrijvingen ───────────────────────────────────────── */}
<a
href="https://ejv.be/jong/kampen/kunstenkamp/"
target="_blank"
rel="noopener noreferrer"
className="group relative flex min-h-0 flex-col overflow-hidden"
<div
style={{
flex: isMobile
? "1 1 50%"
: hovered === "openmic"
? "0 0 30%"
: hovered === "kamp"
? "0 0 70%"
: "1 1 50%",
transition: "flex 0.65s cubic-bezier(0.76, 0, 0.24, 1)",
background: "#214e51",
textDecoration: "none",
background: "#ede4c8",
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E")`,
border: "1px solid #12100e",
outline: "3px solid rgba(18,16,14,0.1)",
outlineOffset: "3px",
borderRadius: 0,
padding: "12px 14px 14px",
boxShadow: "3px 5px 20px rgba(0,0,0,0.25)",
}}
onMouseEnter={() => setHovered("kamp")}
onMouseLeave={() => setHovered(null)}
aria-label="Ga naar de kamp inschrijvingen op ejv.be"
>
{/* Diagonal stripe texture */}
<div
aria-hidden="true"
className="pointer-events-none absolute inset-0"
style={{
backgroundImage:
"repeating-linear-gradient(135deg, rgba(255,255,255,0.03) 0px, rgba(255,255,255,0.03) 1px, transparent 1px, transparent 28px)",
}}
/>
{/* Mustard accent bar */}
<div
aria-hidden="true"
className="absolute top-0 left-0 w-[3px]"
style={{
background: "#d09035",
height: hovered === "kamp" ? "100%" : "0%",
transition: "height 0.65s cubic-bezier(0.76, 0, 0.24, 1)",
}}
/>
{/* Content — constrained width, centered */}
<div className="relative z-10 my-auto w-full px-6 py-8 sm:px-10 sm:py-12">
<div className="w-full max-w-sm">
{/* Top eyebrow */}
<p
className="mb-3 font-['DM_Sans',sans-serif] text-[10px] uppercase tracking-[0.25em] sm:mb-4"
style={{
color: "#d09035",
opacity: mounted ? 1 : 0,
transform: mounted ? "translateY(0)" : "translateY(-8px)",
transition: "opacity 0.7s ease 0.1s, transform 0.7s ease 0.1s",
}}
>
Kunstenkamp
</p>
<h2
className="font-['Intro',sans-serif] text-white uppercase leading-[0.88]"
style={{
fontSize: "clamp(1.6rem, 3.5vw, 2.8rem)",
opacity: mounted ? 1 : 0,
transform: mounted ? "translateY(0)" : "translateY(16px)",
transition: "opacity 0.8s ease 0.2s, transform 0.8s ease 0.2s",
}}
>
<span className="block whitespace-nowrap">Kamp</span>
<span className="block whitespace-nowrap">Inschrijvingen</span>
</h2>
{/* Details */}
<div
className="mt-4 grid grid-cols-2 gap-x-6 gap-y-3 sm:mt-5 sm:gap-y-3"
style={{
opacity: mounted ? 1 : 0,
transform: mounted ? "translateY(0)" : "translateY(8px)",
transition: "opacity 0.5s ease 0.3s, transform 0.5s ease 0.3s",
}}
>
<div>
<p className="font-['DM_Sans',sans-serif] text-[9px] text-white/40 uppercase tracking-[0.2em]">
Leeftijd
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-white/80 text-xs leading-snug sm:text-sm">
9<sup>*</sup>18 jaar
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-[9px] text-white/35 italic">
* geboortejaar dat je 10 wordt
</p>
</div>
<div>
<p className="font-['DM_Sans',sans-serif] text-[9px] text-white/40 uppercase tracking-[0.2em]">
Data
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-white/80 text-xs leading-snug sm:text-sm">
20/0725/07/2026
<br />
27/0701/08/2026
</p>
</div>
<div className="col-span-2">
<p className="font-['DM_Sans',sans-serif] text-[9px] text-white/40 uppercase tracking-[0.2em]">
Locatie
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-white/80 text-xs leading-snug sm:text-sm">
Camp de Limauges · Chemin de Bigaumont 2 · 1341 Ceroux-Mousty
</p>
</div>
</div>
{/* CTA */}
<div
className="mt-5 flex items-center gap-3 sm:mt-6"
style={{
opacity: mounted ? 1 : 0,
transition: "opacity 0.8s ease 0.3s",
}}
>
<div
style={{
height: "1px",
background: "#d09035",
width: hovered === "kamp" ? "72px" : "32px",
transition: "width 0.5s cubic-bezier(0.76, 0, 0.24, 1)",
}}
/>
<span
className="font-['DM_Sans',sans-serif] text-[10px] uppercase tracking-[0.2em]"
style={{ color: "#d09035" }}
>
Ga verder
</span>
</div>
</div>
{/* Top double rule */}
<div style={{ marginBottom: "10px" }}>
<div style={{ height: "2px", background: "#12100e", marginBottom: "3px" }} />
<div style={{ height: "1px", background: "rgba(18,16,14,0.35)" }} />
</div>
{/* Corner decoration */}
<div
aria-hidden="true"
className="pointer-events-none absolute right-0 bottom-0"
style={{
width: "clamp(60px, 15%, 140px)",
height: "clamp(60px, 15%, 140px)",
borderTop: "1px solid rgba(208,144,53,0.12)",
borderLeft: "1px solid rgba(208,144,53,0.12)",
transform: "translate(50%, 50%)",
}}
/>
</a>
{/* ── Open Mic Night ────────────────────────────────────────────── */}
<Link
to="/open-mic"
className="group relative flex min-h-0 flex-col overflow-hidden"
style={{
flex: isMobile
? "1 1 50%"
: hovered === "kamp"
? "0 0 30%"
: hovered === "openmic"
? "0 0 70%"
: "1 1 50%",
transition: "flex 0.65s cubic-bezier(0.76, 0, 0.24, 1)",
background: "#d82560",
textDecoration: "none",
}}
onMouseEnter={() => setHovered("openmic")}
onMouseLeave={() => setHovered(null)}
aria-label="Ga naar de Open Mic Night inschrijvingen"
>
{/* Diagonal stripe texture */}
<div
aria-hidden="true"
className="pointer-events-none absolute inset-0"
style={{
backgroundImage:
"repeating-linear-gradient(135deg, rgba(255,255,255,0.05) 0px, rgba(255,255,255,0.05) 1px, transparent 1px, transparent 28px)",
}}
/>
{/* White accent bar */}
<div
aria-hidden="true"
className="absolute top-0 right-0 w-[3px]"
style={{
background: "rgba(255,255,255,0.7)",
height: hovered === "openmic" ? "100%" : "0%",
transition: "height 0.65s cubic-bezier(0.76, 0, 0.24, 1)",
}}
/>
{/* Content — constrained width, centered */}
<div className="relative z-10 my-auto w-full px-6 py-8 sm:px-10 sm:py-12">
<div className="w-full max-w-sm">
{/* Top eyebrow */}
<div style={{ display: "flex", alignItems: "flex-start", gap: "10px" }}>
<div style={{ flex: 1, minWidth: 0 }}>
<p
className="mb-3 font-['DM_Sans',sans-serif] text-[10px] text-white/50 uppercase tracking-[0.25em] sm:mb-4"
style={{
opacity: mounted ? 1 : 0,
transform: mounted ? "translateY(0)" : "translateY(-8px)",
transition:
"opacity 0.7s ease 0.15s, transform 0.7s ease 0.15s",
fontFamily: "'Special Elite', cursive",
fontSize: "8px",
letterSpacing: "0.3em",
textTransform: "uppercase",
color: "rgba(18,16,14,0.45)",
marginBottom: "6px",
}}
>
Ongedesemd Woord
Aankondiging · Zomerkamp 2026
</p>
<h2
className="font-['Intro',sans-serif] text-white uppercase leading-[0.88]"
<p
style={{
fontSize: "clamp(1.6rem, 3.5vw, 2.8rem)",
opacity: mounted ? 1 : 0,
transform: mounted ? "translateY(0)" : "translateY(16px)",
transition:
"opacity 0.8s ease 0.25s, transform 0.8s ease 0.25s",
fontFamily: "'Playfair Display', serif",
fontWeight: 700,
fontSize: "14px",
color: "#12100e",
lineHeight: 1.35,
marginBottom: "12px",
}}
>
<span className="block whitespace-nowrap">Open</span>
<span className="block whitespace-nowrap">Mic Night</span>
</h2>
{/* Details */}
<div
className="mt-4 grid grid-cols-2 gap-x-6 gap-y-3 sm:mt-5"
Inschrijvingen voor de zomerkampen zijn open!
</p>
<Link
to="/kamp"
style={{
opacity: mounted ? 1 : 0,
transform: mounted ? "translateY(0)" : "translateY(8px)",
transition:
"opacity 0.5s ease 0.35s, transform 0.5s ease 0.35s",
display: "inline-block",
fontFamily: "'Special Elite', cursive",
fontSize: "9px",
letterSpacing: "0.22em",
textTransform: "uppercase",
textDecoration: "none",
color: "#ede4c8",
background: "#12100e",
border: "1px solid rgba(18,16,14,0.4)",
outline: "2px solid rgba(18,16,14,0.08)",
outlineOffset: "3px",
padding: "7px 12px 6px",
}}
>
<div>
<p className="font-['DM_Sans',sans-serif] text-[9px] text-white/50 uppercase tracking-[0.2em]">
Datum
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-white/90 text-xs leading-snug sm:text-sm">
Vrijdag 24 april 2026
<br />
19u30
</p>
</div>
<div>
<p className="font-['DM_Sans',sans-serif] text-[9px] text-white/50 uppercase tracking-[0.2em]">
Optreden
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-white/90 text-xs leading-snug sm:text-sm">
5 min podiumtijd
<br />
Alle kunstvormen
</p>
</div>
<div className="col-span-2">
<p className="font-['DM_Sans',sans-serif] text-[9px] text-white/50 uppercase tracking-[0.2em]">
Locatie
</p>
<p className="mt-0.5 font-['DM_Sans',sans-serif] text-white/90 text-xs leading-snug sm:text-sm">
Lange Winkelstraat 5 · 2000 Antwerpen
</p>
</div>
</div>
{/* CTA */}
<div
className="mt-5 flex items-center gap-3 sm:mt-6"
style={{
opacity: mounted ? 1 : 0,
transition: "opacity 0.8s ease 0.35s",
}}
>
<div
style={{
height: "1px",
background: "rgba(255,255,255,0.7)",
width: hovered === "openmic" ? "72px" : "32px",
transition: "width 0.5s cubic-bezier(0.76, 0, 0.24, 1)",
}}
/>
<span className="font-['DM_Sans',sans-serif] text-[10px] text-white/80 uppercase tracking-[0.2em]">
Ga verder
</span>
</div>
Schrijf je in
</Link>
</div>
<button
type="button"
onClick={handleDismiss}
aria-label="Sluit deze melding"
style={{
background: "none",
border: "none",
color: "rgba(18,16,14,0.3)",
cursor: "pointer",
padding: "2px",
flexShrink: 0,
fontSize: "18px",
lineHeight: 1,
fontFamily: "'Special Elite', cursive",
}}
>
×
</button>
</div>
</Link>
</div>
</div>
);
}
function HomePage() {
const [showBanner, setShowBanner] = useState(false);
useEffect(() => {
if (!localStorage.getItem(KAMP_BANNER_KEY)) {
setShowBanner(true);
}
}, []);
const dismissBanner = () => {
localStorage.setItem(KAMP_BANNER_KEY, "1");
setShowBanner(false);
};
return (
<>
<div className="relative">
<main className="relative">
<Hero />
<Info />
<HoeInschrijven />
<EventRegistrationForm />
<Footer />
</main>
</div>
{showBanner && <KampBanner onDismiss={dismissBanner} />}
</>
);
}

View File

@@ -0,0 +1,474 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { useEffect, useState } from "react";
const KAMP_URL = "https://ejv.be/jong/kampen/kunstenkamp/";
export const Route = createFileRoute("/kamp")({
component: KampPage,
});
const STYLES = `
@import url('https://fonts.googleapis.com/css2?family=UnifrakturMaguntia&family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700&family=EB+Garamond:ital,wght@0,400;0,500;1,400;1,500&family=Special+Elite&display=swap');
@keyframes kampPressIn {
from { opacity: 0; }
to { opacity: 1; }
}
body.kamp-page {
background-color: #d6cdb0 !important;
overflow: hidden;
}
body.kamp-page ::selection {
background: #12100e;
color: #ede4c8;
}
.kamp-scroll::-webkit-scrollbar {
width: 6px;
}
.kamp-scroll::-webkit-scrollbar-track {
background: #c9c0a4;
}
.kamp-scroll::-webkit-scrollbar-thumb {
background: #12100e;
}
`;
const PAPER = "#ede4c8";
const INK = "#12100e";
const INK_MID = "rgba(18,16,14,0.5)";
const INK_GHOST = "rgba(18,16,14,0.2)";
const RULE_W = "rgba(18,16,14,0.75)";
function TripleRule() {
return (
<div style={{ display: "flex", flexDirection: "column", gap: "3px" }}>
<div style={{ height: "3px", background: INK }} />
<div style={{ height: "1px", background: RULE_W }} />
<div style={{ height: "2px", background: INK }} />
</div>
);
}
function DoubleRule() {
return (
<div style={{ display: "flex", flexDirection: "column", gap: "3px" }}>
<div style={{ height: "2px", background: RULE_W }} />
<div style={{ height: "1px", background: RULE_W }} />
</div>
);
}
function KampPage() {
const [mounted, setMounted] = useState(false);
const [ctaHovered, setCtaHovered] = useState(false);
useEffect(() => {
if (!document.getElementById("kamp-newspaper-styles")) {
const el = document.createElement("style");
el.id = "kamp-newspaper-styles";
el.textContent = STYLES;
document.head.appendChild(el);
}
document.body.classList.add("kamp-page");
const t = setTimeout(() => setMounted(true), 60);
return () => {
document.body.classList.remove("kamp-page");
clearTimeout(t);
};
}, []);
return (
<div
style={{
height: "100dvh",
background: "#d6cdb0",
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='400' height='400' filter='url(%23n)' opacity='0.12'/%3E%3C/svg%3E")`,
backgroundRepeat: "repeat",
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: "1.5rem 1rem",
}}
>
{/* Newspaper page */}
<article
className="kamp-scroll"
style={{
width: "100%",
maxWidth: "700px",
height: "100%",
background: PAPER,
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E")`,
border: `1px solid ${INK}`,
boxShadow:
"3px 5px 24px rgba(0,0,0,0.18), 0 1px 3px rgba(0,0,0,0.12)",
opacity: mounted ? 1 : 0,
animation: mounted ? "kampPressIn 0.9s ease both" : undefined,
overflowY: "auto",
}}
>
{/* Outer decorative border inset */}
<div
style={{
margin: "6px",
border: `1px solid ${INK}`,
}}
>
{/* Top flag strip */}
<div
style={{
borderBottom: `1px solid ${INK}`,
padding: "7px 20px 6px",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Link
to="/"
style={{
fontFamily: "'Special Elite', cursive",
fontSize: "10px",
letterSpacing: "0.18em",
color: INK,
textDecoration: "none",
borderBottom: `1px solid ${INK}`,
paddingBottom: "1px",
}}
>
Open Mic Night
</Link>
<span
style={{
fontFamily: "'Special Elite', cursive",
fontSize: "9px",
letterSpacing: "0.18em",
color: INK_MID,
}}
>
· ·
</span>
<span
style={{
fontFamily: "'Special Elite', cursive",
fontSize: "9px",
letterSpacing: "0.22em",
textTransform: "uppercase",
color: INK_MID,
}}
>
Anno 2026
</span>
</div>
{/* Masthead */}
<div
style={{
padding: "20px 24px 16px",
textAlign: "center",
borderBottom: `1px solid ${INK}`,
}}
>
<h1
style={{
fontFamily: "'UnifrakturMaguntia', cursive",
fontSize: "clamp(2.4rem, 9vw, 4.5rem)",
color: INK,
margin: 0,
lineHeight: 1,
letterSpacing: "0.02em",
}}
>
De Kunstenkamp Gazet
</h1>
</div>
{/* Publication bar */}
<div
style={{
display: "flex",
justifyContent: "space-between",
padding: "6px 20px 5px",
borderBottom: `1px solid ${INK}`,
}}
>
{[
"Vol. CCXXVI",
"Zomerkamp · Juli 2026",
"Prijs: uw aanwezigheid",
].map((t) => (
<span
key={t}
style={{
fontFamily: "'Special Elite', cursive",
fontSize: "10px",
color: INK_MID,
letterSpacing: "0.1em",
}}
>
{t}
</span>
))}
</div>
{/* Main content area */}
<div style={{ padding: "28px 28px 24px" }}>
{/* Triple rule */}
<div style={{ marginBottom: "24px" }}>
<TripleRule />
</div>
{/* Main headline */}
<div style={{ textAlign: "center", marginBottom: "16px" }}>
<h2
style={{
fontFamily: "'Playfair Display', serif",
fontWeight: 900,
fontSize: "clamp(2.6rem, 9vw, 4.5rem)",
color: INK,
textTransform: "uppercase",
letterSpacing: "0.06em",
lineHeight: 0.95,
margin: "0 0 14px",
}}
>
Wat Is Waar?
</h2>
<p
style={{
fontFamily: "'Playfair Display', serif",
fontStyle: "italic",
fontSize: "clamp(1rem, 2.5vw, 1.2rem)",
color: INK_MID,
margin: 0,
lineHeight: 1.45,
}}
>
Een krant. Een tijdmachine. De waarheid doorheen de eeuwen.
</p>
</div>
{/* Triple rule */}
<div style={{ marginBottom: "22px" }}>
<TripleRule />
</div>
{/* Editorial body copy */}
<p
style={{
fontFamily: "'EB Garamond', serif",
fontSize: "clamp(1.05rem, 2.2vw, 1.2rem)",
color: INK,
lineHeight: 1.75,
margin: "0 0 10px",
textAlign: "justify",
hyphens: "auto",
}}
>
In de zomer van 1826 en opnieuw in 2026 reizen onze verslaggevers
terug naar de roerige redactiezalen van de negentiende eeuw. Waar de
drukpers ronkt, de rookmachines tieren en elke kop een mening
verbergt, stellen wij de vraag die door alle eeuwen galmt:{" "}
<em>wat mogen wij geloven?</em>
</p>
<p
style={{
fontFamily: "'EB Garamond', serif",
fontStyle: "italic",
fontSize: "clamp(0.95rem, 2vw, 1.08rem)",
color: INK_MID,
lineHeight: 1.7,
margin: "0 0 24px",
textAlign: "justify",
hyphens: "auto",
}}
>
Twee waarheden en een leugen. Vier bolhoeden en één typmachine.
Bereid u voor op een week journalistiek, theater, dans en woordkunst
alles gehuld in inkt en papier-maché.
</p>
{/* Ornamental divider */}
<p
style={{
textAlign: "center",
fontFamily: "'EB Garamond', serif",
fontSize: "13px",
color: INK_GHOST,
margin: "0 0 24px",
letterSpacing: "0.4em",
}}
>
· ·
</p>
{/* Details grid */}
<div
style={{
display: "grid",
gridTemplateColumns: "1fr 1fr",
border: `1px solid ${INK}`,
marginBottom: "28px",
}}
>
{[
{ label: "Primo", value: "20 25 Juli 2026" },
{ label: "Secundo", value: "27 Juli 1 Aug 2026" },
{
label: "Leeftijd",
value: "9 18 jaar",
sub: "* geboortejaar dat je 10 wordt",
},
{
label: "Locatie",
value: "Camp de Limauges",
sub: "Ceroux-Mousty · België",
},
].map(({ label, value, sub }, i) => (
<div
key={label}
style={{
padding: "16px 18px",
borderRight:
i % 2 === 0 ? `1px solid ${INK}` : undefined,
borderTop: i >= 2 ? `1px solid ${INK}` : undefined,
}}
>
<p
style={{
fontFamily: "'Special Elite', cursive",
fontSize: "9px",
letterSpacing: "0.3em",
textTransform: "uppercase",
color: INK_MID,
margin: "0 0 6px",
}}
>
{label}
</p>
<p
style={{
fontFamily: "'Playfair Display', serif",
fontWeight: 700,
fontSize: "clamp(1rem, 2.5vw, 1.15rem)",
color: INK,
margin: 0,
lineHeight: 1.3,
}}
>
{value}
</p>
{sub && (
<p
style={{
fontFamily: "'EB Garamond', serif",
fontStyle: "italic",
fontSize: "13px",
color: INK_MID,
margin: "4px 0 0",
}}
>
{sub}
</p>
)}
</div>
))}
</div>
{/* Double rule */}
<div style={{ marginBottom: "24px" }}>
<DoubleRule />
</div>
{/* CTA — inverted ink block */}
<div style={{ marginBottom: "4px" }}>
<p
style={{
fontFamily: "'Special Elite', cursive",
fontSize: "9px",
letterSpacing: "0.35em",
textTransform: "uppercase",
color: INK_MID,
textAlign: "center",
margin: "0 0 10px",
}}
>
Aankondiging
</p>
<a
href={KAMP_URL}
target="_blank"
rel="noopener noreferrer"
onMouseEnter={() => setCtaHovered(true)}
onMouseLeave={() => setCtaHovered(false)}
style={{
display: "block",
background: ctaHovered ? "#2a2418" : INK,
color: PAPER,
textDecoration: "none",
textAlign: "center",
padding: "28px 32px 26px",
outline: `2px solid ${INK}`,
outlineOffset: "4px",
transition: "background 0.2s ease",
}}
>
<span
style={{
display: "block",
fontFamily: "'Playfair Display', serif",
fontWeight: 900,
fontSize: "clamp(1.5rem, 5vw, 2.4rem)",
textTransform: "uppercase",
letterSpacing: "0.1em",
lineHeight: 1,
marginBottom: "10px",
}}
>
Schrijf U In
</span>
<span
style={{
display: "block",
fontFamily: "'Special Elite', cursive",
fontSize: "clamp(0.7rem, 2vw, 0.85rem)",
letterSpacing: "0.25em",
opacity: 0.65,
}}
>
via ejv.be
</span>
</a>
</div>
</div>
{/* Footer */}
<div
style={{
borderTop: `1px solid ${INK}`,
padding: "7px 20px 8px",
textAlign: "center",
}}
>
<p
style={{
fontFamily: "'EB Garamond', serif",
fontStyle: "italic",
fontSize: "12px",
color: INK_GHOST,
margin: 0,
letterSpacing: "0.06em",
}}
>
Kunst · Expressie · Avontuur · Waar is de waarheid?
</p>
</div>
</div>
</article>
</div>
);
}

View File

@@ -1,24 +0,0 @@
import { createFileRoute } from "@tanstack/react-router";
import EventRegistrationForm from "@/components/homepage/EventRegistrationForm";
import Footer from "@/components/homepage/Footer";
import Hero from "@/components/homepage/Hero";
import HoeInschrijven from "@/components/homepage/HoeInschrijven";
import Info from "@/components/homepage/Info";
export const Route = createFileRoute("/open-mic")({
component: OpenMicPage,
});
function OpenMicPage() {
return (
<div className="relative">
<main className="relative">
<Hero />
<Info />
<HoeInschrijven />
<EventRegistrationForm />
<Footer />
</main>
</div>
);
}