commit
This commit is contained in:
@@ -1 +1,130 @@
|
||||
/* minimal css placeholder */
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.site-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.nav-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 0;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.brand__logo { width: 46px; height: 46px; object-fit: contain; }
|
||||
.brand__text { display: flex; flex-direction: column; line-height: 1.1; }
|
||||
.brand__name { font-weight: 700; letter-spacing: -0.3px; }
|
||||
.brand__tag { color: var(--color-muted); font-size: 13px; }
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.nav-links a { color: var(--color-text); }
|
||||
.nav-links a:hover { color: var(--color-primary); }
|
||||
|
||||
.nav-actions { display: flex; align-items: center; gap: 10px; }
|
||||
.menu-toggle { display: none; background: transparent; border: 1px solid var(--color-border); padding: 8px 10px; border-radius: var(--radius-sm); }
|
||||
.mobile-menu { display: none; padding: 12px 16px; border-top: 1px solid var(--color-border); background: #fff; }
|
||||
.mobile-menu a, .mobile-menu button { display: block; width: 100%; text-align: left; margin-bottom: 10px; }
|
||||
|
||||
@media (max-width: 900px){
|
||||
.nav-links { display: none; }
|
||||
.menu-toggle { display: inline-flex; }
|
||||
.nav-actions .btn { display: none; }
|
||||
.mobile-menu.open { display: block; }
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding: 64px 0;
|
||||
background: linear-gradient(135deg, #fdf6e6, #f1e8de);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.hero__grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 32px; align-items: center; }
|
||||
.hero__text h1 { margin: 12px 0 10px 0; font-size: clamp(28px, 4vw, 42px); line-height: 1.1; }
|
||||
.hero__text .lede { color: var(--color-muted); font-size: 17px; }
|
||||
.hero__actions { display:flex; gap: 12px; flex-wrap: wrap; margin: 18px 0; }
|
||||
.hero__meta { display:flex; gap:8px; flex-wrap: wrap; }
|
||||
.hero__card { padding: 20px; background: #fff; border:1px solid var(--color-border); box-shadow: var(--shadow-card); }
|
||||
|
||||
.eyebrow { text-transform: uppercase; letter-spacing: 1px; font-size: 12px; color: var(--color-muted); margin: 0; }
|
||||
.lede { margin: 0; }
|
||||
.muted.small { font-size: 13px; }
|
||||
|
||||
.section { padding: 64px 0; }
|
||||
.section.alt { background: #ffffff; border-block: 1px solid var(--color-border); }
|
||||
.section__head { display:flex; justify-content:space-between; align-items:flex-start; gap: 16px; flex-wrap: wrap; }
|
||||
|
||||
.split { display:grid; grid-template-columns: 1.1fr 0.9fr; gap: 24px; align-items: start; }
|
||||
@media (max-width: 960px){ .split, .hero__grid { grid-template-columns: 1fr; } }
|
||||
|
||||
.card { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: 18px; box-shadow: var(--shadow-card); }
|
||||
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; background: var(--color-accent-soft); color: var(--color-highlight); border-radius: 999px; font-weight: 700; font-size: 12px; letter-spacing: .3px; }
|
||||
|
||||
.hero__card .form-row { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
|
||||
|
||||
.pill-row { display:flex; flex-wrap: wrap; gap: 8px; }
|
||||
.pill { display:inline-flex; align-items:center; gap:6px; padding: 6px 10px; border-radius: 999px; border: 1px solid var(--color-border); background:#fff; font-size: 13px; }
|
||||
|
||||
.list { margin: 0; padding-left: 18px; display: grid; gap: 8px; }
|
||||
.list li { color: var(--color-text); }
|
||||
|
||||
.privacy-card { background: linear-gradient(145deg, #ffffff, #f7f0e6); }
|
||||
|
||||
.step { text-align: left; }
|
||||
.step__icon { width: 34px; height:34px; border-radius: 10px; background: var(--color-accent); color: #fff; display:flex; align-items:center; justify-content:center; font-weight:700; margin-bottom: 8px; }
|
||||
|
||||
.faq details { border:1px solid var(--color-border); border-radius: var(--radius-sm); padding: 10px 12px; background: #fff; }
|
||||
.faq summary { cursor:pointer; font-weight: 600; }
|
||||
.faq p { margin: 8px 0 0 0; color: var(--color-muted); }
|
||||
|
||||
.toast-bar { max-width: var(--maxw); margin: 16px auto; background: #fff; border:1px solid var(--color-border); border-radius: var(--radius-md); padding: 12px 16px; box-shadow: var(--shadow-card); }
|
||||
|
||||
.btn { background: var(--color-primary); color: var(--color-primary-contrast); }
|
||||
.btn:hover { transform: translateY(-1px); transition: transform 120ms ease; }
|
||||
.btn.ghost { border:1px solid var(--color-border); color: var(--color-text); background: #fff; }
|
||||
|
||||
.chip.inline { padding: 6px 10px; }
|
||||
|
||||
.results .card { padding: 0; }
|
||||
.event__body { padding: 16px; display:grid; gap:8px; }
|
||||
.event__meta { display:flex; gap: 12px; flex-wrap: wrap; font-size: 13px; color: var(--color-muted); }
|
||||
.event__tags { display:flex; gap: 6px; flex-wrap: wrap; }
|
||||
.event__access { font-size: 12px; color: var(--color-highlight); font-weight: 700; text-transform: uppercase; letter-spacing: .5px; }
|
||||
|
||||
.label { font-size: 13px; color: var(--color-muted); }
|
||||
.input, .select { border-radius: var(--radius-sm); border-color: var(--color-border); background: #fff; }
|
||||
.input:focus, .select:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.14); }
|
||||
|
||||
.cta-card { background: linear-gradient(135deg, #fdf4e0, #ffffff); }
|
||||
|
||||
.flex { display:flex; }
|
||||
.between { justify-content: space-between; }
|
||||
.center-y { align-items: center; }
|
||||
.gap-12 { gap: 12px; }
|
||||
.stack { display:flex; flex-direction: column; }
|
||||
|
||||
@media (max-width: 720px){
|
||||
.nav-row { padding: 12px 0; }
|
||||
.hero { padding: 40px 0; }
|
||||
.section { padding: 48px 0; }
|
||||
}
|
||||
|
||||
@@ -21,20 +21,21 @@ input, textarea, select { font: inherit; color: inherit; }
|
||||
|
||||
/* 2) Tokens */
|
||||
:root {
|
||||
--color-bg: #f8fafc; /* primary soft */
|
||||
--color-bg: #f7f2ea;
|
||||
--color-surface: #ffffff;
|
||||
--color-border: #e5e7eb; /* slate-200 */
|
||||
--color-muted: #64748b; /* slate-500 */
|
||||
--color-text: #0f172a; /* slate-900 */
|
||||
--color-primary: #111827; /* neutral-900 */
|
||||
--color-border: #e5d8c1;
|
||||
--color-muted: #5f6b7a;
|
||||
--color-text: #26323f;
|
||||
--color-primary: #34485a; /* Basisfarbe */
|
||||
--color-primary-contrast: #ffffff;
|
||||
--color-accent: #f59e0b; /* amber-500 */
|
||||
--color-accent-soft: #fff7ed; /* amber-50 */
|
||||
--color-accent: #e9b049; /* warmes Highlight */
|
||||
--color-accent-soft: #fdf4e0;
|
||||
--color-highlight: #99433f; /* Akzent 2 */
|
||||
--radius-sm: 10px;
|
||||
--radius-md: 14px;
|
||||
--radius-lg: 18px;
|
||||
--shadow-card: 0 1px 2px rgba(0,0,0,0.04), 0 6px 24px rgba(0,0,0,0.06);
|
||||
--maxw: 1100px;
|
||||
--shadow-card: 0 1px 2px rgba(0,0,0,0.04), 0 10px 32px rgba(0,0,0,0.08);
|
||||
--maxw: 1180px;
|
||||
}
|
||||
|
||||
/******************** 3) Utilities ********************/
|
||||
@@ -58,7 +59,7 @@ input, textarea, select { font: inherit; color: inherit; }
|
||||
.clamp-3 { display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
|
||||
|
||||
/******************** 4) Layout ********************/
|
||||
.header { position: sticky; top:0; z-index: 40; backdrop-filter: blur(4px); background: rgba(255,255,255,0.85); border-bottom:1px solid var(--color-border); }
|
||||
.header { position: sticky; top:0; z-index: 40; backdrop-filter: blur(4px); background: rgba(255,255,255,0.9); border-bottom:1px solid var(--color-border); }
|
||||
.header .nav { display:flex; gap:24px; align-items:center; }
|
||||
.header .brand { display:flex; align-items:center; gap:8px; font-weight:600; font-size:18px; letter-spacing: -0.2px; }
|
||||
.header .menu-btn { display:none; border-radius: 10px; padding:8px; }
|
||||
|
||||
@@ -1 +1,206 @@
|
||||
console.log('mini example loaded');
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const body = document.body;
|
||||
const isLoggedIn = body.dataset.auth === '1';
|
||||
const childGender = body.dataset.childGender || '';
|
||||
|
||||
// Logo-Logik
|
||||
const pickLogo = (gender) => {
|
||||
if (gender === 'female') return 'logo_female.png';
|
||||
if (gender === 'male') return 'logo_male.png';
|
||||
return Math.random() < 0.5 ? 'logo_female.png' : 'logo_male.png';
|
||||
};
|
||||
const chosenLogo = pickLogo(childGender);
|
||||
document.querySelectorAll('[data-logo-img]').forEach(img => {
|
||||
img.src = `/assets/bilder/${chosenLogo}`;
|
||||
});
|
||||
|
||||
// Mobile Menü
|
||||
const mobileMenu = document.getElementById('mobileMenu');
|
||||
document.querySelectorAll('.menu-toggle').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
mobileMenu?.classList.toggle('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Scroll zu Events
|
||||
const scrollBtn = document.getElementById('scrollToEvents');
|
||||
if (scrollBtn) {
|
||||
scrollBtn.addEventListener('click', () => {
|
||||
document.getElementById('events')?.scrollIntoView({ behavior: 'smooth' });
|
||||
});
|
||||
}
|
||||
|
||||
// Demo-Events
|
||||
const events = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Spielplatzrunde im Park',
|
||||
teaser: 'Lockeres Treffen mit Kaffee, Sandspielzeug und Picknick.',
|
||||
description: 'Wir treffen uns am großen Spielplatz im Kiez. Bringt Snacks mit, wir teilen. Für alle Altersstufen offen.',
|
||||
city: 'Berlin',
|
||||
zip: '10437',
|
||||
region: 'Prenzlauer Berg',
|
||||
topic: 'outdoor',
|
||||
startsAt: '2025-08-10T10:00:00',
|
||||
allowKids: true,
|
||||
ageGroup: 'kids',
|
||||
visibility: 'public',
|
||||
contact: 'papa-berlin@example.com',
|
||||
locationLabel: 'Mauerpark',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Väter-Kaffee & Austausch',
|
||||
teaser: 'Elternzeit, Job, Schlaf – wir reden über alles.',
|
||||
description: 'Reservierter Tisch im Café. Fokus auf Austausch unter Vätern, Kinder optional.',
|
||||
city: 'Hamburg',
|
||||
zip: '22767',
|
||||
region: 'Altona',
|
||||
topic: 'kaffee',
|
||||
startsAt: '2025-08-12T19:00:00',
|
||||
allowKids: false,
|
||||
ageGroup: '',
|
||||
visibility: 'members',
|
||||
contact: 'altona-dads@example.com',
|
||||
locationLabel: 'Café Elbseite',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Sport & Spiel im Park',
|
||||
teaser: 'Ballspiele und leichtes Workout, Kinder toben mit.',
|
||||
description: 'Wir bringen Bälle und Slackline. Warm-up, danach freies Spiel. Bitte Wasser mitbringen.',
|
||||
city: 'München',
|
||||
zip: '80804',
|
||||
region: 'Schwabing',
|
||||
topic: 'sport',
|
||||
startsAt: '2025-08-15T11:00:00',
|
||||
allowKids: true,
|
||||
ageGroup: 'school',
|
||||
visibility: 'public',
|
||||
contact: 'schwabing-sport@example.com',
|
||||
locationLabel: 'Luitpoldpark',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Workshop: Erste Hilfe für Kids',
|
||||
teaser: 'Erste Hilfe Basics speziell für Kinder-Unfälle.',
|
||||
description: 'Zertifizierter Trainer, kleiner Materialbeitrag. Kinder können mitgebracht werden.',
|
||||
city: 'Köln',
|
||||
zip: '50667',
|
||||
region: 'Innenstadt',
|
||||
topic: 'workshop',
|
||||
startsAt: '2025-08-20T18:30:00',
|
||||
allowKids: true,
|
||||
ageGroup: 'kids',
|
||||
visibility: 'members',
|
||||
contact: 'koeln-workshop@example.com',
|
||||
locationLabel: 'Familienzentrum Mitte',
|
||||
},
|
||||
];
|
||||
|
||||
const state = { topic: 'all', age: '', region: '', query: '' };
|
||||
const el = {
|
||||
list: document.getElementById('eventList'),
|
||||
chips: document.querySelectorAll('[data-filter]'),
|
||||
locInput: document.getElementById('locInput'),
|
||||
topicSelect: document.getElementById('topicSelect'),
|
||||
ageSelect: document.getElementById('ageSelect'),
|
||||
btnSearch: document.getElementById('btnSearch'),
|
||||
btnGeo: document.getElementById('btnGeo'),
|
||||
};
|
||||
|
||||
const fmtDate = (iso) => {
|
||||
const d = new Date(iso);
|
||||
return d.toLocaleDateString('de-DE', { weekday: 'short', day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' });
|
||||
};
|
||||
|
||||
const tag = (label) => `<span class="badge">${label}</span>`;
|
||||
|
||||
const renderCard = (item) => {
|
||||
const guest = !isLoggedIn;
|
||||
const access = item.visibility === 'members' && guest ? '<div class="event__access">Nur für Mitglieder</div>' : '';
|
||||
const desc = guest ? `<p class="muted">Melde dich an, um die volle Beschreibung zu sehen.</p>` : `<p>${item.description}</p>`;
|
||||
const contact = !guest ? `<div class="muted small">Kontakt: ${item.contact}</div>` : '';
|
||||
const kids = item.allowKids ? 'Mit Kindern' : 'Ohne Kinder';
|
||||
const tags = [
|
||||
tag(item.topic === 'kaffee' ? 'Kaffee & Austausch' : item.topic.charAt(0).toUpperCase() + item.topic.slice(1)),
|
||||
tag(kids),
|
||||
item.ageGroup ? tag(`Alter: ${item.ageGroup}`) : '',
|
||||
].filter(Boolean).join('');
|
||||
|
||||
return `
|
||||
<article class="card">
|
||||
<div class="event__body">
|
||||
${access}
|
||||
<div class="event__meta">
|
||||
<span>${fmtDate(item.startsAt)}</span>
|
||||
<span>📍 ${item.region || item.city}</span>
|
||||
<span>${item.visibility === 'public' ? 'Öffentlich' : 'Mitglieder'}</span>
|
||||
</div>
|
||||
<h3>${item.title}</h3>
|
||||
<p class="muted">${guest ? item.teaser : item.description.slice(0, 140) + '...'}</p>
|
||||
${guest ? '' : desc}
|
||||
<div class="event__tags">${tags}</div>
|
||||
${contact}
|
||||
<div class="flex gap-12">
|
||||
<button class="btn ghost">Details</button>
|
||||
${!guest ? '<button class="btn">Teilnehmen</button>' : '<button class="btn">Anmelden</button>'}
|
||||
</div>
|
||||
</div>
|
||||
</article>`;
|
||||
};
|
||||
|
||||
const matchesFilter = (ev) => {
|
||||
const topicOk = state.topic === 'all' || state.topic === ev.topic;
|
||||
const ageOk = !state.age || ev.ageGroup === state.age || (state.age === 'baby' && ev.ageGroup === 'kids'); // simple fallback
|
||||
const regionOk = !state.region || ev.region.toLowerCase().includes(state.region) || ev.city.toLowerCase().includes(state.region) || ev.zip.startsWith(state.region);
|
||||
const queryOk = !state.query || (ev.title + ev.teaser + ev.description + ev.city + ev.region).toLowerCase().includes(state.query);
|
||||
return topicOk && ageOk && regionOk && queryOk;
|
||||
};
|
||||
|
||||
const renderEvents = () => {
|
||||
if (!el.list) return;
|
||||
const filtered = events.filter(matchesFilter);
|
||||
el.list.innerHTML = filtered.map(renderCard).join('') || '<p class="muted">Keine Events gefunden.</p>';
|
||||
};
|
||||
|
||||
if (el.chips.length > 0) {
|
||||
el.chips[0].classList.add('active');
|
||||
}
|
||||
|
||||
el.chips.forEach(chip => {
|
||||
chip.addEventListener('click', () => {
|
||||
el.chips.forEach(c => c.classList.remove('active'));
|
||||
chip.classList.add('active');
|
||||
state.topic = chip.dataset.filter;
|
||||
renderEvents();
|
||||
});
|
||||
});
|
||||
|
||||
if (el.btnSearch) {
|
||||
el.btnSearch.addEventListener('click', () => {
|
||||
state.region = (el.locInput?.value || '').trim().toLowerCase();
|
||||
state.topic = el.topicSelect?.value || 'all';
|
||||
state.age = el.ageSelect?.value || '';
|
||||
renderEvents();
|
||||
});
|
||||
}
|
||||
|
||||
if (el.btnGeo) {
|
||||
el.btnGeo.addEventListener('click', () => {
|
||||
if (!navigator.geolocation) {
|
||||
alert('Geolocation wird nicht unterstützt.');
|
||||
return;
|
||||
}
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
() => {
|
||||
state.region = 'nähe';
|
||||
renderEvents();
|
||||
},
|
||||
() => alert('Standort konnte nicht ermittelt werden.')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
renderEvents();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user