Compare commits
4 Commits
845624dfd3
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
d3a4554b0d
|
|||
|
71b85d6874
|
|||
|
7b3d5461ef
|
|||
|
56942275b8
|
@@ -8,11 +8,14 @@ import { Header } from "./Header";
|
|||||||
export function SiteHeader() {
|
export function SiteHeader() {
|
||||||
const { data: session } = authClient.useSession();
|
const { data: session } = authClient.useSession();
|
||||||
const routerState = useRouterState();
|
const routerState = useRouterState();
|
||||||
const isHomepage = routerState.location.pathname === "/";
|
const pathname = routerState.location.pathname;
|
||||||
|
const isHomepage = pathname === "/";
|
||||||
|
const isKamp = pathname === "/kamp";
|
||||||
|
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (isKamp) return;
|
||||||
if (!isHomepage) {
|
if (!isHomepage) {
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
return;
|
return;
|
||||||
@@ -25,7 +28,9 @@ export function SiteHeader() {
|
|||||||
handleScroll();
|
handleScroll();
|
||||||
window.addEventListener("scroll", handleScroll, { passive: true });
|
window.addEventListener("scroll", handleScroll, { passive: true });
|
||||||
return () => window.removeEventListener("scroll", handleScroll);
|
return () => window.removeEventListener("scroll", handleScroll);
|
||||||
}, [isHomepage]);
|
}, [isHomepage, isKamp]);
|
||||||
|
|
||||||
|
if (isKamp) return null;
|
||||||
|
|
||||||
if (!session?.user) {
|
if (!session?.user) {
|
||||||
return <Header isGuest isVisible={isVisible} isHomepage={isHomepage} />;
|
return <Header isGuest isVisible={isVisible} isHomepage={isHomepage} />;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { Route as TermsRouteImport } from './routes/terms'
|
|||||||
import { Route as ResetPasswordRouteImport } from './routes/reset-password'
|
import { Route as ResetPasswordRouteImport } from './routes/reset-password'
|
||||||
import { Route as PrivacyRouteImport } from './routes/privacy'
|
import { Route as PrivacyRouteImport } from './routes/privacy'
|
||||||
import { Route as LoginRouteImport } from './routes/login'
|
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 ForgotPasswordRouteImport } from './routes/forgot-password'
|
||||||
import { Route as DrinkkaartRouteImport } from './routes/drinkkaart'
|
import { Route as DrinkkaartRouteImport } from './routes/drinkkaart'
|
||||||
import { Route as ContactRouteImport } from './routes/contact'
|
import { Route as ContactRouteImport } from './routes/contact'
|
||||||
@@ -46,6 +47,11 @@ const LoginRoute = LoginRouteImport.update({
|
|||||||
path: '/login',
|
path: '/login',
|
||||||
getParentRoute: () => rootRouteImport,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
|
const KampRoute = KampRouteImport.update({
|
||||||
|
id: '/kamp',
|
||||||
|
path: '/kamp',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
const ForgotPasswordRoute = ForgotPasswordRouteImport.update({
|
const ForgotPasswordRoute = ForgotPasswordRouteImport.update({
|
||||||
id: '/forgot-password',
|
id: '/forgot-password',
|
||||||
path: '/forgot-password',
|
path: '/forgot-password',
|
||||||
@@ -113,6 +119,7 @@ export interface FileRoutesByFullPath {
|
|||||||
'/contact': typeof ContactRoute
|
'/contact': typeof ContactRoute
|
||||||
'/drinkkaart': typeof DrinkkaartRoute
|
'/drinkkaart': typeof DrinkkaartRoute
|
||||||
'/forgot-password': typeof ForgotPasswordRoute
|
'/forgot-password': typeof ForgotPasswordRoute
|
||||||
|
'/kamp': typeof KampRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/privacy': typeof PrivacyRoute
|
'/privacy': typeof PrivacyRoute
|
||||||
'/reset-password': typeof ResetPasswordRoute
|
'/reset-password': typeof ResetPasswordRoute
|
||||||
@@ -131,6 +138,7 @@ export interface FileRoutesByTo {
|
|||||||
'/contact': typeof ContactRoute
|
'/contact': typeof ContactRoute
|
||||||
'/drinkkaart': typeof DrinkkaartRoute
|
'/drinkkaart': typeof DrinkkaartRoute
|
||||||
'/forgot-password': typeof ForgotPasswordRoute
|
'/forgot-password': typeof ForgotPasswordRoute
|
||||||
|
'/kamp': typeof KampRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/privacy': typeof PrivacyRoute
|
'/privacy': typeof PrivacyRoute
|
||||||
'/reset-password': typeof ResetPasswordRoute
|
'/reset-password': typeof ResetPasswordRoute
|
||||||
@@ -150,6 +158,7 @@ export interface FileRoutesById {
|
|||||||
'/contact': typeof ContactRoute
|
'/contact': typeof ContactRoute
|
||||||
'/drinkkaart': typeof DrinkkaartRoute
|
'/drinkkaart': typeof DrinkkaartRoute
|
||||||
'/forgot-password': typeof ForgotPasswordRoute
|
'/forgot-password': typeof ForgotPasswordRoute
|
||||||
|
'/kamp': typeof KampRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/privacy': typeof PrivacyRoute
|
'/privacy': typeof PrivacyRoute
|
||||||
'/reset-password': typeof ResetPasswordRoute
|
'/reset-password': typeof ResetPasswordRoute
|
||||||
@@ -170,6 +179,7 @@ export interface FileRouteTypes {
|
|||||||
| '/contact'
|
| '/contact'
|
||||||
| '/drinkkaart'
|
| '/drinkkaart'
|
||||||
| '/forgot-password'
|
| '/forgot-password'
|
||||||
|
| '/kamp'
|
||||||
| '/login'
|
| '/login'
|
||||||
| '/privacy'
|
| '/privacy'
|
||||||
| '/reset-password'
|
| '/reset-password'
|
||||||
@@ -188,6 +198,7 @@ export interface FileRouteTypes {
|
|||||||
| '/contact'
|
| '/contact'
|
||||||
| '/drinkkaart'
|
| '/drinkkaart'
|
||||||
| '/forgot-password'
|
| '/forgot-password'
|
||||||
|
| '/kamp'
|
||||||
| '/login'
|
| '/login'
|
||||||
| '/privacy'
|
| '/privacy'
|
||||||
| '/reset-password'
|
| '/reset-password'
|
||||||
@@ -206,6 +217,7 @@ export interface FileRouteTypes {
|
|||||||
| '/contact'
|
| '/contact'
|
||||||
| '/drinkkaart'
|
| '/drinkkaart'
|
||||||
| '/forgot-password'
|
| '/forgot-password'
|
||||||
|
| '/kamp'
|
||||||
| '/login'
|
| '/login'
|
||||||
| '/privacy'
|
| '/privacy'
|
||||||
| '/reset-password'
|
| '/reset-password'
|
||||||
@@ -225,6 +237,7 @@ export interface RootRouteChildren {
|
|||||||
ContactRoute: typeof ContactRoute
|
ContactRoute: typeof ContactRoute
|
||||||
DrinkkaartRoute: typeof DrinkkaartRoute
|
DrinkkaartRoute: typeof DrinkkaartRoute
|
||||||
ForgotPasswordRoute: typeof ForgotPasswordRoute
|
ForgotPasswordRoute: typeof ForgotPasswordRoute
|
||||||
|
KampRoute: typeof KampRoute
|
||||||
LoginRoute: typeof LoginRoute
|
LoginRoute: typeof LoginRoute
|
||||||
PrivacyRoute: typeof PrivacyRoute
|
PrivacyRoute: typeof PrivacyRoute
|
||||||
ResetPasswordRoute: typeof ResetPasswordRoute
|
ResetPasswordRoute: typeof ResetPasswordRoute
|
||||||
@@ -268,6 +281,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof LoginRouteImport
|
preLoaderRoute: typeof LoginRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
|
'/kamp': {
|
||||||
|
id: '/kamp'
|
||||||
|
path: '/kamp'
|
||||||
|
fullPath: '/kamp'
|
||||||
|
preLoaderRoute: typeof KampRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
'/forgot-password': {
|
'/forgot-password': {
|
||||||
id: '/forgot-password'
|
id: '/forgot-password'
|
||||||
path: '/forgot-password'
|
path: '/forgot-password'
|
||||||
@@ -361,6 +381,7 @@ const rootRouteChildren: RootRouteChildren = {
|
|||||||
ContactRoute: ContactRoute,
|
ContactRoute: ContactRoute,
|
||||||
DrinkkaartRoute: DrinkkaartRoute,
|
DrinkkaartRoute: DrinkkaartRoute,
|
||||||
ForgotPasswordRoute: ForgotPasswordRoute,
|
ForgotPasswordRoute: ForgotPasswordRoute,
|
||||||
|
KampRoute: KampRoute,
|
||||||
LoginRoute: LoginRoute,
|
LoginRoute: LoginRoute,
|
||||||
PrivacyRoute: PrivacyRoute,
|
PrivacyRoute: PrivacyRoute,
|
||||||
ResetPasswordRoute: ResetPasswordRoute,
|
ResetPasswordRoute: ResetPasswordRoute,
|
||||||
|
|||||||
@@ -1,16 +1,162 @@
|
|||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute, Link } from "@tanstack/react-router";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import EventRegistrationForm from "@/components/homepage/EventRegistrationForm";
|
import EventRegistrationForm from "@/components/homepage/EventRegistrationForm";
|
||||||
import Footer from "@/components/homepage/Footer";
|
import Footer from "@/components/homepage/Footer";
|
||||||
import Hero from "@/components/homepage/Hero";
|
import Hero from "@/components/homepage/Hero";
|
||||||
import HoeInschrijven from "@/components/homepage/HoeInschrijven";
|
import HoeInschrijven from "@/components/homepage/HoeInschrijven";
|
||||||
import Info from "@/components/homepage/Info";
|
import Info from "@/components/homepage/Info";
|
||||||
|
|
||||||
|
const KAMP_BANNER_KEY = "kk_kamp_banner_dismissed";
|
||||||
|
|
||||||
export const Route = createFileRoute("/")({
|
export const Route = createFileRoute("/")({
|
||||||
component: HomePage,
|
component: HomePage,
|
||||||
});
|
});
|
||||||
|
|
||||||
function HomePage() {
|
function KampBanner({ onDismiss }: { onDismiss: () => void }) {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
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 (
|
return (
|
||||||
|
<header
|
||||||
|
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)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
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)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* 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>
|
||||||
|
|
||||||
|
<div style={{ display: "flex", alignItems: "flex-start", gap: "10px" }}>
|
||||||
|
<div style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontFamily: "'Special Elite', cursive",
|
||||||
|
fontSize: "8px",
|
||||||
|
letterSpacing: "0.3em",
|
||||||
|
textTransform: "uppercase",
|
||||||
|
color: "rgba(18,16,14,0.45)",
|
||||||
|
marginBottom: "6px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
✦ Aankondiging · Zomerkamp 2026 ✦
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontFamily: "'Playfair Display', serif",
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: "14px",
|
||||||
|
color: "#12100e",
|
||||||
|
lineHeight: 1.35,
|
||||||
|
marginBottom: "12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Inschrijvingen voor de zomerkampen zijn open!
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
to="/kamp"
|
||||||
|
style={{
|
||||||
|
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",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
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>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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">
|
<div className="relative">
|
||||||
<main className="relative">
|
<main className="relative">
|
||||||
<Hero />
|
<Hero />
|
||||||
@@ -20,5 +166,7 @@ function HomePage() {
|
|||||||
<Footer />
|
<Footer />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
{showBanner && <KampBanner onDismiss={dismissBanner} />}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
473
apps/web/src/routes/kamp.tsx
Normal file
473
apps/web/src/routes/kamp.tsx
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user