V-US-01-02: Leistungsübersicht mit 3 Paketen umgesetzt

feature/V-US-01-02-leistungsuebersicht
Vincent Laux 2026-09-24 17:13:19 +02:00
parent ad94836432
commit fa4c5ac520
6 changed files with 293 additions and 1 deletions

BIN
.DS_Store vendored 100644

Binary file not shown.

194
css/style.css 100644
View File

@ -0,0 +1,194 @@
/* ==========================================================
tri-hub.de – Design-DNA (Block 4, Projekt-Kickoff)
Hintergrund: #0d0d1a / #1a1a2e
Akzent: #10B981 (Teal / Emerald Green)
Primärtext: #ffffff / #F8FAFC / #94A3B8
Typografie: Playfair Display (Display) + Inter (Body)
Ton: Du-Ansprache, Premium, direkt
========================================================== */
:root {
--bg-dark: #0d0d1a;
--bg-panel: #1a1a2e;
--accent: #10B981;
--accent-soft: rgba(16, 185, 129, 0.12);
--text-primary: #ffffff;
--text-secondary: #F8FAFC;
--text-muted: #94A3B8;
--font-display: "Inter", system-ui, sans-serif;
--font-body: "Inter", system-ui, sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--bg-dark);
color: var(--text-secondary);
font-family: var(--font-body);
}
/* ---------- Leistungsübersicht ---------- */
.pakete {
padding: 5rem 1.5rem;
max-width: 1120px;
margin: 0 auto;
}
.pakete__intro {
text-align: center;
max-width: 42rem;
margin: 0 auto 3rem;
}
.pakete__titel {
font-family: var(--font-display);
font-weight: 700;
font-size: clamp(1.8rem, 3vw, 2.4rem);
color: var(--text-primary);
margin: 0 0 0.75rem;
}
.pakete__text {
color: var(--text-muted);
line-height: 1.6;
margin: 0;
}
/* Kästchen nebeneinander, jede Karte für sich */
.pakete__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
align-items: stretch;
}
.paket-karte {
display: flex;
flex-direction: column;
background: var(--bg-panel);
border: 1px solid rgba(248, 250, 252, 0.08);
border-radius: 14px;
padding: 2rem 1.75rem;
position: relative;
}
.paket-karte--empfohlen {
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent-soft);
}
.paket-karte--ausgewaehlt {
border-color: var(--accent);
box-shadow: 0 0 0 2px var(--accent);
}
.paket-karte__badge {
position: absolute;
top: -0.7rem;
left: 1.75rem;
background: var(--accent);
color: var(--bg-dark);
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.75rem;
border-radius: 999px;
margin: 0;
}
.paket-karte__name {
font-family: var(--font-display);
font-weight: 600;
font-size: 1.4rem;
color: var(--text-primary);
margin: 0 0 0.5rem;
}
.paket-karte__preis {
margin: 0 0 0.75rem;
display: flex;
align-items: baseline;
gap: 0.35rem;
}
.paket-karte__betrag {
font-family: var(--font-display);
font-size: 2rem;
font-weight: 700;
color: var(--text-primary);
}
.paket-karte__zeitraum {
color: var(--text-muted);
font-size: 0.9rem;
}
.paket-karte__beschreibung {
color: var(--text-muted);
line-height: 1.55;
margin: 0 0 1.5rem;
min-height: 3.3em;
}
.paket-karte__leistungen {
list-style: none;
margin: 0 0 2rem;
padding: 0;
flex-grow: 1;
}
.paket-karte__leistungen li {
position: relative;
padding-left: 1.4rem;
margin-bottom: 0.7rem;
line-height: 1.4;
color: var(--text-secondary);
}
.paket-karte__leistungen li::before {
content: "";
position: absolute;
left: 0;
top: 0.5em;
width: 8px;
height: 8px;
border-radius: 2px;
background: var(--accent);
}
.paket-karte__cta {
font-family: var(--font-body);
font-weight: 600;
font-size: 0.95rem;
color: var(--bg-dark);
background: var(--accent);
border: none;
border-radius: 8px;
padding: 0.85rem 1rem;
cursor: pointer;
transition: filter 0.15s ease;
}
.paket-karte__cta:hover,
.paket-karte__cta:focus-visible {
filter: brightness(1.1);
}
.paket-karte__cta:focus-visible {
outline: 2px solid var(--text-primary);
outline-offset: 2px;
}
@media (max-width: 860px) {
.pakete__grid {
grid-template-columns: 1fr;
}
.paket-karte--empfohlen {
order: -1;
}
}

View File

@ -5,10 +5,81 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ernährungsberater</title> <title>Ernährungsberater</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
</head> </head>
<body> <body>
<!-- US-01-02 Leistungsübersicht -->
<section id="leistungen" class="pakete">
<div class="pakete__intro">
<h2 class="pakete__titel">Deine Pakete</h2>
<p class="pakete__text">
Drei Wege zu einer Ernährung, die zu deinem Training, deinem Alltag und
deinem Alter passt &ndash; entwickelt für Triathletinnen und Triathleten ab 50.
</p>
</div>
<div class="pakete__grid">
<article class="paket-karte">
<h3 class="paket-karte__name">Starter</h3>
<p class="paket-karte__preis">
<span class="paket-karte__betrag">79&nbsp;&euro;</span>
<span class="paket-karte__zeitraum">/ Monat</span>
</p>
<p class="paket-karte__beschreibung">Für den Einstieg in eine bewusste Ernährung neben dem Training.</p>
<ul class="paket-karte__leistungen">
<li>Erstgespräch &amp; Bedarfsanalyse</li>
<li>Individueller Ernährungsplan</li>
<li>Monatliches Check-in per E-Mail</li>
<li>Zugang zu Beispielplänen</li>
</ul>
<button class="paket-karte__cta" type="button" data-paket="Starter">Paket wählen</button>
</article>
<article class="paket-karte paket-karte--empfohlen">
<p class="paket-karte__badge">Beliebteste Wahl</p>
<h3 class="paket-karte__name">STANDART</h3>
<p class="paket-karte__preis">
<span class="paket-karte__betrag">149&nbsp;&euro;</span>
<span class="paket-karte__zeitraum">/ Monat</span>
</p>
<p class="paket-karte__beschreibung">Laufende Begleitung für alle, die regelmäßig für Wettkämpfe trainieren.</p>
<ul class="paket-karte__leistungen">
<li>Alles aus Starter</li>
<li>Plan-Anpassung je Trainingsphase</li>
<li>Zwei Beratungsgespräche pro Monat</li>
<li>Wettkampf-Ernährungsstrategie</li>
<li>Direkter Chat mit deiner Beraterin</li>
</ul>
<button class="paket-karte__cta" type="button" data-paket="Ausdauer">Paket wählen</button>
</article>
<article class="paket-karte">
<h3 class="paket-karte__name">Rundum Sorglos Paket</h3>
<p class="paket-karte__preis">
<span class="paket-karte__betrag">249&nbsp;&euro;</span>
<span class="paket-karte__zeitraum">/ Monat</span>
</p>
<p class="paket-karte__beschreibung">Volle Betreuung für ambitionierte Athletinnen und Athleten.</p>
<ul class="paket-karte__leistungen">
<li>Alles aus Ausdauer</li>
<li>Wöchentliche Beratungsgespräche</li>
<li>Individuelle Supplement-Empfehlung</li>
<li>Betreuung am Wettkampftag</li>
<li>Priorisierter Support</li>
</ul>
<button class="paket-karte__cta" type="button" data-paket="Wettkampf">Paket wählen</button>
</article>
</div>
</section>
<script src="js/script.js"></script>
</body> </body>
</html> </html>

27
js/script.js 100644
View File

@ -0,0 +1,27 @@
// US-01-02 Leistungsübersicht
// Markiert das gewählte Paket visuell und stellt die Auswahl bereit,
// damit US-01-03 (Pakete online buchen) später darauf aufbauen kann.
document.addEventListener("DOMContentLoaded", () => {
const karten = document.querySelectorAll(".paket-karte");
karten.forEach((karte) => {
const button = karte.querySelector(".paket-karte__cta");
if (!button) return;
button.addEventListener("click", () => {
karten.forEach((k) => k.classList.remove("paket-karte--ausgewaehlt"));
karte.classList.add("paket-karte--ausgewaehlt");
const paketName = button.dataset.paket;
// Andere Skripte (z. B. die Buchungsstrecke aus US-01-03)
// können auf dieses Event hören, statt den DOM abzufragen.
document.dispatchEvent(
new CustomEvent("paket:ausgewaehlt", { detail: { paket: paketName } })
);
console.log(`Paket "${paketName}" ausgewählt.`);
});
});
});

View File

View File