// SnapCrew — marketing website // Single React app, brand system from logo work: Space Grotesk + JetBrains Mono, // Ink/Paper/Coral/Purple, Mark D Hero. const { useState, useEffect } = React; // Single mobile breakpoint at 768px. Used by sections to collapse multi-column // grids, shrink display type, and reduce vertical padding on small screens. function useIsMobile(breakpoint = 768) { const get = () => typeof window !== 'undefined' && window.innerWidth < breakpoint; const [m, setM] = useState(get); useEffect(() => { const onResize = () => setM(get()); window.addEventListener('resize', onResize); return () => window.removeEventListener('resize', onResize); }, [breakpoint]); return m; } const T = { ink: '#15151A', paper: '#F6F2EB', paperWarm: '#EFEAE0', paperCool: '#E8E4DC', coral: '#FF6A52', purple: '#8B5CF6', cyan: '#22D3EE', peach: '#FFB088', muted: 'rgba(20,20,25,0.6)', mutedSoft: 'rgba(20,20,25,0.42)', paperOnInk: 'rgba(246,242,235,0.7)', paperOnInkSoft: 'rgba(246,242,235,0.5)', border: 'rgba(20,20,25,0.08)', borderInk: 'rgba(246,242,235,0.1)', }; // ─── shared building blocks ─────────────────────────────────── function Container({ children, style = {} }) { const isMobile = useIsMobile(); return (
{children}
); } function Eyebrow({ children, dark }) { return (
{children}
); } function Button({ children, variant = 'primary', accent, onClick }) { const base = { display: 'inline-flex', alignItems: 'center', gap: 10, padding: '14px 22px', borderRadius: 999, border: 'none', fontSize: 15, fontWeight: 500, letterSpacing: '-0.01em', transition: 'transform .15s ease, background .15s ease, color .15s ease', }; const variants = { primary: { background: T.ink, color: T.paper }, accent: { background: accent, color: T.ink }, ghost: { background: 'transparent', color: T.ink, boxShadow: `inset 0 0 0 1px ${T.border}` }, ghostDark: { background: 'transparent', color: T.paper, boxShadow: `inset 0 0 0 1px ${T.borderInk}` }, }; return ( ); } // ─── Header ─────────────────────────────────────────────────── function Header({ accent }) { const nav = ['Funktionen', 'Challenges', 'Anlässe', 'Preise', 'FAQ']; const isMobile = useIsMobile(960); return (
{!isMobile && ( )}
{!isMobile && Anmelden}
); } // ─── Phone mock (used in hero) ──────────────────────────────── const HERO_PHOTOS = [ { h: 200, c: 'linear-gradient(135deg,#3a2e2a,#5a4438)', label: 'Anstoßen' }, { h: 160, c: 'linear-gradient(135deg,#4a3f5c,#26223a)', label: 'Tanzfläche' }, { h: 170, c: 'linear-gradient(135deg,#2e3a3a,#1b2424)', label: 'Torte' }, { h: 210, c: 'linear-gradient(135deg,#5b4239,#33231e)', label: 'Selfie' }, { h: 150, c: 'linear-gradient(135deg,#3e3a2e,#22201a)', label: 'Detail' }, { h: 180, c: 'linear-gradient(135deg,#4a2e3a,#2a1820)', label: 'Gäste' }, ]; function PhoneMock({ accent }) { return (
{/* Status bar */}
22:48
{/* Notch */}
{/* App header */}
HOCHZEIT
Luca & Mia
LIVE · 84
{/* Masonry-ish grid */}
{[0, 1, 2, 3, 4, 5].map((i) => { const p = HERO_PHOTOS[i]; const isNew = i === 0; return (
{isNew && (
NEU
)}
{p.label} ♥ {12 + i * 3}
); })}
{/* Bottom upload bar */}
Foto teilen +312
); } // ─── Floating QR card overlapping the phone ─────────────────── function FloatingQR({ accent }) { const pattern = ['1110111','1010101','1110101','0001110','1010001','0101010','1110111']; return (
SCAN MICH
{pattern.flatMap((row, r) => row.split('').map((c, i) => c === '1' ? ( ) : null) )}
Luca & Mia
snapcrew.live
); } // ─── Hero ───────────────────────────────────────────────────── function Hero({ accent }) { const isMobile = useIsMobile(900); return (
Die moderne Alternative zur Fotobox

Alle Perspektiven
eurer Feier.

QR scannen, Foto teilen, Challenges spielen. Jedes Bild landet direkt in der Galerie oder live auf jedem Screen. Ohne App, ohne Registrierung. Jeder Gast wird zum Fotografen.

{/* Floating reaction chips */}
❤️ 🔥 🥹 +127
); } // ─── How it works ───────────────────────────────────────────── function HowItWorks({ accent }) { const steps = [ { n: '01', title: 'Event anlegen', body: 'Name, Datum, Design — fertig. Euer persönlicher Account steht sofort bereit.', visual: , }, { n: '02', title: 'QR teilen', body: 'Auf Tischkarten, Einladungen oder dem Beamer. Gäste scannen — und sind drin. Ohne App.', visual: , }, { n: '03', title: 'Live erleben', body: 'Jedes Foto landet sofort in der gemeinsamen Galerie und optional auf der Beamer-Slideshow.', visual: , }, ]; const isMobile = useIsMobile(); return (
So funktioniert's

In drei Schritten
zur Crew-Story.

Vom Anlegen bis zum ersten Foto vergehen unter zwei Minuten. Keine Schulung, kein Setup-Aufwand.

{steps.map((s) => (
{s.n}
{s.visual}

{s.title}

{s.body}

))}
); } function StepEvent({ accent }) { return (
EVENT
); } function StepQR({ accent }) { const pattern = ['1110','1010','1011','0111']; return (
{pattern.flatMap((row, r) => row.split('').map((c, i) => c === '1' ? ( ) : null) )}
snapcrew.live
); } function StepLive({ accent }) { return (
{[0,1,2,3,4,5].map((i) => (
))}
); } // ─── Features ───────────────────────────────────────────────── function Features({ accent }) { const items = [ { title: 'Live Gallery', body: 'Jedes hochgeladene Foto landet sofort in der gemeinsamen Eventgalerie — chronologisch oder als Mosaik.', tag: 'CORE', visual: 'gallery', }, { title: 'Beamer-Slideshow', body: 'Eine zweite URL für den Screen vor Ort. Neue Bilder erscheinen automatisch, mit smoothem Übergang.', tag: 'LIVE', visual: 'slideshow', }, { title: 'Reactions', body: 'Gäste reagieren mit ❤️ 🔥 😂 🥹 🕺 — Emojis fliegen kurz über den Beamer, das beste Foto gewinnt.', tag: 'SOCIAL', visual: 'reactions', }, { title: 'Smart Moderation', body: 'Automatische Freigabe oder manueller Modus. Anstößige Inhalte werden KI-gefiltert, bevor sie öffentlich sind.', tag: 'TRUST', visual: 'moderation', }, ]; const isMobile = useIsMobile(); return (
Was SnapCrew kann

Eine Plattform.
Jeder Moment.

SnapCrew ist keine Fotobox-Imitation. Es ist eine eigene Idee, gebaut für moderne Feiern.

{items.map((it, i) => ( ))}
); } function FeatureCard({ item, accent, large }) { const isMobile = useIsMobile(); return (
{item.tag}

{item.title}

{item.body}

); } function FeatureVisual({ kind, accent }) { if (kind === 'gallery') { return (
{[0,1,2,3,4,5,6,7,8].map((i) => (
))}
); } if (kind === 'slideshow') { return (
LIVE · BEAMER
); } if (kind === 'reactions') { return (
{['❤️','🔥','😂','🥹','🕺'].map((e, i) => ( {e} {[127,84,42,28,16][i]} ))}
{['❤️','🔥','❤️','🥹','🕺'].map((e, i) => ( {e} ))}
); } if (kind === 'moderation') { return (
{[ { ok: true, label: 'Hochgeladen · Anna' }, { ok: true, label: 'Hochgeladen · Tim' }, { ok: false, label: 'Geprüft · ausgeblendet' }, { ok: true, label: 'Hochgeladen · Mia' }, ].map((r, i) => (
{r.ok ? '✓' : '–'} {r.label}
))}
); } } // ─── Photo Challenges ──────────────────────────────────────── const CHALLENGES = [ { n: '01', label: 'Blonde Haare', body: 'Fotografiere jemanden mit blonden Haaren.', emoji: '💁' }, { n: '02', label: 'Das Buffet', body: 'Halte das schönste Tellergericht des Abends fest.', emoji: '🍽️' }, { n: '03', label: 'Gruppenfoto · 5+', body: 'Mache ein Foto mit mindestens fünf Gästen.', emoji: '👯' }, { n: '04', label: 'Emotional', body: 'Fang den emotionalsten Moment des Abends ein.', emoji: '🥹' }, { n: '05', label: 'Beste Tanzbewegung', body: 'Finde die lustigste Tanzbewegung des Abends.', emoji: '🕺' }, { n: '06', label: 'Detail', body: 'Ein Detail, das sonst niemand bemerkt hat.', emoji: '🔍' }, ]; // Tint a hex accent down to a very light pill background. Works for any // accent (coral/purple/cyan) — keeps the chip looking soft + readable. function tintAccent(hex, alpha = 0.14) { const h = hex.replace('#', ''); const r = parseInt(h.slice(0, 2), 16); const g = parseInt(h.slice(2, 4), 16); const b = parseInt(h.slice(4, 6), 16); return `rgba(${r},${g},${b},${alpha})`; } // Small inline icons used inside the phone mock — stroke-based, lucide-style. function IconCamera({ size = 18, stroke = 'currentColor' }) { return ( ); } function IconHeart({ size = 18, stroke = 'currentColor', fill = 'none' }) { return ( ); } function IconTarget({ size = 18, stroke = 'currentColor' }) { return ( ); } function ChallengePhone({ accent }) { // Mirror of the real SnapCrew app: header with brand, "FOTOCHALLENGE" pill, // inset task panel, big primary CTA, bottom tab bar. const tintPill = tintAccent(accent, 0.18); const tabs = [ { label: 'Hochladen', icon: , active: false }, { label: 'Bewerten', icon: , active: false }, { label: 'Challenge', icon: , active: true }, ]; return (
{/* Status bar */}
22:48
{/* Brand header */}
{/* Card */}
{/* Pill */}
FOTOCHALLENGE
{/* Inset task panel */}
DEINE AUFGABE
Mache ein Foto mit 5 weiteren Gästen.
{/* CTA */}
{/* Bottom tab bar */}
{tabs.map((t) => (
{t.icon} {t.label}
))}
); } function Challenges({ accent }) { const isMobile = useIsMobile(900); return (
Foto-Challenges

Aus Gästen werden Mitspieler.

Aktiviert spielerische Foto-Aufgaben und macht euer Event interaktiv. Gäste sehen die Challenges direkt auf dem Smartphone, reichen ihren Beitrag ein — und die Crew kürt das beste Foto per Reaction.

{[ { v: '100+', l: 'Vorgefertigte Aufgaben' }, { v: '∞', l: 'Eigene Challenges' }, { v: '5', l: 'Reaction-Emojis' }, ].map((s) => (
{s.v}
{s.l}
))}
3 aktive Challenges
❤️ 🔥 👏 +64

Beispiel-Aufgaben aus der Bibliothek

{CHALLENGES.map((c) => (
CHALLENGE · {c.n} {c.emoji}
{c.label}

{c.body}

))}
); } // ─── Use cases ──────────────────────────────────────────────── function UseCases({ accent }) { const cases = [ { title: 'Hochzeiten', body: 'Jeder Tisch hat seine eigene Sicht auf den Tag. SnapCrew sammelt sie an einem Ort.', icon: '💍' }, { title: 'Geburtstage', body: 'Vom Kindergeburtstag bis zum 50. — alle Gäste werden Teil des Albums.', icon: '🎂' }, { title: 'Corporate Events', body: 'Mitarbeiterfeste, Sommerparties, Off-Sites. Branding & Domain anpassbar.', icon: '🏢' }, { title: 'Konferenzen', body: 'Speaker-Momente, Workshops, Pausen-Snapshots — live im Foyer auf dem Screen.', icon: '🎤' }, { title: 'Festivals & Clubs', body: 'Mehrtägige Events mit tausenden Gästen. Moderations-Modus inklusive.', icon: '🎶' }, { title: 'Sport & Verein', body: 'Spieltage, Abibälle, Vereinsfeste. Eine Galerie, alle Perspektiven.', icon: '🏆' }, ]; const isMobile = useIsMobile(); return (
Für jeden Anlass

Wo SnapCrew
zuhause ist.

Egal ob 5 oder 5.000 Gäste. SnapCrew sorgt immer für Unterhaltung. Design komplett anpassbar.

{cases.map((c) => (
{ e.currentTarget.style.transform = 'translateY(-3px)'; e.currentTarget.style.borderColor = T.ink; }} onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.borderColor = T.border; }}>
{c.icon}

{c.title}

{c.body}

))}
); } // ─── Pricing ────────────────────────────────────────────────── function Pricing({ accent }) { const tiers = [ { name: 'Mini', price: '19', sub: 'einmalig · 48 h', desc: 'Für kleinere Feiern und private Anlässe.', bullets: [ 'Bis zu 30 Gäste', 'Live Gallery', 'QR-Code als PDF', '500 Fotos inklusive', ], cta: 'Event starten', variant: 'ghost', }, { name: 'Event', price: '49', sub: 'einmalig · 7 Tage', desc: 'Der Klassiker für Hochzeiten, Geburtstage, Partys.', bullets: [ 'Unbegrenzte Gäste', 'Live Gallery + Beamer-Slideshow', 'Reactions & Moderation', 'Eigener Eventname in URL', 'Foto-Download als ZIP', ], cta: 'Event starten', variant: 'accent', featured: true, }, { name: 'Pro', price: '199', sub: 'pro Event', desc: 'Für Corporate-Events, Festivals und Agenturen.', bullets: [ 'Custom Branding & Domain', 'KI-Moderation', 'Multi-Event-Management', 'API & Webhooks', 'Priority Support', ], cta: 'Sales kontaktieren', variant: 'ghost', }, ]; const isMobile = useIsMobile(); return (
Preise

Ein fairer Preis
pro Feier.

Keine Abos, keine Mitgliedschaften. Ihr zahlt nur, wenn ihr feiert.

{tiers.map((t) => (
{t.featured && (
Beliebteste
)}

{t.name}

{t.desc}

€{t.price} {t.sub}
    {t.bullets.map((b) => (
  • {b}
  • ))}
))}
); } // ─── FAQ ───────────────────────────────────────────────────── function FAQ() { const qs = [ { q: 'Müssen meine Gäste eine App herunterladen?', a: 'Nein. SnapCrew läuft komplett im Browser. QR scannen, Kamera erlauben, Foto teilen — fertig.' }, { q: 'Was passiert mit den Fotos nach dem Event?', a: 'Du kannst alle Fotos als ZIP herunterladen. Standardmäßig löschen wir die Daten 60 Tage nach Eventende — verlängerbar bis 12 Monate.' }, { q: 'Kann ich Fotos vor der Veröffentlichung prüfen?', a: 'Ja. Im Moderations-Modus landen neue Fotos in der Warteschlange und erscheinen erst nach Freigabe. Zusätzlich filtert ein KI-Modell anstößige Inhalte automatisch.' }, { q: 'Funktioniert die Slideshow auch ohne Internet vor Ort?', a: 'Die Slideshow benötigt eine aktive Verbindung. Wir empfehlen einen LTE-Hotspot als Backup — wir liefern die Empfehlung mit dem Buchungs-Mail.' }, { q: 'Kann ich das Logo und die Farben anpassen?', a: 'Im Pro-Tarif: ja, vollständig — eigenes Logo, eigene Farben, eigene Domain. Im Event-Tarif: der Eventname erscheint in URL und Header.' }, { q: 'Wie funktionieren die Foto-Challenges?', a: 'Wählt aus über 100 vorgefertigten Aufgaben oder erstellt eigene Challenges. Gäste sehen die aktiven Aufgaben direkt auf dem Smartphone, reichen ein Foto ein — und alle anderen können mit Emojis reagieren. Das Foto mit den meisten Reactions wird zur Top-Einreichung.' }, ]; const [open, setOpen] = useState(0); const isMobile = useIsMobile(); return (
FAQ

Häufige
Fragen.

Noch was offen? Schreib uns kurz — wir antworten meist innerhalb einer Stunde.

{qs.map((it, i) => { const isOpen = open === i; return (
{isOpen && (

{it.a}

)}
); })}
); } // ─── Final CTA ──────────────────────────────────────────────── function FinalCTA({ accent }) { const isMobile = useIsMobile(); return (

Bereit für
euren Moment?

In zwei Minuten ist euer Event online. Probiert es kostenlos mit einem Test-Event.

); } // ─── Footer ─────────────────────────────────────────────────── function Footer({ accent }) { const isMobile = useIsMobile(); return (

Live-Event-Fotos aus eurer Crew. Hergestellt mit ♥ in Deutschland.

© 2026 Content Fellows GmbH Alle Systeme online
); } function FooterCol({ title, items }) { return (
{title}
    {items.map((it) => { const label = typeof it === 'string' ? it : it.label; const href = typeof it === 'string' ? '#' : it.href; return
  • {label}
  • ; })}
); } // ─── App ────────────────────────────────────────────────────── function App() { const accent = T.coral; return ( <>