diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..49132ec Binary files /dev/null and b/.DS_Store differ diff --git a/css/berater.css b/css/berater.css new file mode 100644 index 0000000..25dee86 --- /dev/null +++ b/css/berater.css @@ -0,0 +1,197 @@ +/* Ahmad: Styles bleiben in .berater-section; Karten passen auch auf Mobilgeraete. */ +/* ========================================================== + Globale Design-Variablen - Angepasst an die Design-DNA von Tri-hub + ========================================================== */ +.berater-section { + /* Farben und variabel-namen wurden standarttisiert siehe Kommentare */ + --background: ##0714198a; /* früher "--bg-dark-1" */ + --background-rgb: 7 20 25; /* gleiche Basisfarbe wie --background, + aber ohne fixes Alpha – für Gradient-Stops + wird benutzt um Bildern einen gradient zu verpassen */ + --background-panel: #152027; /* früher "--bg-dark-2" */ + --accent: #4597A3; /* früher "accent-teal" */ + --text-primary: #ffffff; /* früher "text-white" */ + --text-muted: #94A3B8; + + --font-display: 'Inter', system-ui, sans-serif; + --font-body: 'Inter', system-ui, sans-serif; +} + +.berater-section { + margin: 0; + /* Padding vereinheitlicht, um dem Pakete-Bereich zu entsprechen */ + padding: 5rem 1.5rem; + font-family: var(--font-body); + background-color: var(--background); + color: var(--text-white); + display: flex; + flex-direction: column; + align-items: center; + /* Gesamten Inhalt vertikal zentrieren */ +} + +/* ========================================= + Styling für Header (Titel und Untertitel) passend zu den Paketen + ========================================= */ +.berater-section .section-header { + text-align: center; + max-width: 42rem; + margin: 0 auto 3rem; +} + +.berater-section .section-title { + font-family: var(--font-display); + font-weight: 700; + font-size: clamp(1.8rem, 3vw, 2.4rem); + color: var(--text-white); + margin: 0 0 0.75rem; +} + +.berater-section .section-subtitle { + color: var(--text-muted); + line-height: 1.6; + margin: 0; +} + +/* ========================================= + Styling für den Container und die Berater-Karten + ========================================= */ +.berater-section .berater-container { + display: flex; + gap: 30px; + width: 100%; + max-width: 1000px; + flex-wrap: wrap; + justify-content: center; +} + +.berater-section .berater-card { + background-color: var(--background-panel); + /* Leichte Umrandung hinzugefügt, ähnlich wie bei den Pakete-Karten */ + border: 1px solid rgba(248, 250, 252, 0.08); + /* Border-Radius angepasst, passend zu den Paketen */ + border-radius: 14px; + padding: 24px; + width: min(380px, 100%); + box-sizing: border-box; + display: flex; + flex-direction: column; +} + +.berater-section .berater-image-wrapper { + background-color: var(--background); + border-radius: 10px; + padding: 10px; + margin-bottom: 24px; +} + +.berater-section .berater-image-wrapper img { + width: 100%; + height: 350px; + object-fit: cover; + border-radius: 8px; + display: block; +} + +.berater-section .berater-name { + margin: 0 0 8px 0; + font-family: var(--font-display); + font-size: 1.4rem; + /* Schriftgröße des Namens harmonisiert */ + font-weight: 600; + color: var(--text-white); +} + +.berater-section .berater-rolle { + margin: 0 0 24px 0; + font-family: var(--font-body); + font-size: 14px; + color: var(--accent); + text-transform: uppercase; + letter-spacing: 1.5px; + font-weight: 600; +} + +.berater-section .berater-bio-box { + /* Hintergrund entfernt, um sich nahtlos in die Karte einzufügen */ + background-color: transparent; + border-radius: 16px; + /* Überschüssiges Padding entfernt */ + padding: 0; + flex-grow: 1; +} + +.berater-section .bio-title { + margin: 0 0 16px 0; + font-size: 16px; + font-weight: 600; + color: var(--text-primary); +} + +.berater-section .bio-text { + margin: 0; + font-size: 15px; + line-height: 1.6; + color: var(--text-muted); +} + +/* ========================================= + Styling für dynamische Listen (z. B. Zertifikate) + ========================================= */ +.berater-section .berater-liste { + margin: 8px 0 0 0; + padding-left: 1.4rem; + color: var(--text-muted); + font-size: 14px; + line-height: 1.6; + list-style: none; + /* Standard-Listenpunkte entfernt für benutzerdefiniertes Styling */ +} + +.berater-section .berater-liste li { + position: relative; + margin-bottom: 0.7rem; + color: var(--text-primary); +} + +/* Grünes quadratisches Aufzählungszeichen hinzugefügt, exakt wie im Pakete-Bereich */ +.berater-section .berater-liste li::before { + content: ""; + position: absolute; + left: -1.4rem; + top: 0.4em; + width: 8px; + height: 8px; + border-radius: 2px; + background: var(--accent); +} + +/* ========================================= + Styling für dynamische Links (Buttons) + ========================================= */ +.berater-section .berater-links { + margin-top: 20px; + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.berater-section .berater-link-btn { + display: inline-block; + font-family: var(--font-body); + font-weight: 600; + font-size: 0.95rem; + color: var(--background); + background: var(--accent); + border: none; + border-radius: 8px; + padding: 0.85rem 1rem; + cursor: pointer; + text-decoration: none; + transition: filter 0.15s ease; +} + +.berater-section .berater-link-btn:hover, +.berater-section .berater-link-btn:focus-visible { + filter: brightness(1.1); +} \ No newline at end of file diff --git a/css/beratung.css b/css/beratung.css new file mode 100644 index 0000000..53d2f49 --- /dev/null +++ b/css/beratung.css @@ -0,0 +1,419 @@ +/* Dennis: Seitenweite Regeln sind auf den Beratungsbereich begrenzt. */ + + +.beratung-bereich { + /* Farben – Tokens von tri-hub.de (Hex-Fallback + oklch) */ + --background: #0714198a; + --background-rgb: 7 20 25; /* gleiche Basisfarbe wie --background, + aber ohne fixes Alpha – für Gradient-Stops + wird benutzt um Bildern einen gradient zu verpassen */ + --background-panel: #152027; /* früher "surface" */ + --text-primary: #ffffff; /* früher "foreground" */ + --text-muted: #9ba7aa; /* früher "muted-fg" */ + --accent: #4597A3; /* früher "primary" */ + --border: rgba(234, 8, 8, 0.1); + + /* Typografie */ + --font-display: "Sora", sans-serif; + --font-body: "DM Sans", Arial, Helvetica, sans-serif; + + /* Layout */ + --container: 1120px; + --radius: 1.1rem; +} + +/* ---------- Basic ---------- */ + +.beratung-bereich, +.beratung-bereich *, +.beratung-bereich::before, +.beratung-bereich *::before, +.beratung-bereich::after, +.beratung-bereich *::after { + box-sizing: border-box; +} + +.beratung-bereich { + scroll-behavior: smooth; +} + +.beratung-bereich { + margin: 0; + background-color: var(--background); + color: var(--foreground); + font-family: var(--font-body); + line-height: 1.625; + -webkit-font-smoothing: antialiased; + position: relative; + isolation: isolate; +} + +/* Licht*/ +.beratung-bereich::before { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: + radial-gradient(900px 520px at 78% -10%, rgba(0, 179, 194, 0.13), transparent 65%), + radial-gradient(700px 480px at -10% 30%, rgba(35, 137, 148, 0.1), transparent 60%), + radial-gradient(600px 420px at 90% 95%, rgba(247, 194, 48, 0.05), transparent 60%); + pointer-events: none; +} + +.beratung-bereich h1, +.beratung-bereich h2, +.beratung-bereich h3 { + margin-top: 0; + font-family: var(--font-display); + color: var(--foreground); + line-height: 1.2; + letter-spacing: -0.01em; +} + +.beratung-bereich p { + margin: 0 0 1em; +} + +.beratung-bereich .container { + width: min(100% - 48px, var(--container)); + margin-inline: auto; +} + +/* ---------- Typo-Helfer ---------- */ + +.beratung-bereich .kicker { + display: inline-flex; + align-items: center; + gap: 10px; + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--accent); + margin-bottom: 18px; +} + +.beratung-bereich .kicker::before { + content: ""; + width: 28px; + height: 2px; + border-radius: 2px; + background: var(--accent); +} + +.beratung-bereich .lead { + font-size: 1.15rem; + color: var(--text-muted); + max-width: 660px; +} + +.beratung-bereich .muted { + color: var(--text-muted); +} + +/* ---------- Button ---------- */ + +.beratung-bereich .btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.8rem 1.5rem; + border-radius: 999px; + font-family: var(--font-body); + font-weight: 600; + font-size: 0.95rem; + line-height: 1.2; + text-decoration: none; + border: 1px solid transparent; + cursor: pointer; + transition: transform 0.18s ease, box-shadow 0.18s ease, + background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease; +} + +.beratung-bereich .btn-accent { + background: var(--accent); + color: #03242b; +} + +.beratung-bereich .btn-accent:hover { + transform: translateY(-1px); + box-shadow: 0 10px 28px rgba(0, 179, 194, 0.28); +} + +/* ---------- Sektionen ---------- */ + +.beratung-bereich .section { + padding: 96px 0; +} + +.beratung-bereich .section-head { + max-width: 720px; + margin-bottom: 56px; +} + +.beratung-bereich .section-head h2 { + font-size: clamp(1.9rem, 4vw, 2.7rem); + margin-bottom: 18px; +} + +/* ---------- Boxen & Grid ---------- */ + +.beratung-bereich .grid-2 { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 24px; +} + +.beratung-bereich .box { + /* Lange Woerter duerfen die Karten auf kleinen Displays nicht verbreitern. */ + min-width: 0; + overflow-wrap: anywhere; + hyphens: auto; + background-color: var(--background-panel); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 32px; + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); +} + +/* ---------- Checklisten ---------- */ + +.beratung-bereich .check-list { + list-style: none; + padding: 0; + margin: 20px 0 0; + display: grid; + gap: 12px; +} + +.beratung-bereich .check-list li { + position: relative; + padding-left: 34px; + color: var(--foreground); +} + +.beratung-bereich .check-list li::before { + content: "✓"; + position: absolute; + left: 0; + top: 0; + color: var(--accent); + font-weight: bold; + font-size: 1.1rem; +} + +/* ---------- Ablauf-Schritte ---------- */ + +.beratung-bereich .beratung-ablauf { + list-style: none; + counter-reset: schritt; + padding: 0; + margin: 24px 0 0; + display: grid; + gap: 20px; +} + +.beratung-bereich .beratung-ablauf li { + counter-increment: schritt; + position: relative; + padding-left: 60px; +} + +.beratung-bereich .beratung-ablauf li::before { + content: counter(schritt, decimal-leading-zero); + position: absolute; + left: 0; + top: 2px; + display: grid; + place-items: center; + width: 44px; + height: 44px; + border-radius: 50%; + font-family: var(--font-display); + font-size: 0.9rem; + font-weight: 600; + color: var(--accent); + background: rgba(0, 179, 194, 0.1); + border: 1px solid rgba(0, 179, 194, 0.3); +} + +.beratung-bereich .beratung-ablauf strong { + display: block; + font-family: var(--font-display); + font-size: 1.02rem; + color: var(--foreground); + margin-bottom: 4px; +} + +.beratung-bereich .beratung-ablauf p { + margin: 0; + color: var(--text-muted); + font-size: 0.95rem; +} + +/* ---------- CTA-Band ---------- */ + +.beratung-bereich .cta-band { + margin-top: 96px; + padding: 64px 40px; + text-align: center; + border: 1px solid var(--border); + border-radius: calc(var(--radius) + 8px); + background: linear-gradient(135deg, #071216, #0a1b1f 46%, #050e16); +} + +.beratung-bereich .cta-band h2 { + font-size: clamp(1.8rem, 4vw, 2.5rem); + margin-bottom: 16px; +} + +.beratung-bereich .cta-band p { + color: var(--text-muted); + max-width: 560px; + margin-inline: auto; +} + +/* ---------- Footer ---------- */ + +.beratung-bereich .logo { + font-family: var(--font-display); + font-weight: 700; + font-size: 1.35rem; + letter-spacing: -0.02em; + color: var(--foreground); + text-decoration: none; + white-space: nowrap; +} + +.beratung-bereich .logo span { + color: var(--accent); +} + +.beratung-bereich .site-footer { + margin-top: 96px; + padding: 64px 0 40px; + border-top: 1px solid var(--border); + background: rgba(255, 255, 255, 0.015); +} + +.beratung-bereich .footer-grid { + display: grid; + grid-template-columns: 2fr 1fr 1fr; + gap: 48px; +} + +.beratung-bereich .footer-brand p { + color: var(--text-muted); + font-size: 0.95rem; + max-width: 340px; + margin-top: 14px; +} + +.beratung-bereich .footer-col h3 { + font-size: 0.85rem; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--text-muted); + margin-bottom: 16px; +} + +.beratung-bereich .footer-col ul { + list-style: none; + margin: 0; + padding: 0; +} + +.beratung-bereich .footer-col a { + display: block; + padding: 5px 0; + color: var(--text-muted); + text-decoration: none; + font-size: 0.92rem; + transition: color 0.15s ease; +} + +.beratung-bereich .footer-col a:hover { + color: var(--foreground); +} + +.beratung-bereich .footer-legal { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: 12px; + margin-top: 48px; + padding-top: 24px; + border-top: 1px solid var(--border); + color: var(--text-muted); + font-size: 0.85rem; +} + +.beratung-bereich .footer-legal a { + color: inherit; + text-decoration: none; +} + +.beratung-bereich .footer-legal a:hover { + color: var(--foreground); +} + +/* ---------- Scroll-Reveal ---------- */ + +.beratung-bereich .reveal { + opacity: 0; + transform: translateY(18px); + transition: opacity 0.6s ease, transform 0.6s ease; +} + +.beratung-bereich .reveal.visible { + opacity: 1; + transform: none; +} + +/* ---------- Responsiv ---------- */ + +@media (max-width: 980px) { + .beratung-bereich .footer-grid { + grid-template-columns: 1fr 1fr; + } +} + +@media (max-width: 760px) { + .beratung-bereich .grid-2 { + grid-template-columns: minmax(0, 1fr); + } + + .beratung-bereich .section { + padding: 72px 0; + } + + .beratung-bereich .footer-grid { + grid-template-columns: 1fr; + gap: 32px; + } + + .beratung-bereich .cta-band { + padding: 48px 24px; + } +} + +/* ---------- Reduzierte Bewegung ---------- */ + +@media (prefers-reduced-motion: reduce) { + .beratung-bereich { + scroll-behavior: auto; + } + + .beratung-bereich .reveal { + opacity: 1; + transform: none; + transition: none; + } + + .beratung-bereich, +.beratung-bereich * { + transition-duration: 0.01ms !important; + } +} diff --git a/css/leistungen.css b/css/leistungen.css new file mode 100644 index 0000000..2fe3444 --- /dev/null +++ b/css/leistungen.css @@ -0,0 +1,200 @@ +/* Vincent: Gemeinsame Klassennamen und Variablen sind auf .pakete begrenzt. */ +/* ========================================================== + tri-hub.de – Farben angeglichen an Produktübersicht (Shahnam) + Hintergrund: #071419 / #1b2830 + Akzent: #4597A3 (gedämpftes Cyan-Teal) + Primärtext: #ffffff / #b7bec2 / #7e858a + Typografie: Sora (Display) + Inter (Body) + Werte per Pixel-Sampling aus dem Screenshot der Produktübersicht ermittelt. + ========================================================== */ + +.pakete { + /* Werte per Pixel-Sampling aus dem Referenz-Screenshot (Produktübersicht) übernommen */ + --background: #0714198a; /* früher "bg-dark */ + --background-rgb: 7 20 25; /* gleiche Basisfarbe wie --background, + aber ohne fixes Alpha – für Gradient-Stops + wird benutzt um Bildern einen gradient zu verpassen */ + --background-panel: #152027; /* früher "primary */ + --accent: #4597A3; + --accent-soft: rgba(69, 151, 163, 0.14); + --text-primary: #ffffff; + --text-muted: #7e858a; + + --font-display: "Sora", "Inter", system-ui, sans-serif; + --font-body: "Inter", system-ui, sans-serif; +} + +.pakete, +.pakete * { + box-sizing: border-box; +} + +.pakete { + margin: 0; + background: var(--background); + color: var(--text-primary); + font-family: var(--font-body); +} + +/* ---------- Leistungsübersicht ---------- */ + +.pakete { + padding: 5rem 1.5rem; + max-width: 1120px; + margin: 0 auto; +} + +.pakete .pakete__intro { + text-align: center; + max-width: 42rem; + margin: 0 auto 3rem; +} + +.pakete .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 .pakete__text { + color: var(--text-muted); + line-height: 1.6; + margin: 0; +} + +/* Kästchen nebeneinander, jede Karte für sich */ +.pakete .pakete__grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; + align-items: stretch; +} + +.pakete .paket-karte { + display: flex; + flex-direction: column; + background: var(--background-panel); + border: 1px solid rgba(248, 250, 252, 0.08); + border-radius: 14px; + padding: 2rem 1.75rem; + position: relative; +} + +.pakete .paket-karte--empfohlen { + border-color: var(--accent); + box-shadow: 0 0 0 1px var(--accent-soft); +} + +.pakete .paket-karte--ausgewaehlt { + border-color: var(--accent); + box-shadow: 0 0 0 2px var(--accent); +} + +.pakete .paket-karte__badge { + display: inline-block; + background: var(--accent-soft); + color: var(--accent); + border: 1px solid var(--accent); + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + padding: 0.35rem 0.9rem; + border-radius: 999px; + margin: 0 0 1rem; +} + +.pakete .paket-karte__name { + font-family: var(--font-display); + font-weight: 600; + font-size: 1.4rem; + color: var(--text-primary); + margin: 0 0 0.5rem; +} + +.pakete .paket-karte__preis { + margin: 0 0 0.75rem; + display: flex; + align-items: baseline; + gap: 0.35rem; +} + +.pakete .paket-karte__betrag { + font-family: var(--font-display); + font-size: 2rem; + font-weight: 700; + color: var(--text-primary); +} + +.pakete .paket-karte__zeitraum { + color: var(--text-muted); + font-size: 0.9rem; +} + +.pakete .paket-karte__beschreibung { + color: var(--text-muted); + line-height: 1.55; + margin: 0 0 1.5rem; + min-height: 3.3em; +} + +.pakete .paket-karte__leistungen { + list-style: none; + margin: 0 0 2rem; + padding: 0; + flex-grow: 1; +} + +.pakete .paket-karte__leistungen li { + position: relative; + padding-left: 1.4rem; + margin-bottom: 0.7rem; + line-height: 1.4; + color: var(--text-primary); +} + +.pakete .paket-karte__leistungen li::before { + content: ""; + position: absolute; + left: 0; + top: 0.5em; + width: 8px; + height: 8px; + border-radius: 2px; + background: var(--accent); +} + +.pakete .paket-karte__cta { + font-family: var(--font-body); + font-weight: 600; + font-size: 0.95rem; + color: var(--text-primary); + background: var(--accent); + border: none; + border-radius: 8px; + padding: 0.85rem 1rem; + cursor: pointer; + transition: filter 0.15s ease; +} + +.pakete .paket-karte__cta:hover, +.pakete .paket-karte__cta:focus-visible { + filter: brightness(1.1); +} + +.pakete .paket-karte__cta:focus-visible { + outline: 2px solid var(--text-primary); + outline-offset: 2px; +} + +@media (max-width: 860px) { + .pakete .pakete__grid { + grid-template-columns: 1fr; + } + + .pakete .paket-karte--empfohlen { + order: -1; + } +} diff --git a/css/produktuebersicht.css b/css/produktuebersicht.css new file mode 100644 index 0000000..1b27549 --- /dev/null +++ b/css/produktuebersicht.css @@ -0,0 +1,412 @@ +/* Shahnam: Styles und Variablen bleiben innerhalb der Produktuebersicht. */ +.produktuebersicht { + color-scheme: dark; + --background: #0714198a; + --background-rgb: 7 20 25; /* gleiche Basisfarbe wie --background, + aber ohne fixes Alpha – für Gradient-Stops + wird benutzt um Bildern einen gradient zu verpassen */ + /* es fehlt eine andere backgroundfarbe für das Panel */ + --accent: #4597A3; + --text-primary: #ffffff; /*früher "text"*/ + --text-muted: #b7bec2; /*früher "muted"*/ + --border: rgb(255 255 255 / 16%); + font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif; + color: var(--text-primary); + background: var(--background); +} + +.produktuebersicht, +.produktuebersicht *, +.produktuebersicht::before, +.produktuebersicht *::before, +.produktuebersicht::after, +.produktuebersicht *::after { + box-sizing: border-box; +} + +.produktuebersicht { + display: flex; + flex-direction: column; + min-height: 100vh; + min-height: 100svh; + margin: 0; + line-height: 1.6; +} + +.produktuebersicht p, +.produktuebersicht h1 { + margin: 0; +} + +.produktuebersicht .container { + width: min(1680px, calc(100% - clamp(40px, 10vw, 192px))); + margin-inline: auto; +} + +.produktuebersicht .site-header { + border-top: 3px solid var(--accent); +} + +.produktuebersicht .brand { + display: flex; + align-items: center; + gap: 20px; + min-height: 96px; + padding-block: 8px; +} + +.produktuebersicht .brand__logo { + display: grid; + place-items: center; + flex-shrink: 0; + width: 90px; + height: 80px; + border-radius: 22px; + background: #fff; +} + +.produktuebersicht .brand__logo img { + display: block; + width: 60px; + height: 60px; + object-fit: contain; +} + +.produktuebersicht .brand__text { + display: flex; + flex-direction: column; + gap: 4px; + min-width: 0; +} + +.produktuebersicht .brand__name { + color: #8a9093; + font-size: 14px; + font-weight: 650; + line-height: 1.4; + letter-spacing: 0.25em; +} + +.produktuebersicht .brand__label { + color: var(--text-muted); + font-size: 17px; + font-weight: 600; + line-height: 1.4; +} + +.produktuebersicht .produktuebersicht__main { + display: flex; + flex: 1; +} + +.produktuebersicht .hero { + position: relative; + isolation: isolate; + display: flex; + flex: 1; + min-width: 0; + border-block: 1px solid var(--border); +} + +.produktuebersicht .hero__image, +.produktuebersicht .hero::after { + position: absolute; + z-index: -1; + inset: 0; + width: 100%; + height: 100%; +} + +.produktuebersicht .hero__image { + object-fit: cover; + object-position: center 42%; +} + +.produktuebersicht .hero::after { + /*background: var(--background); + /* ich bekomme das nicht richtig hin muss Shahmad machen */ + background: + linear-gradient(0deg, rgb(var(--background-rgb) / 96%), transparent 42%), + linear-gradient(90deg, rgb(var(--background-rgb) / 94%) 0%, rgb(var(--background-rgb) / 79%) 35%, rgb(var(--background-rgb) / 38%) 72%, rgb(var(--background-rgb) / 25%) 100%); + content: ""; +} + + + +.produktuebersicht .hero__inner { + display: flex; + flex-direction: column; + padding-block: clamp(32px, 5vh, 64px) 28px; +} + +.produktuebersicht .hero__content { + width: min(100%, 1000px); + margin-block: auto; + padding-block: 24px 64px; +} + +.produktuebersicht .hero__eyebrow { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 26px; + color: #4597A3; + font-size: 11px; + font-weight: 650; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +.produktuebersicht .hero__eyebrow::before { + width: 28px; + height: 1px; + flex-shrink: 0; + background: currentColor; + content: ""; +} + +.produktuebersicht h1 { + max-width: 100%; + font-size: clamp(42px, 4.9vw, 88px); + font-weight: 550; + line-height: 1.1; + letter-spacing: -0.055em; + text-wrap: balance; + overflow-wrap: break-word; +} + +.produktuebersicht h1 span { + display: block; + margin-top: 8px; + color: var(--accent); +} + +.produktuebersicht .hero__description { + max-width: 65ch; + margin-top: 30px; + color: #d1d7df; + font-size: clamp(16px, 1.15vw, 19px); + line-height: 1.85; +} + +.produktuebersicht .hero__details { + display: grid; + grid-template-columns: minmax(0, 1fr) 250px; + align-items: center; + gap: 48px; + padding-top: 28px; + border-top: 1px solid var(--border); +} + +.produktuebersicht .benefits { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 24px; + margin: 0; + padding: 0; + list-style: none; +} + +.produktuebersicht .benefits li { + display: flex; + align-items: baseline; + gap: 14px; +} + +.produktuebersicht .benefits__number { + color: var(--accent); + font-size: 11px; + font-variant-numeric: tabular-nums; +} + +.produktuebersicht .benefits p { + font-size: 14px; + font-weight: 500; +} + +.produktuebersicht .benefits p span { + display: block; + margin-top: 4px; + color: var(--text-muted); + font-size: 12px; + font-weight: 400; +} + +.produktuebersicht .hero__caption { + padding-left: 24px; + border-left: 1px solid var(--border); +} + +.produktuebersicht .hero__caption-label { + color: var(--text-muted); + font-size: 10px; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.produktuebersicht .hero__slogan { + margin-top: 8px; + font-size: 22px; + font-weight: 450; + line-height: 1.4; + letter-spacing: -0.025em; +} + +.produktuebersicht .site-footer__inner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + min-height: 88px; + padding-block: 24px; + font-size: 12px; +} + +.produktuebersicht .site-footer__inner p > span { + margin-left: 12px; + color: var(--text-muted); +} + +.produktuebersicht .site-footer__note { + display: flex; + align-items: center; + gap: 9px; + color: var(--text-muted); +} + +.produktuebersicht .site-footer__note > span { + width: 5px; + height: 5px; + flex-shrink: 0; + border-radius: 50%; + background: var(--accent); +} + +@media (max-width: 1100px) { + .produktuebersicht .hero__image { + object-position: 80% center; + } + + .produktuebersicht .hero::after { + background: + linear-gradient(0deg, rgb(var(--background-rgb) / 96%), transparent 42%), + linear-gradient(90deg, rgb(var(--background-rgb) / 92%), rgb(var(--background-rgb) / 70%) 65%, rgb(var(--background-rgb) / 48%)); + } + + .produktuebersicht .hero__content { + max-width: 85%; + } + + .produktuebersicht .hero__details { + grid-template-columns: minmax(0, 1fr) 200px; + gap: 28px; + } + + .produktuebersicht .benefits li { + flex-direction: column; + gap: 8px; + } +} + +@media (max-width: 700px) { + .produktuebersicht .brand { + min-height: 78px; + gap: 12px; + } + + .produktuebersicht .brand__logo { + width: 66px; + height: 62px; + border-radius: 17px; + } + + .produktuebersicht .brand__logo img { + width: 46px; + height: 46px; + } + + .produktuebersicht .brand__name { + font-size: 12px; + } + + .produktuebersicht .brand__label { + font-size: 13px; + } + + .produktuebersicht .hero__image { + object-position: 85% center; + } + + .produktuebersicht .hero::after { + background: linear-gradient(90deg, rgb(var(--background-rgb) / 87%), rgb(var(--background-rgb) / 65%)), + linear-gradient(0deg, var(--background), transparent 55%); + } + + .produktuebersicht .hero__content { + max-width: 100%; + padding-block: 12px 40px; + } + + .produktuebersicht .hero__eyebrow { + gap: 8px; + font-size: 10px; + letter-spacing: 0.11em; + } + + .produktuebersicht .hero__eyebrow::before { + width: 20px; + } + + .produktuebersicht .hero__description { + margin-top: 24px; + } + + .produktuebersicht .hero__details { + grid-template-columns: 1fr; + gap: 28px; + padding-top: 24px; + } + + .produktuebersicht .benefits { + gap: 16px; + } + + .produktuebersicht .benefits p { + font-size: 12px; + } + + .produktuebersicht .hero__caption { + padding-left: 16px; + border-left-color: var(--accent); + } + + .produktuebersicht .hero__slogan { + font-size: 20px; + } + + .produktuebersicht .site-footer__inner { + align-items: flex-start; + flex-direction: column; + gap: 14px; + } + + .produktuebersicht .site-footer__inner p > span { + margin-left: 0; + } + + .produktuebersicht .site-footer__inner > p:first-child span { + display: block; + margin-top: 4px; + } +} + +@media (max-width: 360px) { + .produktuebersicht .benefits { + grid-template-columns: 1fr; + } + + .produktuebersicht .benefits li { + flex-direction: row; + gap: 14px; + } +} diff --git a/css/site.css b/css/site.css new file mode 100644 index 0000000..b6fc916 --- /dev/null +++ b/css/site.css @@ -0,0 +1,10 @@ +:root { + color-scheme: dark; + font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif; + color: #f8fafc; + background: #0714198a; +} + +body { + margin: 0; +} diff --git a/docs/integration-review.md b/docs/integration-review.md new file mode 100644 index 0000000..dfcfd3b --- /dev/null +++ b/docs/integration-review.md @@ -0,0 +1,105 @@ +# Ernährungsseite – Integrationsänderungen + +## Dateien und Zuständigkeiten + +Die Bereiche stehen gemeinsam in [index.html](../index.html), in dieser Reihenfolge: Produktübersicht → Pakete → Berater → Beratungsinformationen mit Footer. + +| Bereich | CSS | JavaScript | Daten | +| --- | --- | --- | --- | +| Shahnam: Produktübersicht | [produktuebersicht.css](../css/produktuebersicht.css) | – | Direkt im HTML | +| Vincent: Pakete | [leistungen.css](../css/leistungen.css) | [leistungen.js](../js/leistungen.js) | [pakete.json](../json/pakete.json) | +| Ahmad: Berater | [berater.css](../css/berater.css) | [berater.js](../js/berater.js) | [berater.json](../json/berater.json) | +| Dennis: Beratung und Footer | [beratung.css](../css/beratung.css) | [beratung.js](../js/beratung.js) | Direkt im HTML | + +[site.css](../css/site.css) enthält nur die gemeinsame Seitengrundlage: Hintergrund, Textfarbe, Standardschrift und den entfernten Außenabstand des `body`. + +### Umbenannte und verschobene Dateien + +Die alten Pfade beziehen sich auf den jeweiligen Quellbranch. + +| Bereich | Vorher | Jetzt | +| --- | --- | --- | +| Shahnam | `css/style.css` | `css/produktuebersicht.css` | +| Vincent | `css/style.css` | `css/leistungen.css` | +| Vincent | `js/script.js` | `js/leistungen.js` | +| Ahmad | `css/style.css` | `css/berater.css` | +| Dennis | `style.css` | `css/beratung.css` | +| Dennis | `script.js` | `js/beratung.js` | +| Beraterbilder | `img/relindis_agethen.png` | `images/relindis_agethen.png` | +| Beraterbilder | `img/relindis_agethen_1.jpg` | `images/relindis_agethen_1.jpg` | + +Die Bildpfade in `json/berater.json` wurden entsprechend angepasst. + +## Gemeinsames HTML und CSS + +**HTML:** Die unterschiedlichen `index.html`-Versionen wurden zu einem Dokument mit einem `head`, einem `body` und einem übergeordneten `main` zusammengesetzt. Alle benötigten CSS- und JS-Dateien sind dort eingebunden; die Skripte laden mit `defer`. Die Schriftarten werden einmal im gemeinsamen Head angefordert. + +**CSS:** Regeln für `body`, Überschriften, `.container` und Farbvariablen waren ursprünglich teilweise seitenweit gültig. Sie sind jetzt auf die jeweiligen Bereiche begrenzt: + +| Bereich | Äußerer Selektor | +| --- | --- | +| Produktübersicht | `.produktuebersicht` | +| Pakete | `.pakete` | +| Berater | `.berater-section` | +| Beratung einschließlich Footer | `.beratung-bereich` | + +Beispiel: `.produktuebersicht .container` gilt nur im Produktbereich, `.beratung-bereich .container` nur im Beratungsbereich. Gleichnamige Klassen und Variablen können dadurch in beiden Bereichen bestehen bleiben. + +**Beim Ergänzen von Styles:** Den jeweiligen äußeren Selektor beibehalten. Neue globale Regeln wie `h2 { ... }`, `.container { ... }` oder Variablen in `:root` können wieder andere Bereiche beeinflussen. Ein anderer CSS-Dateiname allein verhindert das nicht. + +## Änderungen je Bereich + +### Shahnam – Produktübersicht + +- Der gesamte Bereich liegt jetzt innerhalb von `.produktuebersicht`; die Styles und Variablen wurden entsprechend begrenzt. +- Das bisherige innere `main` wurde zu `div.produktuebersicht__main`, damit es nur einen übergeordneten `main` gibt. Der innere `.hero` ist ebenfalls ein `div`. + +### Vincent – Pakete + +| Stelle | Änderung | Grund | +| --- | --- | --- | +| Datenabruf in `js/leistungen.js` | `data/pakete.json` → `json/pakete.json` | Der bisherige Pfad passte nicht zum vorhandenen Ordner. | +| Initialisierung | Prüfung auf `#leistungen`; Elementsuche innerhalb dieses Bereichs | Das Skript greift nur auf seinen eigenen Bereich zu. | +| Datenabruf | HTTP-Statusprüfung und `try/catch` mit sichtbarer Fehlermeldung | Ein Ladefehler soll nicht als leerer Paketbereich enden. | +| Paketbuttons | Klickfunktion wieder angeschlossen | Die Auswahl aus der ersten Umsetzung fehlte nach der Umstellung auf JSON. | +| Auswahlstatus | Genau eine markierte Karte und `aria-pressed` für die Buttons | Auswahl sichtbar und für Hilfstechnologien erkennbar halten. | + +Nach einer Auswahl wird auf `document` das Event `paket:ausgewaehlt` ausgelöst. `event.detail.paket` enthält den `dataPaket`-Wert aus der JSON-Datei. Eine spätere Buchungsfunktion kann daran anschließen; der Button führt aktuell keine Buchung aus. + +### Ahmad – Berater + +- Kartenbreite von `380px` auf `min(380px, 100%)` angepasst; der Kartencontainer erhält `width: 100%` bei weiterhin maximal `1000px`. So passen die Karten auf schmale Displays. +- CSS auf `.berater-section` begrenzt. Die HTML-Sektion erhielt `id="berater"` und eine zugängliche Bereichsbezeichnung. +- `json/berater.json`: die beiden Bildpfade auf `images/` umgestellt. + +### Dennis – Beratung und Footer + +- CSS auf `.beratung-bereich` begrenzt. Die vorhandenen allgemeinen Klassennamen bleiben innerhalb dieses Containers nutzbar. +- Der dekorative Hintergrund ist jetzt innerhalb des Bereichs absolut positioniert und durch `isolation: isolate` begrenzt. Er liegt nicht mehr fest hinter der gesamten Seite. +- Scroll-Reveal sucht in `js/beratung.js` nach `.beratung-bereich .reveal` statt seitenweit nach `.reveal`. +- Grid-Spalten verwenden `minmax(0, 1fr)`. Die Karten erhalten `min-width: 0`, `overflow-wrap: anywhere` und `hyphens: auto`. Das behebt den beim 320-Pixel-Test festgestellten horizontalen Überlauf durch lange Wörter. + +## Lokal starten und prüfen + +`index.html` über einen lokalen HTTP-Server öffnen, zum Beispiel VS Code Live Server. Beim direkten Öffnen als `file://` können die JSON-Abfragen scheitern. + +Die vollständige Integrationsprüfung erfolgte automatisiert in Chrome, ergänzt durch die Ansicht von Screenshots: + +- Breiten: **320, 390, 768, 1366 und 1920 px**; nach den Korrekturen kein horizontaler Überlauf. +- **3 Pakete und 2 Beraterkarten**, funktionierende Bilder und eindeutige IDs. +- Paketwechsel: genau eine Auswahl und korrektes `paket:ausgewaehlt`-Event. +- Sichtbare Fehlermeldungen bei fehlender Paket- beziehungsweise Berater-JSON. +- Sichtbare Beratungsinhalte bei aktivierter Einstellung für reduzierte Bewegung. +- Keine unbehandelten JavaScript-Fehler oder fehlgeschlagenen lokalen Ressourcen im normalen Testlauf. + +Die Browserprüfung fand vor dem Verschieben der Bilder statt; danach wurden die Bildpfade und Dateiinhalte geprüft. Andere Browser und echte Mobilgeräte wurden nicht getestet. + +## Offene Punkte für das Team + +| Bereich | Noch zu prüfen | +| --- | --- | +| Produktübersicht | Platzhalter durch endgültige Texte ersetzen. | +| Pakete | Bezeichnung `STANDART`, Preise und Paketangaben prüfen; Buchungsfunktion noch offen. | +| Berater | Zwei gleich benannte Profile mit gleichen Informationen und unterschiedlichen Bildern sind aus dem Quellstand übernommen. Prüfen, ob das so vorgesehen ist. | +| Kontakt und externe Links | Ziele und Angaben fachlich prüfen. | +| Gesamtgestaltung | Unterschiede bei Farben, Abständen und Schriftgrößen gemeinsam bewerten. | diff --git a/images/hero-triathlon.webp b/images/hero-triathlon.webp new file mode 100644 index 0000000..239ac6d Binary files /dev/null and b/images/hero-triathlon.webp differ diff --git a/images/relindis_agethen.png b/images/relindis_agethen.png new file mode 100644 index 0000000..ca0e288 Binary files /dev/null and b/images/relindis_agethen.png differ diff --git a/images/relindis_agethen_1.jpg b/images/relindis_agethen_1.jpg new file mode 100644 index 0000000..718a6e3 Binary files /dev/null and b/images/relindis_agethen_1.jpg differ diff --git a/images/trihub-logo.jpg b/images/trihub-logo.jpg new file mode 100644 index 0000000..5814a4c Binary files /dev/null and b/images/trihub-logo.jpg differ diff --git a/index.html b/index.html index c8edbe7..90a3774 100644 --- a/index.html +++ b/index.html @@ -4,26 +4,247 @@ - Ernährungsberater + Ernährungsberatung für Triathleten | tri-hub + + + + + + + + + + + - -
+
+ +
+ -
- -
+
+
+ Gruppe beim Radfahren und Laufen in einer Berglandschaft im Abendlicht -
- -
+
+
+

Der Text wärmt sich noch auf

+

+ Überschrift. Weitere Zeile. + Akzentzeile. +

+

+ Hier folgt eine kurze Beschreibung der Ernährungsberatung. + Dieser Platz ist für den finalen Text vorgesehen und wird ergänzt, + sobald die Inhalte vorliegen. +

+
-
- -
+
+
    +
  • + +

    Erster Vorteil Text folgt

    +
  • +
  • + +

    Zweiter Vorteil Text folgt

    +
  • +
  • + +

    Dritter Vorteil Text folgt

    +
  • +
-
+
+

Bildunterschrift folgt

+

Slogan folgt. Weitere Zeile.

+
+ + + + + + +
+ + +
+
+

+

+
+ +
+
+ + +
+
+

+

+
+ +
+
+ + +
+
+
+
+ Info über die Beratung +

Gut zu wissen, bevor du startest

+

Transparenz von Anfang an: So arbeitet die Beratung, für wen sie sich eignet und + was dich erwartet.

+
+ +
+
+

Was dich bei der Beratung erwartet

+ +

Gemeinsam schauen wir uns deine individuellen Ziele, Gewohnheiten und Bedürfnisse an und + entwickeln daraus passende Strategien für deinen Alltag.

+ +
    +
  • Individuelle Ernährungsberatung
  • +
  • Erstellung von Ernährungsplänen
  • +
  • Unterstützung bei Gewichtsmanagement
  • +
  • Beratung bei speziellen Ernährungsbedürfnissen
  • +
  • Analyse deiner aktuellen Ernährungsgewohnheiten
  • +
  • Praktische Tipps für die Umsetzung im Alltag
  • +
+
+ +
+

So läuft die Beratung ab

+ +
    +
  1. + Erstgespräch +

    Wir besprechen deine Ziele, Wünsche und bisherigen Erfahrungen.

    +
  2. + +
  3. + Analyse +

    Deine aktuelle Ernährung und deine individuellen Bedürfnisse werden betrachtet. +

    +
  4. + +
  5. + Planung +

    Gemeinsam entwickeln wir konkrete und realistische Maßnahmen.

    +
  6. + +
  7. + Begleitung +

    Bei Bedarf wird der Fortschritt regelmäßig überprüft und der Plan angepasst.

    +
  8. +
+
+ +
+

Für wen ist die Beratung geeignet?

+ +
    +
  • Menschen, die ihre Ernährung verbessern möchten
  • +
  • Sportler mit individuellen Ernährungszielen
  • +
  • Menschen mit speziellen Ernährungsbedürfnissen
  • +
  • Personen, die Unterstützung beim Gewichtsmanagement suchen
  • +
+
+ +
+

Weitere Informationen

+ +

+ Platzhalter für zukünftige Erweiterungen, beispielsweise Informationen zu Preisen, + Terminen, Kontaktmöglichkeiten oder zusätzlichen Beratungsangeboten. +

+
+
+
+ +
+
+

Bereit für deinen nächsten Schritt?

+

Vereinbare ein unverbindliches Kennenlerngespräch – wir schauen gemeinsam, ob die Beratung zu + dir + passt.

+ Jetzt + unverbindlich anfragen +
+
+ + + +
+ +
+ - \ No newline at end of file + diff --git a/js/berater.js b/js/berater.js new file mode 100644 index 0000000..7b14961 --- /dev/null +++ b/js/berater.js @@ -0,0 +1,103 @@ +document.addEventListener('DOMContentLoaded', async () => { + // Container für die Berater-Karten auswählen + const container = document.getElementById('berater-container'); + + // Titel- und Untertitel-Elemente aus dem HTML abrufen + const titleEl = document.querySelector('.section-title'); + const subtitleEl = document.querySelector('.section-subtitle'); + + let daten; + try { + // Daten aus der JSON-Datei asynchron laden + const response = await fetch('json/berater.json'); + if (!response.ok) throw new Error(`HTTP Fehler: ${response.status}`); + daten = await response.json(); + } catch (error) { + console.error('Fehler beim Laden der JSON-Datei:', error); + // Fehlermeldung auf der Webseite anzeigen, falls das Laden fehlschlägt + if (container) { + container.innerHTML = '

Daten konnten nicht geladen werden.

'; + } + return; + } + + // 1. Titel und Einleitungstext (Intro) aus der JSON-Datei einfügen + if (titleEl && daten.intro) { + titleEl.textContent = daten.intro.titel; + } + if (subtitleEl && daten.intro) { + subtitleEl.textContent = daten.intro.text; + } + + // 2. Berater-Karten verarbeiten und erstellen + // Wir iterieren über das Array "berater" innerhalb der JSON-Daten + daten.berater.forEach(berater => { + // Ein neues div-Element für die Karte erstellen + const card = document.createElement('div'); + card.className = 'berater-card'; + + // Zertifikate verarbeiten (falls vorhanden) + let zertifikateHtml = ''; + if (berater.zertifikate && berater.zertifikate.length > 0) { + zertifikateHtml = `

Zertifikate

`; + } + + // Links verarbeiten (falls vorhanden) + let linksHtml = ''; + if (berater.links && berater.links.length > 0) { + linksHtml = ``; + } + + // Zusatzinformationen verarbeiten (falls vorhanden) + let zusatzHtml = ''; + if (berater.zusatzInfo) { + zusatzHtml = `

${berater.zusatzInfo}

`; + } + + // Eigene/unbekannte dynamische Felder verarbeiten + // Zuerst definieren wir, welche Felder Standard sind und ignoriert werden sollen + const standardFelder = ['id', 'name', 'role', 'image', 'bioTitle', 'bioText', 'zertifikate', 'links', 'zusatzInfo']; + let eigeneFelderHtml = ''; + + // Wir durchlaufen jeden Eintrag in der JSON für diesen spezifischen Berater + for (const [schluessel, wert] of Object.entries(berater)) { + // Wenn das Feld kein Standardfeld ist, generieren wir daraus eine Überschrift und den zugehörigen Text + if (!standardFelder.includes(schluessel)) { + eigeneFelderHtml += ` +

${schluessel}

+

${wert}

+ `; + } + } + + // Die Karte mit allen gesammelten HTML-Bausteinen zusammenbauen + card.innerHTML = ` +
+ ${berater.name} Profilbild +
+

${berater.name}

+

${berater.role}

+ +
+

${berater.bioTitle}

+

${berater.bioText}

+ + ${eigeneFelderHtml} + ${zusatzHtml} + ${zertifikateHtml} + ${linksHtml} +
+ `; + + // Die fertige Karte zum Container auf der Seite hinzufügen + container.appendChild(card); + }); +}); \ No newline at end of file diff --git a/js/beratung.js b/js/beratung.js new file mode 100644 index 0000000..bcae4ba --- /dev/null +++ b/js/beratung.js @@ -0,0 +1,51 @@ +// ----- Mobile Navigation ----- +(function () { + const toggle = document.querySelector(".nav-toggle"); + const nav = document.getElementById("main-nav"); + if (!toggle || !nav) return; + + toggle.addEventListener("click", function () { + const open = nav.classList.toggle("open"); + toggle.setAttribute("aria-expanded", String(open)); + toggle.setAttribute("aria-label", open ? "Menü schließen" : "Menü öffnen"); + }); + + // Menü nach Klick auf einen Link automatisch schließen + nav.querySelectorAll("a").forEach(function (link) { + link.addEventListener("click", function () { + nav.classList.remove("open"); + toggle.setAttribute("aria-expanded", "false"); + }); + }); +})(); + +// ----- Scroll-Reveal ----- +(function () { + const elements = document.querySelectorAll(".beratung-bereich .reveal"); + if (!elements.length) return; + + const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + + if (reduceMotion || !("IntersectionObserver" in window)) { + elements.forEach(function (el) { + el.classList.add("visible"); + }); + return; + } + + const observer = new IntersectionObserver( + function (entries) { + entries.forEach(function (entry) { + if (entry.isIntersecting) { + entry.target.classList.add("visible"); + observer.unobserve(entry.target); + } + }); + }, + { threshold: 0.12, rootMargin: "0px 0px -40px 0px" } + ); + + elements.forEach(function (el) { + observer.observe(el); + }); +})(); diff --git a/js/leistungen.js b/js/leistungen.js new file mode 100644 index 0000000..e37dbee --- /dev/null +++ b/js/leistungen.js @@ -0,0 +1,119 @@ +// 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", async () => { + const section = document.getElementById("leistungen"); + if (!section) return; + + // Integration: Der Datenpfad muss zum vorhandenen JSON-Ordner passen. + let daten; + try { + const response = await fetch("json/pakete.json"); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + daten = await response.json(); + } catch (error) { + section.querySelector(".pakete__text").textContent = "Die Pakete konnten nicht geladen werden. Bitte lade die Seite erneut."; + console.error("Pakete konnten nicht geladen werden:", error); + return; + } + + // Elemente aus dem HTML holen + const titel = section.querySelector(".pakete__titel"); + const text = section.querySelector(".pakete__text"); + const grid = section.querySelector(".pakete__grid"); + + // Intro mit Daten aus JSON füllen + titel.textContent = daten.intro.titel; + text.textContent = daten.intro.text; + + // Vorhandenen Inhalt entfernen + grid.innerHTML = ""; + + // Für jedes Paket eine Karte erstellen + daten.pakete.forEach(paket => { + + // Artikel erstellen + const karte = document.createElement("article"); + karte.classList.add("paket-karte"); + + // Empfohlenes Paket bekommt zusätzliche Klasse + if (paket.empfohlen) { + karte.classList.add("paket-karte--empfohlen"); + } + + // Badge nur erstellen, wenn eines vorhanden ist + if (paket.badge) { + const badge = document.createElement("p"); + badge.classList.add("paket-karte__badge"); + badge.textContent = paket.badge; + karte.appendChild(badge); + } + + // Name + const name = document.createElement("h3"); + name.classList.add("paket-karte__name"); + name.textContent = paket.name; + karte.appendChild(name); + + // Preis + const preis = document.createElement("p"); + preis.classList.add("paket-karte__preis"); + + const betrag = document.createElement("span"); + betrag.classList.add("paket-karte__betrag"); + betrag.textContent = `${paket.preis} €`; + + const zeitraum = document.createElement("span"); + zeitraum.classList.add("paket-karte__zeitraum"); + zeitraum.textContent = `/ ${paket.zeitraum}`; + + preis.appendChild(betrag); + preis.appendChild(zeitraum); + karte.appendChild(preis); + + // Beschreibung + const beschreibung = document.createElement("p"); + beschreibung.classList.add("paket-karte__beschreibung"); + beschreibung.textContent = paket.beschreibung; + karte.appendChild(beschreibung); + + // Leistungen + const liste = document.createElement("ul"); + liste.classList.add("paket-karte__leistungen"); + + paket.leistungen.forEach(leistung => { + const punkt = document.createElement("li"); + punkt.textContent = leistung; + liste.appendChild(punkt); + }); + + karte.appendChild(liste); + + // Button + const button = document.createElement("button"); + button.classList.add("paket-karte__cta"); + button.type = "button"; + button.textContent = "Paket wählen"; + button.dataset.paket = paket.dataPaket; + button.setAttribute("aria-pressed", "false"); + + // Die Paketauswahl aus der ersten Version auch nach dem JSON-Rendering erhalten. + button.addEventListener("click", () => { + grid.querySelectorAll(".paket-karte").forEach(andereKarte => { + andereKarte.classList.remove("paket-karte--ausgewaehlt"); + andereKarte.querySelector("button").setAttribute("aria-pressed", "false"); + }); + karte.classList.add("paket-karte--ausgewaehlt"); + button.setAttribute("aria-pressed", "true"); + document.dispatchEvent(new CustomEvent("paket:ausgewaehlt", { + detail: { paket: button.dataset.paket } + })); + }); + + karte.appendChild(button); + + // Karte ins Grid einfügen + grid.appendChild(karte); + }); +}); diff --git a/json/berater.json b/json/berater.json new file mode 100644 index 0000000..fff67f7 --- /dev/null +++ b/json/berater.json @@ -0,0 +1,52 @@ +{ + "intro": { + "titel": "Deine Ernährungsberater und Coaches", + "text": "Erfahrene Triathleten und zertifizierte Coaches, die dich auf dem Weg zu deinen Zielen begleiten und dir helfen, deine Leistung zu optimieren." + }, + "berater": [ + { + "id": 1, + "name": "Relindis Agethen ", + "role": "TRIATHLET UND ERNÄHRUNGSBERATERIN", + "image": "images/relindis_agethen.png", + "bioTitle": "Kurzbiografie", + "bioText": "Relindis Agethen, genannt Lilli, ist seit 16 Jahren im Triathlon aktiv und bringt starke sportliche Erfolge mit: Vize-Europameisterin, Deutsche Meisterin und mehrfache Baden-Württembergische Meisterin. Als zertifizierte Ernährungsberaterin für Sportler B-Lizenz ergänzt sie das Team um Leistungsentwicklung und Ernährungswissen.", + "zertifikate": [ + "Zertifizierter Triathlon-Trainer", + "Ernährungscoach B-Lizenz" + ], + "links": [ + { + "text": "Instagram Profil", + "url": "https://instagram.com" + }, + { + "text": "Trainingsplan buchen", + "url": "https://tri-hub.de/booking" + } + ] + }, + { + "id": 2, + "name": "Relindis Agethen ", + "role": "TRIATHLET UND ERNÄHRUNGSBERATERIN", + "image": "images/relindis_agethen_1.jpg", + "bioTitle": "Kurzbiografie", + "bioText": "Relindis Agethen, genannt Lilli, ist seit 16 Jahren im Triathlon aktiv und bringt starke sportliche Erfolge mit: Vize-Europameisterin, Deutsche Meisterin und mehrfache Baden-Württembergische Meisterin. Als zertifizierte Ernährungsberaterin für Sportler B-Lizenz ergänzt sie das Team um Leistungsentwicklung und Ernährungswissen.", + "zertifikate": [ + "Zertifizierter Triathlon-Trainer", + "Ernährungscoach B-Lizenz" + ], + "links": [ + { + "text": "Instagram Profil", + "url": "https://instagram.com" + }, + { + "text": "Trainingsplan buchen", + "url": "https://tri-hub.de/booking" + } + ] + } + ] +} \ No newline at end of file diff --git a/json/pakete.json b/json/pakete.json new file mode 100644 index 0000000..482b2d5 --- /dev/null +++ b/json/pakete.json @@ -0,0 +1,55 @@ +{ + "intro": { + "titel": "Deine Pakete", + "text": "Drei Wege zu einer Ernährung, die zu deinem Training, deinem Alltag und deinem Alter passt – entwickelt für Triathletinnen und Triathleten ab 50." + }, + "pakete": [ + { + "name": "Starter", + "preis": 79, + "zeitraum": "Monat", + "beschreibung": "Für den Einstieg in eine bewusste Ernährung neben dem Training.", + "leistungen": [ + "Erstgespräch & Bedarfsanalyse", + "Individueller Ernährungsplan", + "Monatliches Check-in per E-Mail", + "Zugang zu Beispielplänen" + ], + "badge": null, + "empfohlen": false, + "dataPaket": "Starter" + }, + { + "name": "STANDART", + "preis": 149, + "zeitraum": "Monat", + "beschreibung": "Laufende Begleitung für alle, die regelmäßig für Wettkämpfe trainieren.", + "leistungen": [ + "Alles aus Starter", + "Plan-Anpassung je Trainingsphase", + "Zwei Beratungsgespräche pro Monat", + "Wettkampf-Ernährungsstrategie", + "Direkter Chat mit deiner Beraterin" + ], + "badge": "Beliebteste Wahl", + "empfohlen": true, + "dataPaket": "Ausdauer" + }, + { + "name": "Rundum Sorglos Paket", + "preis": 249, + "zeitraum": "Monat", + "beschreibung": "Volle Betreuung für ambitionierte Athletinnen und Athleten.", + "leistungen": [ + "Alles aus Ausdauer", + "Wöchentliche Beratungsgespräche", + "Individuelle Supplement-Empfehlung", + "Betreuung am Wettkampftag", + "Priorisierter Support" + ], + "badge": null, + "empfohlen": false, + "dataPaket": "Wettkampf" + } + ] +} \ No newline at end of file diff --git a/script.js b/script.js deleted file mode 100644 index e69de29..0000000 diff --git a/style.css b/style.css deleted file mode 100644 index e69de29..0000000