/* ========================================================================== LANDING: hero and category tiles. ========================================================================== */ const TILE_SPAN = { stoffe: "wide", kontext: "wide", sport: "", ernahrung: "", schlaf: "", gesundheit: "", rezepte: "half", wettkampf: "half", }; function CategoryTile({ cat, span }) { const forumOnly = cat.forumOnly; const href = forumOnly ? "/forum?kind=recipe" : "/wissen?cat=" + cat.id; const count = forumOnly ? (cat.forumCount || 0) : cat.count; return ( {cat.image && ( { e.target.style.display = "none"; }} /> )}
{BB.num(count)} {BB.t("Einträge")} {cat.readCount > 0 && · {BB.num(cat.readCount)} {BB.t("gelesen")}}

{cat.label}

{cat.blurb &&

{cat.blurb}

}
); } function KnowledgeLanding({ categories, stats }) { const tops = useMemo( () => BB.children(categories, null).filter((c) => TILE_SPAN[c.id] !== undefined), [categories] ); const rest = useMemo( () => BB.children(categories, null).filter((c) => TILE_SPAN[c.id] === undefined), [categories] ); return ( <> {/* ---------------- hero ---------------- */}
{/* ---------------- categories ---------------- */}
{BB.t("Hauptkategorien")}

{BB.t("Wo willst du anfangen?")}

{BB.t("Jede Kategorie ist ein eigener Baum aus Unterthemen, von der Molekülstruktur bis zum fertigen Trainingsplan.")}

{tops.map((c) => )}
{rest.length > 0 && ( {rest.map((c) => ( {c.label} {c.count} ))} )}
); } /* ========================================================================== STARTSEITE: Premium-Funktionen zuerst. Die Wissensbasis hat ihre eigene Landingpage in KnowledgeLanding; hier wird das Produkt als zusammenhaengendes System aus Analyse, Wissen und Molekuelkarte gezeigt. ========================================================================== */ const HOME_ANALYSES = [ { id: "split", number: "01", label: "Trainingssplit", title: "Volumen sehen. Erholung verstehen.", copy: "Sätze, Frequenz und Übungsauswahl werden zu einer lesbaren Woche. Du siehst nicht nur den Score, sondern jede Annahme darunter.", score: 86, scoreLabel: "stimmige Belastung", note: "2 Stellen verdienen Aufmerksamkeit", path: "M4 72 C22 68 30 30 49 37 S78 78 98 52 S128 17 151 28 S180 65 206 20", metrics: [["Wochenvolumen", 0.86], ["Erholung", 0.74], ["Abdeckung", 0.92]], facts: ["18 Muskelgruppen", "5 Trainingstage", "jede Zahl begründet"], }, { id: "stack", number: "02", label: "Stack", title: "Zusammenspiel statt Einzelliste.", copy: "Wirkstoffe, Dosis und Dauer werden gemeinsam betrachtet: Zielabdeckung, Redundanz, Organlast und bekannte Interaktionen bleiben getrennt nachvollziehbar.", score: 62, scoreLabel: "erhöhte Komplexität", note: "3 Überschneidungen im Blick behalten", path: "M4 64 C22 42 38 52 54 31 S82 20 101 48 S130 76 148 43 S183 28 206 39", metrics: [["Zielabdeckung", 0.81], ["Redundanz", 0.58], ["Datenlage", 0.69]], facts: ["5 Wirkstoffe", "11 Wirkungspfade", "keine Empfehlung"], }, { id: "meal", number: "03", label: "Mahlzeit", title: "Mehr Kontext als Makros.", copy: "Eine Mahlzeit wird für ihren Anlass gelesen. Nährwerte, Kaloriendichte, Verdauung und Mikronährstoffe landen in derselben verständlichen Ansicht.", score: 91, scoreLabel: "passt zum Trainingsziel", note: "Proteinverteilung ist der stärkste Punkt", path: "M4 67 C24 63 34 48 51 51 S77 58 94 36 S119 18 140 31 S173 59 206 24", metrics: [["Protein", 0.94], ["Energiedichte", 0.72], ["Mikronährstoffe", 0.79]], facts: ["742 kcal", "54 g Protein", "Anlass einbezogen"], }, { id: "blood", number: "04", label: "Blutbild", title: "Werte im richtigen Zusammenhang.", copy: "Messwerte werden im Referenzbereich verortet und mit Training, Belastung und zeitlichem Verlauf gelesen. Auffällig heißt nicht automatisch schlecht.", score: 78, scoreLabel: "überwiegend unauffällig", note: "2 Werte brauchen Verlauf statt Momentaufnahme", path: "M4 55 C23 35 39 61 57 42 S88 30 107 37 S131 62 151 48 S178 17 206 30", metrics: [["Referenzlage", 0.82], ["Verlauf", 0.67], ["Vollständigkeit", 0.88]], facts: ["24 Messwerte", "3 Zeitpunkte", "Kontext statt Diagnose"], }, ]; const HOME_MAP_NODES = [ { id: "testosteron", label: "Testosteron", name: "Testosteron", type: "substance", seed: true, tiefe: 0, detail: "Ausgangspunkt der Demo. Von hier werden Bindungen, Umwandlungen und Analyse-Endpunkte sichtbar." }, { id: "ar", label: "AR", name: "Androgenrezeptor", type: "receptor", tiefe: 1, detail: "Der Androgenrezeptor verbindet den Stoff mit mehreren nachgelagerten biologischen Signalen." }, { id: "cyp19a1", label: "CYP19A1", name: "Aromatase · CYP19A1", type: "enzyme", tiefe: 1, detail: "Das Enzym bildet die Brücke zur Umwandlung von Testosteron in Estradiol." }, { id: "estradiol", label: "Estradiol", name: "Estradiol", type: "metabolite", tiefe: 2, detail: "Ein Metabolit mit eigenen Rezeptorwegen – nicht bloß ein Nebenprodukt in der Karte." }, { id: "esr1", label: "ESR1", name: "Estrogenrezeptor alpha", type: "receptor", tiefe: 2, detail: "Ein Zielprotein, über das Estradiol weitere regulatorische Wege erreicht." }, { id: "protein", label: "MPS", name: "Muskelproteinsynthese", type: "endpoint", tiefe: 2, detail: "Ein virtueller Analyse-Endpunkt bündelt mehrere belegte Wege, ohne sie zu einer Behauptung zu verkürzen." }, { id: "shbg", label: "SHBG", name: "Sexualhormon-bindendes Globulin", type: "transporter", tiefe: 1, detail: "Der Transportknoten zeigt, dass freie und gebundene Anteile im System nicht dasselbe sind." }, ]; const HOME_MAP_EDGES = [ { id: 1, src: "testosteron", dst: "ar", mechanism: "agonist", evidence: "measured", strength: 0.95, confidence: 0.94, messungen: 12 }, { id: 2, src: "testosteron", dst: "cyp19a1", mechanism: "substrate", evidence: "measured", strength: 0.76, confidence: 0.89, messungen: 7 }, { id: 3, src: "cyp19a1", dst: "estradiol", mechanism: "produces", evidence: "measured", strength: 0.86, confidence: 0.91, messungen: 8 }, { id: 4, src: "estradiol", dst: "esr1", mechanism: "agonist", evidence: "measured", strength: 0.88, confidence: 0.93, messungen: 10 }, { id: 5, src: "ar", dst: "protein", mechanism: "positive_modulator", evidence: "predicted", strength: 0.66, confidence: 0.72, effect: 1 }, { id: 6, src: "testosteron", dst: "shbg", mechanism: "binding", evidence: "measured", strength: 0.72, confidence: 0.87, messungen: 5 }, ]; const HOME_MAP_TYPE_LABEL = { substance: "Substanz", metabolite: "Metabolit", receptor: "Rezeptor", enzyme: "Enzym", transporter: "Transporter", regulator: "Regulator", endpoint: "Analyse-Endpunkt", }; function HomeHero({ stats }) { return (
); } function HomeAnalysisPreview({ story }) { return (
{BB.t("Beispielanalyse")} {BB.t("vollständig begründet")}
{BB.t("Gesamtbild")} {story.score} {BB.t(story.scoreLabel)}
{story.metrics.map(([label, value]) => (
{BB.t(label)}{Math.round(value * 100)}%
))}
{BB.t(story.note)}
); } function HomeAnalysisShowcase() { const [active, setActive] = useState(0); const [direction, setDirection] = useState(1); const stageRef = useRef(null); const animationRef = useRef(null); const story = HOME_ANALYSES[active]; useEffect(() => { const stage = stageRef.current; if (!stage || BB.reducedMotion() || !stage.animate) return undefined; if (animationRef.current) animationRef.current.cancel(); animationRef.current = stage.animate( [ { opacity: 0.35, transform: `translate3d(${direction * 24}px, 0, 0)`, filter: "blur(2px)" }, { opacity: 1, transform: "translate3d(0, 0, 0)", filter: "blur(0)" }, ], { duration: 600, easing: "cubic-bezier(0.23, 1, 0.32, 1)" } ); return () => { if (animationRef.current) animationRef.current.cancel(); }; }, [active, direction]); function select(next) { if (next === active) return; setDirection(next > active ? 1 : -1); setActive(next); } function step(delta) { const next = (active + delta + HOME_ANALYSES.length) % HOME_ANALYSES.length; setDirection(delta > 0 ? 1 : -1); setActive(next); } return (
{BB.t("Premium Analysen")}

{BB.t("Nicht nur ein Score.")} {BB.t("Die ganze Rechnung.")}

{BB.t("Jede Auswertung zeigt, wie sie zu ihrem Ergebnis kommt – vom Eingangswert bis zur Quelle. Vier Perspektiven, dieselbe Klarheit.")}

{ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return; event.preventDefault(); const delta = event.key === "ArrowRight" ? 1 : -1; const next = (active + delta + HOME_ANALYSES.length) % HOME_ANALYSES.length; select(next); const tabs = event.currentTarget.querySelectorAll('[role="tab"]'); if (tabs[next]) tabs[next].focus(); }} > {HOME_ANALYSES.map((item, index) => ( ))}
{ if (event.key === "ArrowLeft") { event.preventDefault(); step(-1); } if (event.key === "ArrowRight") { event.preventDefault(); step(1); } }} >
{story.number} / 04 · {BB.t(story.label)}

{BB.t(story.title)}

{BB.t(story.copy)}

    {story.facts.map((fact) =>
  • {BB.t(fact)}
  • )}
{BB.t("Analyse öffnen")}
0{active + 1} 04
); } function HomeMoleculeDemo() { const [selected, setSelected] = useState(HOME_MAP_NODES[0]); function pick(node) { const match = HOME_MAP_NODES.find((item) => String(item.id) === String(node.id)); if (match) setSelected(match); } const links = HOME_MAP_EDGES.filter((edge) => edge.src === selected.id || edge.dst === selected.id).length; return (
{BB.t("Molekülkarte")}

{BB.t("Vom Stoff zum System.")} {BB.t("Eine Verbindung nach der anderen.")}

{BB.t("Diese kleine Auswahl nutzt bereits die echte Kartenansicht. Wähle eine Node und verfolge, wie Substanz, Enzym, Rezeptor und Endpunkt zusammenhängen.")}

{BB.t("Interaktive Demo")} {HOME_MAP_NODES.length} {BB.t("ausgewählte Nodes")}
{}} onZuklappen={() => {}} onNodeSelect={pick} />
); } function HomeClosing() { return (
{BB.t("Bodybuilding Bible Premium")}

{BB.t("Deine Frage ist der Anfang.")} {BB.t("Nicht das Ende der Erklärung.")}

{BB.t("Starte mit einer Analyse oder tauche kostenlos in die kuratierte Wissensbasis ein.")}

{BB.t("Analyse starten")} {BB.t("Wissen entdecken")}
); } function HomeLoader({ ready }) { return (
); } function Landing({ categories, stats }) { const [ready, setReady] = useState(() => { try { return window.sessionStorage.getItem("bb-home-image-ready") === "1"; } catch (_) { return false; } }); useEffect(() => { if (ready) return undefined; const previousOverflow = document.body.style.overflow; const startedAt = performance.now(); const image = new Image(); let active = true; let settled = false; let revealTimer; let fallbackTimer; document.body.style.overflow = "hidden"; document.body.classList.add("home-is-loading"); const reveal = () => { if (settled) return; settled = true; window.clearTimeout(fallbackTimer); const remaining = Math.max(0, 400 - (performance.now() - startedAt)); revealTimer = window.setTimeout(() => { if (!active) return; try { window.sessionStorage.setItem("bb-home-image-ready", "1"); } catch (_) { /* Storage can be disabled without blocking the page. */ } setReady(true); }, remaining); }; image.onload = reveal; image.onerror = reveal; image.src = "/static/assets/landing-gym.jpg?v=hero4k1"; if (image.decode) image.decode().then(reveal).catch(() => { if (image.complete) reveal(); }); fallbackTimer = window.setTimeout(reveal, 4000); return () => { active = false; window.clearTimeout(revealTimer); window.clearTimeout(fallbackTimer); image.onload = null; image.onerror = null; document.body.style.overflow = previousOverflow; document.body.classList.remove("home-is-loading"); }; }, [ready]); return (
); } Object.assign(window, { Landing, KnowledgeLanding, CategoryTile });