Compare commits

..

10 Commits

Author SHA1 Message Date
Daniel Fromm 9066763ec6 Merge pull request 'Sprint 1: Landing Page Ernährungsberatung (US01-01 bis US01-03)' (#5) from dev into main
Reviewed-on: https://gitty.informatik.th-mannheim.de/3015351/PM_Project/pulls/5
2026-09-24 18:13:09 +02:00
Daniel Fromm 350040fe61 Merge pull request 'US01-03: Ablauf in 4 Schritten (+ Fix Paketkarten Tablet)' (#4) from feature_US01-03 into dev
Reviewed-on: https://gitty.informatik.th-mannheim.de/3015351/PM_Project/pulls/4
2026-09-24 17:48:47 +02:00
Kevin Kopp 7d732e0937 Fix US01-02: Paketkarten laufen bei Tablet-Breite nicht mehr über 2026-09-24 17:41:39 +02:00
Kevin Kopp 69b0186ada US01-03: Ablauf in 4 Schritten mit Abschluss-Link zu den Angeboten 2026-09-24 17:41:16 +02:00
Daniel Fromm 0f48f2637e Merge pull request 'US01-02: 3 Pakete mit Detaildialog und Verweis auf Coaching-Rabatte' (#3) from feature_US01-02 into dev
Reviewed-on: https://gitty.informatik.th-mannheim.de/3015351/PM_Project/pulls/3
2026-09-24 17:30:36 +02:00
Kevin Kopp 07bf86f818 US01-02: 3 Pakete mit Detaildialog und Verweis auf Coaching-Rabatte 2026-09-24 17:23:24 +02:00
Kevin Alexander Kopp b41b3cbc3e Merge pull request 'US01-01: Hero mit Angebot, Zielgruppe und 3 Vorteilen' (#2) from feature_US01-01 into dev
Reviewed-on: https://gitty.informatik.th-mannheim.de/3015351/PM_Project/pulls/2
2026-09-24 17:16:56 +02:00
Kevin Kopp 8233ed5dcb US01-01: 3 Vorteile mit Überschrift unter dem Hero ergänzt 2026-09-24 17:07:01 +02:00
Kevin Kopp d6fe2f9288 US01-01: Hero mit Angebot, Zielgruppe, Bild und Button zu Vorteilen 2026-09-24 16:54:58 +02:00
Kevin Kopp 8ead245453 Setup: Grundgerüst mit leeren Sektionen für US01-01 bis US01-03 2026-09-24 16:29:29 +02:00
13 changed files with 1260 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

View File

95
css/base.css 100644
View File

@ -0,0 +1,95 @@
/* =========================================================
base.css – gemeinsame Basis für alle Features
Änderungen hier nur über eigenen Branch (betrifft alle!)
========================================================= */
/* ---------- Design-Tokens laut tri-hub Design-DNA ---------- */
:root {
/* Hintergrund: tiefes Dunkelblau / Schwarz */
--th-bg: #0d0d1a;
--th-bg-elevated: #1a1a2e;
/* Akzent: Teal / Emerald Green – CTAs, Icons, Highlights */
--th-accent: #10b981;
/* Text: Weiß / Hellgrau */
--th-text: #ffffff;
--th-text-soft: #f8fafc;
--th-text-muted: #94a3b8;
/* Typografie: Serif Display + Sans-Serif Body */
--th-font-display: "Playfair Display", Georgia, serif;
--th-font-body: "Inter", system-ui, sans-serif;
/* Lesbarkeit Zielgruppe 50+ (Definition of Done) */
--th-font-size-body: 1.125rem; /* 18px */
--th-line-height: 1.65;
/* Abstände / Radien für alle Sektionen */
--th-section-space: 5rem;
--th-radius: 1.4rem;
}
/* ---------- Grundlayout ---------- */
body {
background: var(--th-bg);
color: var(--th-text-soft);
font-family: var(--th-font-body);
font-size: var(--th-font-size-body);
line-height: var(--th-line-height);
}
h1, h2, h3 {
font-family: var(--th-font-display);
color: var(--th-text);
letter-spacing: -0.01em;
}
main > section {
padding-block: var(--th-section-space);
}
/* Anker nicht unter dem Header verstecken */
section[id] {
scroll-margin-top: 5rem;
}
/* ---------- Header ---------- */
.site-header {
position: sticky;
top: 0;
z-index: 40;
background: rgb(13 13 26 / 0.85);
backdrop-filter: blur(12px);
border-bottom: 1px solid rgb(255 255 255 / 0.08);
}
.site-header .container {
display: flex;
align-items: center;
justify-content: space-between;
padding-block: 1rem;
}
.site-logo {
font-family: var(--th-font-display);
font-size: 1.5rem;
font-weight: 700;
color: var(--th-text);
}
/* ---------- Barrierefreiheit ---------- */
a:focus-visible,
button:focus-visible {
outline: 3px solid var(--th-accent);
outline-offset: 4px;
border-radius: 0.5rem;
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}

View File

@ -0,0 +1,142 @@
/* =========================================================
US01-03: Ablauf sehen
Branch: feature_US01-03
Nur Selektoren unter #ablauf verwenden.
Farben/Schriften über var(--th-...) aus base.css.
Vorlage: Prototyp (Programmablauf)
========================================================= */
#ablauf {
--abl-mint: #56d9b1;
--abl-line: rgb(255 255 255 / 0.11);
}
/* ---------- Überschrift ---------- */
#ablauf .ablauf-heading {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 3.5rem;
margin-bottom: 2.75rem;
}
#ablauf .ablauf-eyebrow {
margin: 0;
font-size: 0.875rem;
font-weight: 650;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--abl-mint);
}
#ablauf h2 {
margin: 0.9rem 0 0;
font-size: clamp(2.2rem, 3.4vw, 2.8rem);
font-weight: 400;
line-height: 1.12;
letter-spacing: -0.03em;
}
#ablauf .ablauf-heading > p {
max-width: 24rem;
margin: 0;
color: var(--th-text-muted);
}
/* ---------- Schritte ---------- */
#ablauf .steps {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 2rem;
margin: 0;
padding: 0;
list-style: none;
}
#ablauf .step-number {
display: block;
margin-bottom: 1.4rem;
padding: 0.5rem 0 1.1rem;
border-bottom: 1px solid var(--abl-line);
font-family: var(--th-font-display);
font-size: 2rem;
line-height: 1;
color: var(--abl-mint);
position: relative;
}
/* grüner Fortschrittsstrich unter der Nummer zeigt die Reihenfolge */
#ablauf .step-number::after {
content: "";
position: absolute;
left: 0;
bottom: -1px;
width: 2.5rem;
height: 2px;
background: var(--th-accent);
}
#ablauf .step h3 {
margin: 0 0 0.75rem;
font-family: var(--th-font-body);
font-size: 1.25rem;
font-weight: 600;
line-height: 1.3;
}
#ablauf .step p {
margin: 0;
color: var(--th-text-muted);
}
/* ---------- Abschluss ---------- */
#ablauf .process-end {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1.5rem;
margin-top: 2.75rem;
padding-top: 1.9rem;
border-top: 1px solid var(--abl-line);
}
#ablauf .process-end p {
margin: 0;
font-family: var(--th-font-display);
font-size: 1.45rem;
font-style: italic;
color: #d3d7e1;
}
#ablauf .process-link {
display: inline-flex;
align-items: center;
gap: 0.75rem;
min-height: 2.75rem;
font-size: 1.125rem;
font-weight: 600;
color: var(--th-text-soft);
white-space: nowrap;
}
#ablauf .process-link:hover {
color: var(--abl-mint);
}
/* ---------- Tablet: 2 × 2 ---------- */
@media (max-width: 1100px) {
#ablauf .ablauf-heading { gap: 2rem; }
#ablauf .steps { grid-template-columns: repeat(2, 1fr); gap: 2rem 1.75rem; }
}
/* ---------- Mobil: untereinander ---------- */
@media (max-width: 760px) {
#ablauf .ablauf-heading { display: block; margin-bottom: 2rem; }
#ablauf .ablauf-heading > p { max-width: none; margin-top: 1.25rem; }
#ablauf .process-end { display: block; }
#ablauf .process-link { margin-top: 1rem; }
}
@media (max-width: 560px) {
#ablauf .steps { grid-template-columns: 1fr; gap: 1.75rem; }
}

View File

@ -0,0 +1,381 @@
/* =========================================================
US01-02: Angebote und Pakete (+ Verweis auf Coaching-Rabatte)
Branch: feature_US01-02
Nur Selektoren unter #angebote verwenden.
Farben/Schriften über var(--th-...) aus base.css.
Vorlage: Prototyp (Angebotsbereich + Detaildialog)
========================================================= */
#angebote {
--ang-mint: #56d9b1;
--ang-line: rgb(255 255 255 / 0.11);
background: linear-gradient(135deg, #161625, #11111e);
border-block: 1px solid var(--ang-line);
}
/* ---------- Überschrift ---------- */
#angebote .angebote-heading {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 3.5rem;
margin-bottom: 1.5rem;
}
#angebote .angebote-eyebrow {
margin: 0;
font-size: 0.875rem;
font-weight: 650;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ang-mint);
}
#angebote h2 {
margin: 0.9rem 0 0;
font-size: clamp(2.2rem, 3.4vw, 2.8rem);
font-weight: 400;
line-height: 1.12;
letter-spacing: -0.03em;
}
#angebote .angebote-heading > p {
max-width: 24rem;
margin: 0;
color: var(--th-text-muted);
}
#angebote .concept-note {
display: flex;
gap: 0.5rem;
margin: 0 0 2rem;
font-size: 1rem;
color: var(--th-text-muted);
}
/* ---------- Paketkarten ---------- */
#angebote .package-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr)); /* minmax(0,…) verhindert Überlaufen */
gap: 1.5rem;
}
#angebote .package {
display: flex;
flex-direction: column;
padding: 0.75rem;
border: 1px solid var(--ang-line);
border-radius: 18px;
background: linear-gradient(140deg, #202032, #181827);
transition: border-color 0.2s;
}
#angebote .package:hover,
#angebote .package.featured {
border-color: rgb(16 185 129 / 0.45);
}
#angebote .package-image {
position: relative;
overflow: hidden;
border-radius: 10px;
}
#angebote .package-image img {
width: 100%;
aspect-ratio: 1.65;
object-fit: cover;
transition: transform 0.4s;
}
#angebote .package:hover img {
transform: scale(1.03);
}
#angebote .package-badge {
position: absolute;
left: 0.75rem;
bottom: 0.75rem;
padding: 0.45rem 0.75rem;
border-radius: 5px;
background: var(--th-accent);
color: #06261a;
font-size: 0.75rem;
font-weight: 750;
letter-spacing: 0.08em;
text-transform: uppercase;
}
#angebote .package-body {
display: flex;
flex-direction: column;
flex: 1;
padding: 1.5rem 0.9rem 0.9rem;
}
#angebote .package-label {
margin: 0;
font-size: 0.875rem;
font-weight: 650;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ang-mint);
}
#angebote .package-body h3 {
margin: 0.8rem 0 1rem;
font-size: 1.9rem;
font-weight: 400;
line-height: 1.15;
}
#angebote .package-text {
margin: 0;
color: var(--th-text-muted);
}
#angebote .package-body ul {
flex: 1;
margin: 1.25rem 0 0;
padding: 1.25rem 0 1.5rem;
list-style: none;
border-top: 1px solid var(--ang-line);
}
#angebote .package-body li {
position: relative;
padding: 0.3rem 0 0.3rem 1.5rem;
}
#angebote .package-body li::before {
content: "✓";
position: absolute;
left: 0;
color: var(--ang-mint);
}
/* ---------- Buttons ---------- */
#angebote .package-button,
#angebote .dialog-done {
display: inline-flex;
align-items: center;
justify-content: space-between;
width: 100%;
min-height: 3.25rem;
padding: 0.9rem 1rem;
border: 1px solid rgb(255 255 255 / 0.15);
border-radius: 7px;
background: transparent;
color: var(--th-text-soft);
font-size: 1.0625rem;
font-weight: 650;
cursor: pointer;
transition: background 0.2s, border-color 0.2s;
}
#angebote .package-button:hover {
border-color: var(--th-accent);
background: rgb(16 185 129 / 0.08);
}
#angebote .package-button.is-primary,
#angebote .dialog-done {
border-color: transparent;
background: var(--th-accent);
color: #071b16;
}
#angebote .package-button.is-primary:hover,
#angebote .dialog-done:hover {
background: #37c99b;
}
/* ---------- Coaching-Rabatt ---------- */
#angebote .coaching-banner {
display: flex;
align-items: center;
gap: 1.5rem;
margin-top: 1.75rem;
padding: 1.6rem 1.9rem;
border: 1px solid rgb(16 185 129 / 0.19);
border-radius: 12px;
background: rgb(16 185 129 / 0.04);
}
#angebote .bonus-symbol {
padding-right: 1.5rem;
border-right: 1px solid rgb(16 185 129 / 0.25);
font-family: var(--th-font-display);
font-size: 2.2rem;
color: var(--ang-mint);
}
#angebote .coaching-banner h3 {
margin: 0 0 0.3rem;
font-family: var(--th-font-body);
font-size: 1.2rem;
font-weight: 600;
}
#angebote .coaching-banner p {
margin: 0;
color: var(--th-text-muted);
}
#angebote .bonus-button {
margin-left: auto;
min-height: 2.75rem;
border: 0;
background: none;
color: var(--ang-mint);
font-size: 1.0625rem;
font-weight: 600;
white-space: nowrap;
cursor: pointer;
}
/* ---------- Dialog ---------- */
#angebote dialog {
margin: auto; /* Kunden-CSS setzt margin:0 → Dialog wieder zentrieren */
width: min(680px, calc(100% - 2rem));
max-height: 90dvh;
padding: 0;
border: 1px solid rgb(255 255 255 / 0.15);
border-radius: 20px;
background: #171726;
color: var(--th-text-soft);
box-shadow: 0 30px 100px rgb(0 0 0 / 0.55);
}
#angebote dialog::backdrop {
background: rgb(5 5 11 / 0.8);
backdrop-filter: blur(6px);
}
#angebote .dialog-inner {
position: relative;
padding: 2.5rem;
}
#angebote .close-dialog {
position: absolute;
top: 0.75rem;
right: 1rem;
width: 2.75rem;
height: 2.75rem;
border: 0;
background: transparent;
color: var(--th-text-muted);
font-size: 1.9rem;
cursor: pointer;
}
#angebote .dialog-inner h2 {
margin: 0.8rem 2.2rem 1.1rem 0;
font-size: 2.2rem;
}
#angebote #dialog-description {
margin: 0;
color: var(--th-text-muted);
}
#angebote .dialog-inner h3 {
margin: 1.6rem 0 0.75rem;
font-family: var(--th-font-body);
font-size: 1.2rem;
font-weight: 600;
}
#angebote #dialog-features {
margin: 0;
padding-left: 1.25rem;
}
#angebote #dialog-features li {
padding: 0.25rem 0;
}
#angebote .dialog-hint {
margin: 0.75rem 0 0;
font-size: 1rem;
color: var(--th-text-muted);
}
#angebote .discount-box {
margin: 1.6rem 0;
padding: 1.4rem;
border: 1px solid rgb(16 185 129 / 0.27);
border-radius: 12px;
background: rgb(16 185 129 / 0.035);
}
#angebote .discount-box h3 {
margin-top: 0.4rem;
}
#angebote .discount-box label {
display: block;
margin-bottom: 0.5rem;
}
#angebote .discount-box select {
width: 100%;
padding: 0.75rem;
border: 1px solid rgb(255 255 255 / 0.25);
border-radius: 7px;
background: #11111f;
color: var(--th-text-soft);
font-size: 1.0625rem;
}
#angebote #discount-result {
margin: 0;
padding: 1rem 0 0;
color: var(--ang-mint);
}
#angebote #discount-result strong {
font-size: 1.6rem;
}
#angebote .discount-box a {
display: inline-block;
margin-top: 0.9rem;
color: var(--ang-mint);
}
#angebote select:focus-visible {
outline: 3px solid var(--th-accent);
outline-offset: 3px;
}
/* ---------- Tablet ---------- */
@media (max-width: 1100px) {
#angebote .angebote-heading { gap: 2rem; }
#angebote .package-body h3 { font-size: 1.7rem; }
#angebote .coaching-banner { flex-wrap: wrap; }
#angebote .bonus-button { margin-left: 0; }
}
/* ---------- schmale Tablets: 2 Karten nebeneinander ---------- */
@media (max-width: 1000px) {
#angebote .package-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* ---------- Mobil ---------- */
@media (max-width: 760px) {
#angebote .angebote-heading { display: block; }
#angebote .angebote-heading > p { max-width: none; margin-top: 1.25rem; }
#angebote .package-grid { grid-template-columns: 1fr; }
#angebote .package-image img { aspect-ratio: 1.8; }
#angebote .coaching-banner { padding: 1.4rem; gap: 1rem; }
#angebote .coaching-banner > div:nth-child(2) { flex: 1; min-width: 12rem; }
#angebote .bonus-symbol { display: none; }
#angebote .dialog-inner { padding: 2rem 1.4rem; }
#angebote .dialog-inner h2 { font-size: 1.9rem; }
}
@media (prefers-reduced-motion: reduce) {
#angebote .package img { transition: none; }
}

View File

@ -0,0 +1,264 @@
/* =========================================================
US01-01: Angebot und Zielgruppe sofort sehen (Hero)
Branch: feature_US01-01
Nur Selektoren unter #hero verwenden.
Farben/Schriften über var(--th-...) aus base.css.
Vorlage: Prototyp (Hero-Bereich)
========================================================= */
#hero {
--hero-mint: #56d9b1; /* helle Akzentvariante aus dem Prototyp */
--hero-line: rgb(255 255 255 / 0.11);
padding-block: clamp(1.5rem, 4svh, 3.5rem); /* überschreibt Sektionsabstand aus base.css */
min-height: calc(100svh - 4.5rem); /* ohne Scrollen sichtbar (minus Header) */
display: flex;
align-items: center;
}
#hero .hero-grid {
display: grid;
grid-template-columns: 1.08fr 1fr;
gap: 4rem;
align-items: center;
width: 100%;
}
/* ---------- Text ---------- */
#hero h1 {
margin: 0;
font-weight: 400;
}
#hero .hero-kicker {
display: flex;
align-items: center;
gap: 0.75rem;
font-family: var(--th-font-body);
font-size: 1rem;
font-weight: 650;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--hero-mint);
line-height: 1.5;
}
#hero .hero-line {
flex: 0 0 1.5rem;
height: 1px;
background: var(--th-accent);
}
#hero .hero-headline {
display: block;
margin-top: 1.5rem;
font-family: var(--th-font-display);
font-size: clamp(2.6rem, 4.8vw, 4.5rem);
line-height: 1.1;
letter-spacing: -0.03em;
color: var(--th-text);
}
#hero .hero-headline em {
color: var(--hero-mint);
}
#hero .hero-intro {
margin-top: 1.5rem;
max-width: 32rem;
font-size: 1.1875rem;
line-height: 1.75;
color: var(--th-text-muted);
}
/* ---------- Aktionen ---------- */
#hero .hero-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1.75rem;
margin-top: 2rem;
}
#hero .hero-button {
display: inline-flex;
align-items: center;
gap: 1.25rem;
min-height: 3.25rem; /* große Klickfläche */
padding: 0.9rem 1.6rem;
border-radius: 7px;
background: var(--th-accent);
color: #071b16;
font-size: 1.125rem;
font-weight: 650;
transition: background 0.2s, transform 0.2s;
}
#hero .hero-button:hover {
background: #37c99b;
transform: translateY(-2px);
}
#hero .hero-link {
display: inline-flex;
align-items: center;
gap: 0.75rem;
min-height: 2.75rem;
font-size: 1.125rem;
font-weight: 600;
color: var(--th-text-soft);
}
#hero .hero-link:hover {
color: var(--hero-mint);
}
/* ---------- Bild ---------- */
#hero .hero-visual {
position: relative;
margin: 0;
height: clamp(320px, 52svh, 540px);
border-radius: 15px;
overflow: hidden;
background: var(--th-bg-elevated);
}
#hero .hero-visual img {
width: 100%;
height: 100%;
object-fit: cover;
}
#hero .hero-visual::after { /* Verlauf für lesbare Bildunterschrift */
content: "";
position: absolute;
inset: 35% 0 0;
background: linear-gradient(transparent, rgb(5 15 18 / 0.94));
}
#hero figcaption {
position: absolute;
left: 2rem;
bottom: 2rem;
z-index: 1;
}
#hero .hero-caption-label {
display: block;
font-size: 0.8rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #b5efda;
}
#hero .hero-caption-text {
display: block;
margin-top: 0.6rem;
font-family: var(--th-font-display);
font-size: 1.75rem;
line-height: 1.3;
color: var(--th-text);
}
#hero .hero-tag {
position: absolute;
top: 1.25rem;
right: 1.25rem;
padding: 0.75rem 1rem;
border: 1px solid rgb(255 255 255 / 0.19);
border-radius: 8px;
background: rgb(13 13 26 / 0.8);
backdrop-filter: blur(12px);
font-size: 0.7rem;
letter-spacing: 0.1em;
text-transform: uppercase;
text-align: center;
color: var(--th-text-soft);
}
#hero .hero-tag b {
display: block;
margin-top: 0.25rem;
font-family: var(--th-font-display);
font-size: 2rem;
line-height: 1.1;
letter-spacing: 0;
color: var(--hero-mint);
}
/* ---------- 3 Vorteile unter dem Hero ---------- */
#hero .hero-benefits {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
margin: 2.5rem 0 0;
padding: 1.5rem 0 0;
list-style: none;
border-top: 1px solid var(--hero-line);
}
#hero .hero-benefits li {
display: flex;
gap: 1rem;
align-items: flex-start;
}
#hero .hero-benefit-icon {
flex: 0 0 2.5rem;
display: flex;
align-items: center;
justify-content: center;
height: 2.5rem;
border-radius: 10px;
background: rgb(16 185 129 / 0.1);
color: var(--hero-mint);
font-size: 1.3rem;
}
#hero .hero-benefits h2 {
margin: 0;
font-family: var(--th-font-body);
font-size: 1.125rem;
font-weight: 600;
line-height: 1.35;
letter-spacing: -0.01em;
color: var(--th-text);
}
#hero .hero-benefits p {
margin: 0.3rem 0 0;
font-size: 1rem;
line-height: 1.55;
color: var(--th-text-muted);
}
/* ---------- Tablet ---------- */
@media (max-width: 1100px) {
#hero .hero-grid { gap: 2rem; }
#hero .hero-benefits { gap: 1.25rem; }
}
/* ---------- Mobil: Text zuerst, Bild darunter ---------- */
@media (max-width: 760px) {
#hero {
min-height: 0;
padding-block: 2rem 3rem;
}
#hero .hero-grid {
grid-template-columns: 1fr;
gap: 2rem;
}
#hero .hero-kicker { font-size: 0.875rem; }
#hero .hero-headline { margin-top: 1rem; font-size: clamp(2.3rem, 10vw, 3.2rem); }
#hero .hero-intro { margin-top: 1rem; font-size: 1.125rem; }
#hero .hero-actions { margin-top: 1.5rem; gap: 1.25rem; }
#hero .hero-visual { height: 340px; }
#hero figcaption { left: 1.25rem; bottom: 1.25rem; }
#hero .hero-caption-text { font-size: 1.4rem; }
#hero .hero-benefits { grid-template-columns: 1fr; gap: 1.25rem; margin-top: 2rem; }
}
@media (max-width: 390px) {
#hero .hero-button { width: 100%; justify-content: space-between; }
}

View File

@ -0,0 +1,270 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ernährungsberatung für Triathleten 50+ | tri-hub</title>
<meta name="description" content="Ernährungsberatung für Triathletinnen und Triathleten ab 50.">
<!-- Kunden-CSS (Tailwind-Build von tri-hub.de) – NICHT verändern -->
<link rel="stylesheet" href="css/assets.css">
<!-- Schriften laut Design-DNA: Playfair Display (Überschriften) + Inter (Text) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Playfair+Display:wght@600;700&display=swap">
<!-- Projektweite Basis (Design-Tokens, Lesbarkeit) -->
<link rel="stylesheet" href="css/base.css">
<!-- Ein Stylesheet pro User Story – jede Datei gehört genau einem Feature-Branch -->
<link rel="stylesheet" href="css/sections/hero.css"> <!-- US01-01 -->
<link rel="stylesheet" href="css/sections/angebote.css"> <!-- US01-02 -->
<link rel="stylesheet" href="css/sections/ablauf.css"> <!-- US01-03 -->
</head>
<body>
<header class="site-header">
<div class="container">
<a href="/" class="site-logo">tri-hub</a>
<!-- US01-05 Navigation: späterer Sprint -->
</div>
</header>
<main>
<!-- ========== US01-01: Angebot und Zielgruppe (Hero) ==========
Branch: feature/US01-01-hero · Styles: css/sections/hero.css
Nur innerhalb dieser <section> arbeiten. -->
<section id="hero" aria-labelledby="hero-title">
<div class="container">
<div class="hero-grid">
<div class="hero-copy">
<h1 id="hero-title">
<span class="hero-kicker"><span class="hero-line" aria-hidden="true"></span>Ernährungsberatung für Triathlon ab&nbsp;50</span>
<span class="hero-headline">Gut versorgt.<br>Für alles, was<br><em>noch vor dir liegt.</em></span>
</h1>
<p class="hero-intro">
Dein nächstes Ziel beginnt auch auf dem Teller. Finde eine Ernährung,
die zu deinem Training, deinem Körper und deinem Leben passt.
</p>
<div class="hero-actions">
<a class="hero-button" href="#angebote">Mehr erfahren <span aria-hidden="true">↓</span></a>
<a class="hero-link" href="#ablauf">So funktioniert’s <span aria-hidden="true">→</span></a>
</div>
</div>
<figure class="hero-visual">
<img src="assets/images/hero/hero.webp" width="1200" height="800"
alt="Zwei sportlich aktive Menschen ab 50 besprechen einen Plan neben einem Fahrrad am See"
fetchpriority="high">
<figcaption>
<span class="hero-caption-label">Dein Tempo. Deine Ziele.</span>
<span class="hero-caption-text">Mehr Freude am Sport.<br>Mehr Energie fürs Leben.</span>
</figcaption>
<div class="hero-tag" aria-hidden="true">Triathlon <b>50+</b></div>
</figure>
</div>
<!-- 3 Vorteile mit Überschrift (Checkliste US01-01) -->
<ul class="hero-benefits" aria-label="Deine Vorteile auf einen Blick">
<li>
<span class="hero-benefit-icon" aria-hidden="true">↗</span>
<div>
<h2>Energie gezielt einplanen</h2>
<p>Mahlzeiten passend zu Ruhetagen, harten Einheiten und langen Ausfahrten.</p>
</div>
</li>
<li>
<span class="hero-benefit-icon" aria-hidden="true">↻</span>
<div>
<h2>Regeneration mitdenken</h2>
<p>Ernährung, die deinen Körper nach dem Training gezielt unterstützt.</p>
</div>
</li>
<li>
<span class="hero-benefit-icon" aria-hidden="true">✓</span>
<div>
<h2>Im Alltag dranbleiben</h2>
<p>Routinen, die zu Arbeit, Familie und deinen Vorlieben passen.</p>
</div>
</li>
</ul>
</div>
</section>
<!-- ========== /US01-01 ========== -->
<!-- ========== US01-02: Angebote und Pakete ==========
Branch: feature_US01-02 · Styles: css/sections/angebote.css · Script: js/angebote.js
Nur innerhalb dieser <section> arbeiten. -->
<section id="angebote" aria-labelledby="angebote-title">
<div class="container">
<div class="angebote-heading">
<div>
<p class="angebote-eyebrow">Deine Ernährung. Deine Begleitung.</p>
<h2 id="angebote-title">So viel Unterstützung,<br>wie du brauchst.</h2>
</div>
<p>Ein klarer Einstieg oder eine enge Begleitung: Wähle den Rahmen, der sich für dich richtig anfühlt.</p>
</div>
<p class="concept-note"><span aria-hidden="true">ⓘ</span> Angebotskonzept · Leistungen zur Abstimmung. Preise und Laufzeiten sind noch offen.</p>
<div class="package-grid">
<article class="package">
<div class="package-image">
<img src="assets/images/angebote/starter.webp" width="700" height="420" alt="Gemeinsame Planung am See für den sportlichen Einstieg" loading="lazy">
</div>
<div class="package-body">
<p class="package-label">Starter</p>
<h3>Dein erster<br>guter Schritt.</h3>
<p class="package-text">Für Einsteiger und Wiedereinsteiger, die ihre Ernährung verstehen und gezielt verändern möchten.</p>
<ul>
<li>Persönliche Bestandsaufnahme</li>
<li>Analyse deiner Essgewohnheiten</li>
<li>Konkrete Empfehlungen für den Alltag</li>
</ul>
<button type="button" class="package-button" data-package="starter">Starter entdecken <span aria-hidden="true">↗</span></button>
</div>
</article>
<article class="package featured">
<div class="package-image">
<img src="assets/images/angebote/standard.webp" width="700" height="420" alt="Sportler und Coach besprechen gemeinsam einen Plan am Fahrrad" loading="lazy">
<span class="package-badge">Mit individuellem Plan</span>
</div>
<div class="package-body">
<p class="package-label">Standard</p>
<h3>Aus guten Vorsätzen<br>wird dein Plan.</h3>
<p class="package-text">Für alle, die Ernährung und Training aufeinander abstimmen und neue Routinen festigen möchten.</p>
<ul>
<li>Alles aus Starter</li>
<li>Individueller Ernährungsrahmen</li>
<li>Feedback und gemeinsame Anpassung</li>
</ul>
<button type="button" class="package-button is-primary" data-package="standard">Standard entdecken <span aria-hidden="true">↗</span></button>
</div>
</article>
<article class="package">
<div class="package-image">
<img src="assets/images/angebote/premium.webp" width="700" height="420" alt="Persönliches Coachinggespräch auf einer Bank neben einem Triathlonrad" loading="lazy">
</div>
<div class="package-body">
<p class="package-label">Premium</p>
<h3>Dein Ziel.<br>Ganz persönlich.</h3>
<p class="package-text">Für ambitionierte Ziele und alle, die sich eine besonders enge, individuelle Begleitung wünschen.</p>
<ul>
<li>Alles aus Standard</li>
<li>Verpflegungsstrategie für Wettkämpfe</li>
<li>Engmaschige Begleitung und Anpassung</li>
</ul>
<button type="button" class="package-button" data-package="premium">Premium entdecken <span aria-hidden="true">↗</span></button>
</div>
</article>
</div>
<!-- Verweis auf Rabatte aus dem Coaching 1zu1 -->
<div class="coaching-banner">
<div class="bonus-symbol" aria-hidden="true">%</div>
<div>
<h3>Schon im Coaching 1zu1? Dein Vorteil kommt mit.</h3>
<p>Mit deinem Coaching-Paket sparst du bei der Ernährungsberatung: Starter 3&nbsp;%, Standard 5&nbsp;%, Premium 10&nbsp;%.</p>
</div>
<button type="button" class="bonus-button" data-package="bonus">Rabatte ansehen <span aria-hidden="true">↗</span></button>
</div>
</div>
<!-- Detaildialog (öffnet nur per Klick, kein Pop-up beim Laden) -->
<dialog id="package-dialog" aria-labelledby="dialog-title">
<div class="dialog-inner">
<button type="button" class="close-dialog" aria-label="Details schließen">×</button>
<p id="dialog-eyebrow" class="angebote-eyebrow"></p>
<h2 id="dialog-title"></h2>
<p id="dialog-description"></p>
<div id="detail-section">
<h3>Deine Begleitung im Überblick</h3>
<ul id="dialog-features"></ul>
<p class="dialog-hint">Konzeptvorschlag: Leistungsumfang, Kontaktfrequenz, Laufzeit und Preis werden noch abgestimmt.</p>
</div>
<div class="discount-box">
<p class="angebote-eyebrow">Dein Coaching-Vorteil</p>
<h3>Du bist schon im Coaching 1zu1?</h3>
<label for="coaching-select">Dein bestehendes Coaching-Paket</label>
<select id="coaching-select">
<option value="0">Noch kein Coaching 1zu1</option>
<option value="3">Starter-Coaching</option>
<option value="5">Standard-Coaching</option>
<option value="10">Premium-Coaching (24 oder 52 Wochen)</option>
</select>
<p id="discount-result" aria-live="polite"></p>
<p class="dialog-hint">Der Rabatt richtet sich nach deinem bestehenden Coaching 1zu1, unabhängig vom gewählten Ernährungsangebot.</p>
<a href="https://tri-hub.de/coaching-1zu1" target="_blank" rel="noopener">Coaching 1zu1 bei TriHub ansehen ↗</a>
</div>
<button type="button" class="dialog-done">Zurück zu den Angeboten</button>
</div>
</dialog>
</section>
<!-- ========== /US01-02 ========== -->
<!-- ========== US01-03: Ablauf sehen ==========
Branch: feature_US01-03 · Styles: css/sections/ablauf.css
Nur innerhalb dieser <section> arbeiten. -->
<section id="ablauf" aria-labelledby="ablauf-title">
<div class="container">
<div class="ablauf-heading">
<div>
<p class="ablauf-eyebrow">So läuft’s ab</p>
<h2 id="ablauf-title">Vom ersten Gespräch<br>zu deiner eigenen Routine.</h2>
</div>
<p>Du musst nicht schon alles wissen. Wir beginnen bei dir und gehen Schritt für Schritt weiter.</p>
</div>
<ol class="steps">
<li class="step">
<span class="step-number" aria-hidden="true">01</span>
<h3><span class="sr-only">Schritt 1: </span>Dich kennenlernen</h3>
<p>Wir besprechen deine Ziele, deinen Alltag und deine sportliche Ausgangslage.</p>
</li>
<li class="step">
<span class="step-number" aria-hidden="true">02</span>
<h3><span class="sr-only">Schritt 2: </span>Gewohnheiten verstehen</h3>
<p>Ein Ernährungsprotokoll macht sichtbar, was bereits passt und wo du ansetzen kannst.</p>
</li>
<li class="step">
<span class="step-number" aria-hidden="true">03</span>
<h3><span class="sr-only">Schritt 3: </span>Deinen Weg planen</h3>
<p>Du erhältst konkrete Empfehlungen – je nach Paket ergänzt um einen individuellen Ernährungsrahmen.</p>
</li>
<li class="step">
<span class="step-number" aria-hidden="true">04</span>
<h3><span class="sr-only">Schritt 4: </span>Umsetzen &amp; anpassen</h3>
<p>Du erprobst die Empfehlungen. In Standard und Premium begleiten Feedback und Anpassungen deinen Weg.</p>
</li>
</ol>
<div class="process-end">
<p>Der beste Plan ist der, der in dein Leben passt.</p>
<a class="process-link" href="#angebote">Dein Angebot entdecken <span aria-hidden="true">↑</span></a>
</div>
</div>
</section>
<!-- ========== /US01-03 ========== -->
</main>
<script src="js/main.js" defer></script>
<script src="js/angebote.js" defer></script> <!-- US01-02 -->
</body>
</html>

105
js/angebote.js 100644
View File

@ -0,0 +1,105 @@
// US01-02: Paketdetails und Coaching-Rabatt im Dialog (Vorlage: Prototyp)
'use strict';
(() => {
const section = document.querySelector('#angebote');
if (!section) return;
const packages = {
starter: {
name: 'Starter',
title: 'Dein erster guter Schritt.',
description: 'Du möchtest wissen, wo du stehst und was du konkret verändern kannst? Starter schafft eine persönliche Grundlage für deinen Einstieg.',
features: [
'Gemeinsames Erstgespräch zu Zielen, Training, Alltag und Vorlieben.',
'Auswertung eines Ernährungsprotokolls mit Blick auf deine bisherigen Gewohnheiten.',
'Persönliche Handlungsempfehlungen für Essen und Trinken im Alltag und rund um dein Training.',
'Abschlussgespräch zur Einordnung deiner nächsten Schritte.'
]
},
standard: {
name: 'Standard',
title: 'Aus guten Vorsätzen wird dein Plan.',
description: 'Du möchtest aus einzelnen Empfehlungen eine verlässliche Routine machen? Standard verbindet die Bestandsaufnahme mit einem individuellen Plan und persönlichem Feedback.',
features: [
'Alle vorgeschlagenen Leistungen aus Starter.',
'Ein individueller Ernährungsrahmen für Trainings- und Ruhetage.',
'Praktische Mahlzeitenideen, abgestimmt auf deine Vorlieben und deinen Alltag.',
'Feedbackgespräche, um Erfahrungen zu besprechen und den Plan gemeinsam anzupassen.'
]
},
premium: {
name: 'Premium',
title: 'Dein Ziel. Ganz persönlich.',
description: 'Du möchtest deine Ernährung gezielt auf sportliche Herausforderungen abstimmen? Premium sieht eine besonders enge Begleitung bis in die Wettkampfvorbereitung vor.',
features: [
'Alle vorgeschlagenen Leistungen aus Standard.',
'Eine individuelle Strategie für Essen und Trinken vor, während und nach Wettkämpfen.',
'Erprobung der Verpflegung im Training und Anpassung an deine Erfahrungen.',
'Engmaschiger persönlicher Austausch und laufende Anpassungen an deine Trainingsphasen.'
]
}
};
const dialog = section.querySelector('#package-dialog');
const select = section.querySelector('#coaching-select');
const result = section.querySelector('#discount-result');
let trigger = null;
function updateDiscount() {
const rate = Number(select.value);
result.replaceChildren();
if (rate) {
const strong = document.createElement('strong');
strong.textContent = `${rate} % Rabatt`;
result.append(strong, document.createTextNode(' auf deine Ernährungsberatung.'));
} else {
result.textContent = 'Mit Coaching 1zu1: Starter 3 %, Standard 5 %, Premium 10 % Rabatt.';
}
}
function openDetails(key, button) {
trigger = button;
const data = packages[key];
section.querySelector('#dialog-eyebrow').textContent =
data ? `Ernährungsberatung · ${data.name}` : 'Coaching 1zu1 · Bonusregelung';
section.querySelector('#dialog-title').textContent =
data ? data.title : 'Dein Coaching zahlt sich aus.';
section.querySelector('#dialog-description').textContent = data
? data.description
: 'Dein bestehendes Coaching-Paket bringt dir einen Preisvorteil bei der Ernährungsberatung. Wähle es aus und sieh deinen Rabatt.';
section.querySelector('#detail-section').hidden = !data;
const list = section.querySelector('#dialog-features');
list.replaceChildren();
if (data) {
data.features.forEach((text) => {
const li = document.createElement('li');
li.textContent = text;
list.append(li);
});
}
updateDiscount();
dialog.showModal();
}
section.querySelectorAll('[data-package]').forEach((button) => {
button.addEventListener('click', () => openDetails(button.dataset.package, button));
});
select.addEventListener('change', updateDiscount);
section.querySelectorAll('.close-dialog, .dialog-done').forEach((button) => {
button.addEventListener('click', () => dialog.close());
});
// Klick auf den abgedunkelten Hintergrund schließt den Dialog
dialog.addEventListener('click', (event) => {
if (event.target === dialog) dialog.close();
});
// Fokus zurück auf den auslösenden Button (Barrierefreiheit)
dialog.addEventListener('close', () => trigger?.focus());
})();

3
js/main.js 100644
View File

@ -0,0 +1,3 @@
// Einstiegspunkt für Skripte.
// Feature-Code in eigene Dateien auslagern (z. B. js/scroll.js für US01-01)
// und hier bzw. in index.html einbinden.