/*
 * home.css – Seitenspezifische Stile für die Homepage (front-page.php)
 */

/* ============================================================
   HERO — Premium Full-Bleed (E.ON Firmenlauf Design)
   ============================================================ */

.hero {
    position: relative;
    min-height: 100svh;
    display: flex;
    align-items: center;
    overflow: hidden;
    background-color: var(--hero-ground);
}

/* 🔴 Das Bild blendet mit ein (03.09.2026, gemeldet von Dennis: „Background Element lädt
   sofort, erst dann lädt Text rein. Sieht falsch aus, da Background so erst alleine steht").
   Der Text im Kopfbereich kommt gestaffelt über `animate-fade-up`; das Foto stand ohne jede
   Einblendung sofort da und wirkte dadurch wie ein Bild, das auf seinen Text wartet.

   ⚠️ Die Einblendung liegt am CONTAINER, nicht an den Bildern. Bei mehreren Bildern trägt
   jedes davon bereits die Animation des Wechsels; eine zweite darauf würde sie überschreiben
   oder mit ihr um denselben Zeitstrahl streiten.

   ⚠️ Kürzer als die Textstaffel (0,55 s gegen 0,7 s plus Verzögerung): Das Bild ist der Grund,
   auf dem der Text steht, es soll vor ihm da sein, nicht mit ihm. */
.hero__media {
    position: absolute;
    inset: 0;
    z-index: 0;
    animation: hero-bild-ein 0.55s ease-out both;
}
@keyframes hero-bild-ein {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .hero__media { animation: none; }
}

.hero__video,
.hero__poster {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 30%;
    display: block;
}

/* ============================================================
   HERO — Bilderwechsel (Kollektion `hero_slider`)
   ------------------------------------------------------------
   Jedes Bild steht 6 Sekunden, das Ueberblenden dauert 1,2 Sekunden. Der Wechsel laeuft
   bewusst in CSS statt in JavaScript: er funktioniert dann auch, wenn ein Skript spaeter
   laedt oder ausfaellt, und belastet den Haupt-Thread nicht. Die Versaetze setzt das
   Template ueber animation-delay, die Gesamtdauer kommt als Variable aus dem PHP.
   ============================================================ */

.hero__slider { position: absolute; inset: 0; }

.hero__slider-bild {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 30%;
    opacity: 0;
    animation-duration: var(--hero-slider-dauer, 18s);
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-fill-mode: both;
}

@keyframes heroWechsel2 {
    0%      { opacity: 0; }
    10.0%  { opacity: 1; }
    50.0%  { opacity: 1; }
    60.0%  { opacity: 0; }
    100%    { opacity: 0; }
}
.hero__slider[data-anzahl="2"] .hero__slider-bild { animation-name: heroWechsel2; }

@keyframes heroWechsel3 {
    0%      { opacity: 0; }
    6.667%  { opacity: 1; }
    33.333%  { opacity: 1; }
    40.0%  { opacity: 0; }
    100%    { opacity: 0; }
}
.hero__slider[data-anzahl="3"] .hero__slider-bild { animation-name: heroWechsel3; }

@keyframes heroWechsel4 {
    0%      { opacity: 0; }
    5.0%  { opacity: 1; }
    25.0%  { opacity: 1; }
    30.0%  { opacity: 0; }
    100%    { opacity: 0; }
}
.hero__slider[data-anzahl="4"] .hero__slider-bild { animation-name: heroWechsel4; }

@keyframes heroWechsel5 {
    0%      { opacity: 0; }
    4.0%  { opacity: 1; }
    20.0%  { opacity: 1; }
    24.0%  { opacity: 0; }
    100%    { opacity: 0; }
}
.hero__slider[data-anzahl="5"] .hero__slider-bild { animation-name: heroWechsel5; }

@keyframes heroWechsel6 {
    0%      { opacity: 0; }
    3.333%  { opacity: 1; }
    16.667%  { opacity: 1; }
    20.0%  { opacity: 0; }
    100%    { opacity: 0; }
}
.hero__slider[data-anzahl="6"] .hero__slider-bild { animation-name: heroWechsel6; }

/* Wer Bewegung reduziert haben moechte, bekommt ein stehendes Bild statt eines Wechsels. */
@media (prefers-reduced-motion: reduce) {
    .hero__slider-bild { animation: none; opacity: 0; }
    .hero__slider-bild:first-child { opacity: 1; }
}

.hero__placeholder {
    width: 100%;
    height: 100%;
    background: var(--hero-placeholder);
}


/* Diagonaler Marken-Overlay über dem Hero-Foto. Beide Verlaufsstufen kommen aus Token,
   damit jedes Event seine eigene Lichtstimmung bekommt statt des E.ON-Rots. */
.hero__overlay {
    position: absolute;
    inset: 0;
    background:
        /* Dieselbe flächige Abdunklung wie im Foto-Band, siehe dort. */
        linear-gradient(rgba(0, 0, 0, var(--text-schleier, 0)),
                        rgba(0, 0, 0, var(--text-schleier, 0))),
        var(--hero-overlay),
        linear-gradient(to top, var(--hero-overlay-foot) 0%, transparent 55%);
}

.hero__content {
    position: relative;
    z-index: 1;
    padding-top: calc(var(--header-height) + var(--space-12));
    padding-bottom: var(--space-20);
    width: 100%;

    color: var(--color-white);
}

.hero__inner {
    max-width: 640px;
}

.hero__brand {
    margin-bottom: var(--space-6);
}

.hero__brand-logo {
    height: 56px;
    width: auto;
    max-width: 260px;
}

.hero__eyebrow {
    font-family: var(--font-heading);
    font-size: var(--text-base);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--color-text-on-primary);
    background: var(--color-primary);
    display: inline-block;
    padding: var(--space-1) var(--space-4);
    margin-bottom: var(--space-5);
}

/* „präsentiert von <Logo>" unter der Titelzeile (Schalter hero_presenter). Das Logo steht auf einer
   weißen Platte: Wortmarken wie Westenergie tragen schwarze Schrift und wären auf dem dunklen
   Foto sonst unsichtbar. */
.hero__presenter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
}
.hero__presenter-label,
.hero__presenter-name {
    font-family: var(--font-heading);
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.85);
}
.hero__presenter-name { font-size: var(--text-lg); text-transform: none; letter-spacing: 0; }
.hero__presenter-logo {
    display: inline-flex;
    align-items: center;
    background: #FFFFFF;
    border-radius: 8px;
    padding: 6px 14px;
    line-height: 0;
}
.hero__presenter-logo img { height: 34px; width: auto; max-width: 220px; display: block; }
/* Freigestelltes Logo: keine Platte, Originalgröße der Datei (auf schmalen Schirmen höchstens
   die Breite der Zeile). */
.hero__presenter-logo--frei { background: none; border-radius: 0; padding: 0; }
.hero__presenter-logo--frei img { height: auto; width: auto; max-width: min(100%, 300px); max-height: none; }
body.be-hero-mitte .hero__presenter { justify-content: center; }

.hero__title {
    font-family: var(--font-display);
    font-size: var(--hero-title-size);
    font-weight: var(--hero-title-weight);
    /* Zeilenhöhe gehört zur Schrift, genau wie Größe, Stärke und Laufweite. Sie stand hier
       fest auf 0,95 — bei den Grotesken der Schwestersites richtig, bei einer gezeichneten
       Comic-Schrift überlappten zwei Zeilen. Der Vorgabewert bleibt 0,95, damit sich ohne
       gepflegten Wert nichts ändert. */
    line-height: var(--hero-title-leading, 0.95);
    letter-spacing: var(--hero-title-tracking);
    text-transform: var(--hero-title-transform);
    color: var(--color-white);
    margin-bottom: var(--space-6);
}

/* ⚠️ Ab 640 px trennt der Hero-Titel NICHT automatisch.
 *
 * `hyphens: auto` steht in main.css auf allen Überschriften und ist dort richtig: auf schmalen
 * Geräten laufen lange deutsche Wörter sonst über den Rand. In einer Schlagzeile greift die
 * Trennung aber auch dann, wenn das ganze Wort noch in die nächste Zeile gepasst hätte —
 * gemessen am Mülheimer Firmenlauf wurde aus „Die sportlichste Betriebsfeier der Stadt" ein
 * „DIE SPORTLICHSTE BE-TRIEBSFEIER DER STADT". Ein getrenntes Wort in der größten Schrift der
 * Seite liest sich wie ein Fehler.
 *
 * Unter 640 px bleibt die Trennung: dort ist der Überlauf das größere Problem, und die
 * Schriftgrößen sind so klein, dass eine Trennung nicht mehr als Schaden auffällt.
 */
@media (min-width: 640px) {
    .hero__title { hyphens: manual; }
}

.hero__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-8);
    font-size: var(--text-base);
    font-weight: 500;
    color: rgba(255, 255, 255, 0.80);
}

.hero__meta-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.hero__meta-item .icon-location {
    font-size: 0.85em;
    opacity: 0.70;
}

/* Letzte Titelzeile in der Akzentfarbe (Branding-Schalter hero_title_akzent).
   Der Kunde steuert das ueber den Zeilenumbruch im Titel, nicht ueber ein Sonderzeichen. */
.hero__title-akzent { color: var(--color-accent, var(--color-primary)); }

.hero__meta-sep {
    color: rgba(255, 255, 255, 0.30);
    font-weight: 300;
}

/* Datum und Ort passen auf schmalen Bildschirmen nicht nebeneinander. Beim Umbruch blieb der
   Trennstrich als letztes Zeichen der ersten Zeile stehen und sah aus wie ein leeres Feld
   hinter dem Datum. Untereinander braucht es ihn nicht. */
@media (max-width: 640px) {
    .hero__meta { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
    /* ⚠️ `.hero__meta-item` ist selbst ein Flex-Kasten und bemisst sich am Inhalt. Ohne
       `min-width: 0` kann er nicht unter die Breite seines längsten Textes schrumpfen, und ein
       langes Datum („Donnerstag, 17. September 2026“) lief bei doppelter Schrift 57 px aus dem
       Bild. Das Umbrechen erlaubt zusätzlich, dass Symbol und Text getrennte Zeilen bekommen. */
    .hero__meta-item { flex-wrap: wrap; min-width: 0; max-width: 100%; }
    .hero__meta-sep { display: none; }
    body.be-hero-mitte .hero__meta { align-items: center; }
}

.hero__countdown-wrapper {
    margin-bottom: var(--space-8);
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.hero__scroll {
    position: absolute;
    bottom: var(--space-8);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    text-decoration: none;
}

.hero__scroll-line {
    width: 1px;
    height: 48px;
    background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.50));
    animation: scrollPulse 2s ease-in-out infinite;
}

@media (max-width: 767px) {
    .hero__title {
        font-size: clamp(2.5rem, 10vw, 4rem);
    }
    .hero__brand-logo {
        height: 40px;
    }
    .hero__inner {
        max-width: 100%;
    }
}

/* ============================================================
   FACTS BAR
   ============================================================ */

.facts-bar {
    /* Eigenes Token, damit die Fakten-Leiste unabhängig vom Marken-Verlauf gesetzt werden kann.
       Ohne gepflegten Wert bleibt es exakt beim bisherigen Verhalten. */
    background: var(--surface-band, var(--gradient-eon));
    padding-block: var(--space-6);
    border-bottom: none;
}

.facts-bar__inner {
    display: flex;
    flex-wrap: wrap;
    /* Der Abstand ersetzt das frühere `space-between`: er hält die Fakten auch ohne
       Wachstum über die Breite verteilt, statt sie in der Mitte zusammenzuziehen. */
    gap: clamp(1.5rem, 3.5vw, 4.5rem);
    align-items: center;
    /* ⚠️ Bewusst NICHT `space-between`. Solange alle Fakten in eine Zeile passen, sieht man
       keinen Unterschied. Sobald sie umbrechen — bei fünf Fakten gemessen ab etwa 1200 px —
       verteilt `space-between` die volle Reihe über die Breite und lässt den einzelnen Rest
       LINKS stehen. Bei 1100 px ergab das 4 + 1 mit dem letzten Fakt am linken Rand.
       Zentriert steht eine unvollständige Reihe mittig unter der vollen. Dieselbe Überlegung
       wie bei der Partnerwand, wo `justify-content: center` genau deshalb gesetzt ist. */
    justify-content: center;
}

/* .facts-bar__item → layout.css (ein Besitzer, siehe Kommentar dort) */

.facts-bar__icon {
    font-size: 3rem;
    flex-shrink: 0;
    color: var(--color-white);
    opacity: 0.90;
    line-height: 1;
}

.facts-bar__label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: rgba(255, 255, 255, 0.65);
    margin-bottom: var(--space-1);
    font-weight: 600;
}

.facts-bar__value {
    font-family: var(--font-heading);
    font-size: var(--text-lg);
    font-weight: 800;
    color: var(--color-white);
    letter-spacing: var(--tracking-tight);

    line-height: 1;
    text-transform: uppercase;
}

/* Der Textblock muss schrumpfen dürfen: ohne `min-width: 0` bleibt ein Flex-Element mindestens
   so breit wie sein längstes Wort, und „DÜSSELDORF" oder „ELEKTRONISCHE" schoben die Leiste
   über den Bildschirmrand hinaus. */
.facts-bar__item > div { min-width: 0; }
/* `anywhere` bricht MITTEN im Wort, auch wenn es gar nicht noetig waere: aus
   „Veranstaltungsort" wurde auf dem Handy „Veranstaltungs / ort". `break-word` bricht nur, wenn
   ein Wort sonst wirklich ueberliefe, und trennt bei deutschen Komposita zusaetzlich sauber,
   wo `hyphens` greifen darf. */
.facts-bar__value,
.facts-bar__label { overflow-wrap: break-word; hyphens: auto; }

@media (max-width: 767px) {
    .facts-bar__inner {
        gap: var(--space-5);
    }
    .facts-bar__item {
        min-width: 140px;
    }
}

/* Auf schmalen Geräten steht das Icon ÜBER dem Text statt daneben. Nebeneinander bleiben bei
   390 px nach Icon und Abstand nur rund 105 px für die Beschriftung — zu wenig für
   „Elektronische Zeitmessung".

   Bewusst RASTER statt Flexbox: `minmax(0, 1fr)` garantiert, dass eine Spalte schmaler werden
   darf als ihr Inhalt. Mit Flexbox hing genau das an `min-width: 0` und an der Frage, ob die
   Summe aus Basisbreiten und Abstand in die Zeile passt — beides hatte ich falsch, die zweite
   Spalte lief über den Bildschirmrand hinaus. */
@media (max-width: 640px) {
    .facts-bar__inner {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-6) var(--space-4);
    }
    .facts-bar__item {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--space-2);
        min-width: 0;
        /* ⚠️ `.facts-bar__item` ist ZWEIMAL definiert: hier und in layout.css. Dort steht
           `text-align: center`. Diese Regel setzte bisher nur die Flex-Achse zurueck, nicht die
           Textausrichtung — die Icons standen also links, die Beschriftungen darunter mittig.
           Genau das sah "verschoben" aus. Wer hier etwas aendert, prueft immer beide Dateien. */
        text-align: left;
    }
    .facts-bar__icon { font-size: 2.25rem; }
    /* Bei ungerader Anzahl steht der letzte Fakt allein in der Reihe. Ueber beide Spalten
       GESTRECKT sah er aus wie eine Stufe; zentriert wirkt er gesetzt statt uebrig. */
    .facts-bar__item:last-child:nth-child(odd) {
        grid-column: 1 / -1;
        align-items: center;
        text-align: center;
    }
}

/* ============================================================
   INTRO-SEKTION
   ============================================================ */

.intro-section {
    background: var(--surface-page);
    padding-block: var(--section-gap);
}

.intro-section__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-16);
    align-items: center;
}

@media (max-width: 900px) {
    .intro-section__grid {
        grid-template-columns: 1fr;
        gap: var(--space-10);
    }
    .intro-section__photo {
        order: -1;
    }
}

.intro-section__title {
    font-size: var(--section-h2-xl);
    font-weight: 900;
    line-height: var(--leading-tight);
    color: var(--color-text);
    margin-bottom: var(--space-8);
}

.intro-section__body {
    font-size: var(--text-lg);   /* war eine feste Zahl (22 px), siehe Hinweis bei `p` in main.css */
    line-height: 1.7;
    color: var(--color-text-muted);
    margin-bottom: var(--space-6);
}

.intro-section__claim {
    font-size: var(--text-2xl);
    font-weight: 800;
    color: var(--color-primary);
    margin: 0;
}

.intro-section__photo {
    position: relative;
    border-radius: var(--radius-2xl);
    overflow: hidden;
    aspect-ratio: 3 / 2;
}

.intro-section__photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.6s ease;
}

.intro-section__photo:hover img {
    transform: scale(1.03);
}

.intro-section__photo-accent {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        135deg,
        rgba(var(--color-primary-rgb), 0.12) 0%,
        rgba(var(--color-dark-rgb), 0.06) 60%,
        transparent 100%
    );
    pointer-events: none;
}

/* ============================================================
   CTA-GRID (3 Karten)
   ============================================================ */

.cta-grid {
    padding-block: var(--section-gap);
}

.cta-grid__inner {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}

@media (min-width: 640px) {
    .cta-grid__inner {
        grid-template-columns: repeat(2, 1fr);
    }
    .cta-grid__inner > :first-child {
        grid-column: 1 / -1;
    }
}

@media (min-width: 1024px) {
    .cta-grid__inner {
        grid-template-columns: repeat(3, 1fr);
    }
    .cta-grid__inner > :first-child {
        grid-column: auto;
    }
}

/* ============================================================
   NEWS-SECTION
   ============================================================ */

.news-section {
    padding-block: var(--section-gap);
    background: var(--surface-sunken);
}

/* Ergänzt die Grundregel aus layout.css, statt sie zu wiederholen.
 *
 * Vorher stand hier derselbe Block noch einmal, und er unterschied sich in genau zwei Werten.
 * Weil home.css nach layout.css lädt, gewann er auf der Startseite — auf Unterseiten (Sponsoren)
 * galt dagegen die Fassung aus layout.css. Dieselbe Klasse sah also je nach Seite anders aus,
 * und wer künftig an layout.css schraubt, hätte auf der Startseite keine Wirkung gesehen.
 *
 * Die zwei Abweichungen bleiben absichtlich: Die Startseite setzt ihre Abschnitte großzügiger
 * ab, und dort steht neben der Überschrift oft ein Verweis, der an der Grundlinie der Unterkante
 * besser sitzt als an der Schriftgrundlinie. Die Darstellung ändert sich durch diesen Umbau
 * nirgends — nur die Herkunft der Werte ist jetzt eindeutig. */
/* .section__header → layout.css (ein Besitzer, siehe Kommentar dort) */

/* .section__kicker → components.css (global) */

.news-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}

@media (min-width: 640px) {
    .news-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
    .news-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================================
   ALLGEMEINE SECTION-BASIS
   ============================================================ */

.section {
    padding-block: var(--section-gap);
}

.section--dark {
    background: var(--gradient-eon-dark);
    color: var(--color-text-white);
}

.section--surface {
    background: var(--color-surface);
}

/* layout.css setzt bereits Spaltenrichtung, Zentrierung und Textausrichtung. Hier bleibt nur,
 * was dort fehlt — und das Zurücknehmen des flex-end von oben. */
.section__header--center {
    justify-content: center;
    align-items: center;
}

.section__link {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-primary);
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
}
.section__link:hover { color: var(--color-primary-dark); }

/* ============================================================
   COUNTDOWN-SEKTION (dunkler Hintergrund, 2-spaltig)
   ============================================================ */

.countdown-section {
    padding-block: var(--section-gap);
    background: var(--gradient-eon);
    color: var(--color-text-white);
}

.countdown-section__inner {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-12);
    align-items: center;

    flex-direction: column;
    text-align: center;
}

@media (min-width: 860px) {
    .countdown-section__inner {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-16);
    }
}

/* Kicker */
.countdown-section__kicker {
    color: rgba(255,255,255,0.60) !important;
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    font-weight: 600;
    display: block;
    margin-bottom: var(--space-3);
}

/* Datum als Headline — groß, mutig */
.countdown-section__title {
    font-family: var(--font-heading);
    font-size: clamp(2rem, 5vw, 3.5rem);
    font-weight: 900;
    color: var(--color-white);
    line-height: var(--leading-tight);
    margin-bottom: var(--space-4);
}

/* Ort */
.countdown-section__location {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-base);
    color: rgba(255,255,255,0.60);
    margin-bottom: var(--space-5);
}

.countdown-section__location svg {
    flex-shrink: 0;
    opacity: 0.7;
}

/* Beschreibung + Preis */
.countdown-section__subtitle {
    font-size: var(--text-base);
    color: rgba(255,255,255,0.70);
    line-height: var(--leading-loose);
    margin-bottom: var(--space-8);
    max-width: 38ch;
}

.countdown-section__subtitle strong {
    color: var(--color-white);
    font-weight: 700;
}

/* Anmeldung geschlossen */
.countdown-section__closed {
    font-size: var(--text-sm);
    color: rgba(255,255,255,0.50);
    margin-top: var(--space-4);
}

/* Widget-Seite */
.countdown-section__widget {
    display: flex;
    justify-content: center;
    align-items: center;
}

.countdown-section__widget-inner {
    text-align: center;
}

.countdown-section__widget-label {
    font-size: var(--text-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: rgba(255,255,255,0.45);
    margin-top: var(--space-4);
}

.countdown-section .section__kicker {
    color: var(--color-accent);
}

.countdown-section__cta {
    margin-top: var(--space-10);
    display: flex;
    gap: var(--space-4);
    justify-content: center;
    flex-wrap: wrap;
}

/* ============================================================
   SPONSOR-WALL
   ============================================================ */

/* Sponsor-Wall-Styles → components.css (dort global verfügbar) */

/* ============================================================
   CTA-KARTEN MIT FOTO-HINTERGRUND
   ============================================================ */

.cta-card--photo {
    background-image: var(--card-photo);
    background-size: cover;
    background-position: center;
    border-color: transparent;
    color: var(--color-white);
    min-height: 280px;
}

.cta-card--photo::before {
    /* ZWEI Schleier, nicht einer.
       Der Marken-Schleier laeuft von LINKS nach rechts und ist am rechten Rand fast klar (5 %).
       Der Text steht aber UNTEN und laeuft ueber rund 70 % der Kartenbreite — auf einem hellen
       Foto stand er dadurch fast ohne Untergrund.
       Gemessen am 19.08.2026 an den drei echten Kartenfotos: der kleine Text kam im
       schlechtesten Fall auf 1,97:1 (gefordert sind 4,5:1). Mit dem neutralen Schleier von unten
       und 92 % Deckkraft am Text sind es 4,82:1.
       Der neutrale Verlauf liegt VOR dem Marken-Verlauf (erste Ebene = oben) und dunkelt nur
       dort, wo Schrift steht; die obere Kartenhaelfte behaelt das Foto. */
    background:
        linear-gradient(to top, rgba(0, 0, 0, 0.68) 0%, rgba(0, 0, 0, 0.34) 38%, rgba(0, 0, 0, 0) 68%),
        var(--overlay-card);
    height: 100%;
    top: 0;
}

.cta-card--photo:hover {
    border-color: transparent;
    color: var(--color-white);
    filter: brightness(1.06);
}

.cta-card--photo .cta-card__icon,
.cta-card--photo .cta-card__title,
.cta-card--photo .cta-card__text,
.cta-card--photo .cta-card__arrow {
    position: relative;
    z-index: 1;
    color: var(--color-white);
}

.cta-card--photo .cta-card__icon {
    color: rgba(255, 255, 255, 0.90);
}

.cta-card--photo .cta-card__text {
    /* 85 % kosteten rund 0,75 Kontrastpunkte. Die Abstufung zum Titel traegt die
       Schriftgroesse, dafuer braucht es keine Transparenz. */
    opacity: 0.92;
}

/* Schrift auf Fotos bekommt zusaetzlich eine weiche Kante. Sie ersetzt keinen Schleier, faengt
   aber die feinen Lichtpunkte ab, die ein Mittelwert nicht sieht (dieselbe Ueberlegung wie bei
   den Unterseiten-Bannern, 15.08.2026). */
/* 🔴 NUR wo der Text wirklich IM Bild steht (03.09.2026).
 *
 * Die Regel galt fuer jede Karte mit Foto. In den Varianten `liste` (Foto ausgeblendet) und
 * `medien` (Bild oben, Text darunter auf der Kartenflaeche) steht der Text aber auf Papier,
 * und der Schatten sah dort aus wie ein Fehler. Gemeldet von Dennis, zweimal am selben Tag:
 * erst fuer die Liste auf rcr, dann fuer „Unsere Extras" auf mf.
 *
 * ⚠️ Deshalb steht hier jetzt die UMGEKEHRTE Bedingung. Vorher war der Schatten die Regel und
 * jede Variante eine Ausnahme, die man einzeln nachtragen muss; jetzt bekommt ihn nur, wer den
 * Text ueber das Foto legt. Eine neue Variante faengt damit keinen falschen Schatten mehr ein.
 * Legt sie den Text doch ins Bild, meldet Pruefung 30 den fehlenden Kontrast. */
.cta-grid:not(.cta-grid--liste):not(.cta-grid--medien) .cta-card--photo .cta-card__title,
.cta-grid:not(.cta-grid--liste):not(.cta-grid--medien) .cta-card--photo .cta-card__text {
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}

/* ============================================================
   FOTO-GALERIE 2025
   ============================================================ */

.gallery-section {
    background: var(--surface-sunken);
    padding-block: var(--section-gap);
}

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
}

@media (max-width: 767px) {
    .gallery-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .gallery-grid {
        grid-template-columns: 1fr;
    }
}

.gallery-item {
    position: relative;
    overflow: hidden;
    display: block;
    aspect-ratio: 3 / 2;
    border-radius: var(--radius-md);
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
}

.gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.5s ease;
}

.gallery-item:hover img {
    transform: scale(1.06);
}

.gallery-item__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        135deg,
        rgba(var(--color-primary-rgb), 0.00) 0%,
        rgba(var(--color-dark-rgb), 0.00) 100%
    );
    transition: background 0.35s ease;
}

.gallery-item:hover .gallery-item__overlay {
    background: linear-gradient(
        135deg,
        rgba(var(--color-primary-rgb), 0.30) 0%,
        rgba(var(--color-dark-rgb), 0.45) 100%
    );
}

/* ============================================================
   FOTO-BAND (Panorama-Banner vor Sponsoren)
   ============================================================ */

.photo-band {
    position: relative;
    min-height: 480px;
    display: flex;
    align-items: center;
    overflow: hidden;
    background-image: var(--band-photo);
    background-size: cover;
    background-position: center 40%;
    background-attachment: fixed;
}

@media (max-width: 767px) {
    .photo-band {
        background-attachment: scroll;
        min-height: 400px;
    }
}

/* ⚠️ Die einstellbare Abdunklung (`text_schleier`) liegt FLÄCHIG hier, nicht hinter dem Text.
   Sie kommt VOR den Marken-Verlauf, liegt also darüber, und wirkt auf dem ganzen Foto gleich.
   Ohne gesetzten Wert ist sie vollständig durchsichtig: für die Sites ohne `text_schleier`
   ändert sich kein Pixel. */
.photo-band__overlay {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(rgba(0, 0, 0, var(--text-schleier, 0)),
                        rgba(0, 0, 0, var(--text-schleier, 0))),
        var(--overlay-band);
}

/* 🔴 KEINE ELLIPSE HINTER DEM TEXT MEHR (03.09.2026).
 *
 * Der Weg dahin in drei Schritten, jeder von Dennis zurückgewiesen: erst ein deckender Kasten
 * („viel zu großer Kasten um Typo und Button"), dann ein weicher Verlauf, der als Rechteck
 * sichtbar blieb, zuletzt eine saubere Ellipse. Auch die war ein Element, das man sieht:
 * „Kreis hinter Typo sieht nicht aus, dann lieber Overlay über Background so anheben, dass
 * dadurch genug Kontrast."
 *
 * Die Abdunklung liegt deshalb jetzt FLÄCHIG im Overlay des Fotos (weiter unten bei
 * `.photo-band__overlay` und `.hero__overlay`). Vorbild ist der Mülheimer Firmenlauf: ein
 * gleichmäßiger Marken-Schleier über dem ganzen Bild, auf dem der Text einfach steht.
 *
 * Hier bleibt nur der Innenabstand: Er hält den Text von der Kante des Blocks weg. */
.hero__inner,
.photo-band__content {
    background: none;
}
/* ⚠️ Der Verlauf allein trägt die ZEILENENDEN nicht: Prüfung 30 misst den schwierigsten
   Bildpunkt im Zeilenkasten, und der liegt am Rand einer langen Zeile, wo der Verlauf schon
   abfällt. Gemessen auf rcr nach dem Umbau: Titel 2,51:1 (nötig 3,0), Text 3,40:1 (nötig 4,5).
   Die weiche Kante um die Buchstaben schließt genau diese Lücke, und zwar dort, wo Schrift
   steht, statt eine größere Fläche abzudunkeln.
   ⚠️ Kein Schalter nötig: Ohne gesetzten Schleier ist der Schatten vollständig durchsichtig,
   für die vier Sites ohne `text_schleier` ändert sich also nichts. */
/* 🔴 NUR wo die Schrift wirklich auf dem Foto steht.
 *
 * Bei der Hero-Anlage `platte` (rcr) liegt der Inhalt auf einer eigenen weissen Flaeche, das
 * Foto ist ein Band darueber. Eine weiche Kante ist dort nicht nur unnoetig, sie sieht falsch
 * aus: Gemeldet von Dennis am 03.09.2026, wenige Minuten nachdem die Regel ausgerollt war.
 * Dieselbe Ueberlegung wie beim Schleier selbst, den `be-hero-platte` ebenfalls ueberschreibt. */
body:not(.be-hero-platte) .hero__inner .hero__title,
body:not(.be-hero-platte) .hero__inner .hero__subtitle,
body:not(.be-hero-platte) .hero__inner .hero__meta,
.photo-band__content .photo-band__title,
.photo-band__content .photo-band__text,
.photo-band__content .photo-band__kicker {
    text-shadow: 0 1px 3px rgba(0, 0, 0, calc(var(--text-schleier, 0) * 1.4)),
                 0 2px 16px rgba(0, 0, 0, calc(var(--text-schleier, 0) * 1.25));
}
/* ⚠️ Hier stand ein Innenabstand, der an `--text-schleier-an` hing. Er hielt den Text von der
   Kante des KASTENS weg; ohne Kasten verschiebt er ihn nur. Mit der Ellipse ist er entfallen. */

.photo-band__content {
    position: relative;
    z-index: 1;
    padding-block: var(--space-20);
    max-width: 720px;
}

.photo-band__kicker {
    display: block;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-widest);
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.70) !important;
    margin-bottom: var(--space-3);
}

.photo-band__title {
    font-family: var(--font-heading);
    font-size: var(--section-h2-xl);
    font-weight: 900;
    line-height: var(--leading-tight);
    color: var(--color-white) !important;
    margin-bottom: var(--space-6);
}

.photo-band__text {
    font-size: var(--text-lg);
    line-height: 1.65;
    color: rgba(255, 255, 255, 0.82) !important;
    margin-bottom: var(--space-8);
    max-width: 560px;
}


/* Startpaket mit Foto statt Leucht-Grafik: das Bild bekommt eine helle Fläche, weil solche
   Produktfotos meist auf Weiß freigestellt sind und auf dunklem Grund sonst als heller Klotz
   ohne Kante stehen. */
.startpaket__art--foto {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #FFFFFF;
    border-radius: var(--radius-2xl);
    padding: clamp(.75rem, 2vw, 1.5rem);
}
.startpaket__art--foto img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-md);
}

/* Freigestellte Grafik: keine weiße Karte. Der weiße Untergrund oben ist für echte
   Produktfotos gedacht, die auf Weiß freigestellt AUSGELIEFERT werden. Eine Grafik mit
   durchsichtigem Hintergrund braucht ihn nicht — auf einer dunklen Seite steht sie darin
   wie ein Fremdkörper (gemeldet 18.08.2026 für park und runs). */
.startpaket__art--frei {
    background: none;
    padding: 0;
    border-radius: 0;
}

/* Fließtext mit mehreren Absätzen (siehe be_fliesstext_html).
   Ein einzelner Absatz bleibt ein <p> und braucht hier nichts; erst bei mehreren steht ein
   <div> mit echten <p> darin. Der Abstand ist bewusst KLEINER als der Abstand zum nächsten
   Block (--space-6): innerhalb eines Textes gehört weniger Luft als zwischen zwei Blöcken.
   Vorher entstand er aus einem doppelten Zeilenumbruch und war mit einer vollen Leerzeile
   (34 px bei 20 px Schrift) größer als der Blockabstand. */
.intro-section__body > p,
.photo-band__text > p,
.intro-section__claim > p {
    margin: 0 0 var(--space-4);
}

.intro-section__body > p:last-child,
.photo-band__text > p:last-child,
.intro-section__claim > p:last-child {
    margin-bottom: 0;
}

/* 🔴 EIN VERWEIS AUF DEM FOTO NIMMT DIE FARBE DES FOTOS AN, NICHT DIE DER SEITE
   Das Aufruf-Band traegt weisse Schrift auf einem abgedunkelten Foto. Ein Verweis darin
   holte sich seine Farbe aus der allgemeinen `a`-Regel, und die ist die Primaerfarbe —
   auf Team Walk ein dunkles Gruen. Gemessen am 31.08.2026 auf „Partner werden": 1,05:1
   und 1,22:1. Die Kontaktadresse und die Rufnummer waren praktisch unsichtbar, und zwar
   genau in dem Abschnitt, der zur Kontaktaufnahme auffordert.

   Dieselbe Fehlerklasse wie bei der Vorzeile des Seitenbanners und bei der Menuefarbe
   der Kopfflaeche: eine Farbe, die fuer PAPIER gewaehlt wurde, landet auf einem Foto.

   Deshalb: Der Verweis erbt die Schriftfarbe seines Umfelds (im Band ist das Weiss) und
   traegt eine Unterstreichung — auf einem Foto ist die Farbe allein ohnehin kein
   verlaessliches Erkennungsmerkmal fuer einen Verweis.

   ⚠️ Am 31.08.2026 ueber alle sechs Websites gemessen: Kein Aufruf-Band enthielt bis
   dahin einen Verweis. Fuer den Bestand aendert sich also nichts. */
.photo-band__text a,
.photo-band__content a:not(.btn) {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: .18em;
    text-decoration-thickness: from-font;
}
.photo-band__text a:hover,
.photo-band__content a:not(.btn):hover {
    color: inherit;
    text-decoration-thickness: 2px;
}

/* Brotkrume IM Kopfbereich (Startseite eines Stopps, seit 31.08.2026)
   ------------------------------------------------------------------
   Sie stammt aus dem schmalen Seiten-Banner, wo sie auf einer abgedunkelten
   Flaeche steht. Im Kopfbereich liegt sie auf einem unbearbeiteten Foto —
   gemessen: `rgba(255,255,255,.6)` OHNE Schatten, ueber einer hellen Stelle
   praktisch unsichtbar.

   Sie bekommt hier denselben Schatten wie die uebrigen Kopfzeilen, wird
   mittig gesetzt (die Liste ist eine Flexbox und richtet sich nicht nach
   `text-align` des Elternteils) und tritt eine Stufe zurueck: Sie ist
   Orientierung, nicht Aussage. */
.hero .breadcrumb {
    margin-bottom: var(--space-3);
}
.hero .breadcrumb__list {
    justify-content: center;
    font-size: var(--text-sm);
}
.hero .breadcrumb__item,
.hero .breadcrumb__item a,
.hero .breadcrumb__item.is-current {
    color: rgba(255, 255, 255, 0.88);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.hero .breadcrumb__item a:hover {
    color: #fff;
    text-decoration: underline;
}

/* Der abgeblendete Knopf im Kopfbereich (gemessen 31.08.2026)
   ----------------------------------------------------------
   `.btn--disabled` setzt `opacity: .45`. Auf einer Flaeche ist das eine
   verstaendliche Abstufung; ueber einem FOTO ist es eine Mischung mit dem
   Bild. Gemessen an der hellsten Stelle des Grundes: 2,37:1 auf tt und
   2,84:1 auf rcr, noetig sind 3,0 fuer grosse Schrift. Der Satz
   „Anmeldung oeffnet bald" war damit genau dort schlecht lesbar, wo er
   die einzige Auskunft ueber den Anmeldezustand ist.

   Der Knopf bleibt sichtbar inaktiv, aber ueber die FARBE statt ueber die
   Durchsichtigkeit: neutrale dunkle Flaeche, heller Rand, keine
   Markenfarbe, kein Zeigerwechsel. Das liest sich ohne Erklaerung als
   „geht gerade nicht" und bleibt auf jedem Foto lesbar. */
.hero .btn--disabled {
    opacity: 1;
    background: rgba(18, 13, 9, 0.62);
    background-image: none;
    /* Deutlich schwaecher als der Geisterknopf daneben. Mit gleich hellem Rand sahen beide
       gleich wichtig aus, und auf einer Seite mit vergangenem Termin ist „Alle Informationen"
       die Handlung, nicht der abgeblendete Knopf. */
    border: 1px solid rgba(255, 255, 255, 0.22);
    color: rgba(255, 255, 255, 0.86);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

/* Die Brotkrume braucht einen eigenen Grund, keinen Schatten.
   ----------------------------------------------------------
   Ein Textschatten hilft dem Auge, aendert am Kontrastverhaeltnis aber
   nichts — und gemessen wird das Verhaeltnis. Ueber einer sonnigen Stelle
   des Fotos stand sie bei 2,26:1. Sie bekommt deshalb dieselbe Loesung wie
   die Vorzeile daneben: eine eigene kleine Flaeche. */
.hero .breadcrumb__list {
    display: inline-flex;
    /* Kleiner und leiser als die Vorzeile darunter: zwei gleich grosse Pillen uebereinander
       lesen sich als zwei Aussagen, und die Brotkrume ist keine. */
    background: rgba(18, 13, 9, 0.58);
    padding: 0.22rem 0.7rem;
    border-radius: 999px;
    font-size: var(--text-xs);
}

/* Der eigene Text eines Stopps
   ---------------------------
   Er kommt aus `page.php`-Erbe und stand deshalb linksbuendig am Rand des
   Rasters, waehrend jeder Abschnitt darueber und darunter mittig steht.
   Gemessen: Spalte 741 px breit, linke Kante bei 48 px in einem 1440er
   Fenster. Er las sich wie ein vergessener Absatz.

   Die Spalte wird mittig gesetzt, der Text bleibt linksbuendig — eine
   zentrierte Fliesstextspalte ist schwerer zu lesen, weil jede Zeile an
   einer anderen Stelle beginnt. */
.be-stopp__text .page-prose {
    margin-inline: auto;
}
/* ⚠️ Hier stand eine groessere Schrift fuer den ERSTEN Absatz. Das war richtig, solange er
   die Einleitung war; seit dem 03.09.2026 sind es zwei gleichwertige Absaetze (Strecke, dann
   Aufruf), und der Sprung las sich als Fehler (gemeldet von Dennis am 04.09.2026). Ein
   Lead-Absatz muss inhaltlich einer sein, sonst ist er nur eine andere Groesse. */
.be-stopp__text .page-prose > p {
    line-height: var(--leading-loose, 1.7);
}

/* Die Karte um den Text (03.09.2026)
   ---------------------------------
   Gemeldet von Dennis: „sieht noch bisschen verloren aus". Der Abschnitt begann
   ohne Ankuendigung mit einem Absatz auf einer leeren Flaeche, waehrend jeder
   Abschnitt darueber und darunter eine Vorzeile und eine Ueberschrift hat.

   ⚠️ Die Karte traegt `--surface-page`, NICHT `--surface-raised`. Beide Werte
   kommen aus dem Branding, aber reines Weiss auf dem abgesenkten Abschnitt war
   ein Sprung von 1,244:1 und sprang als Fremdkoerper ins Auge (gemeldet von
   Dennis am 03.09.2026). Gegen den abgesenkten Grund sind es jetzt 1,112:1,
   also knapp ueber der Schwelle, ab der eine Flaeche ueberhaupt als eigene
   wahrgenommen wird. Der Text steht bei 11,30:1 und verliert dabei nichts.

   Die Karte lebt seitdem von ihrer Kante und dem Schatten, nicht von ihrer
   Helligkeit. Deshalb ist der Rand eine Spur deutlicher als vorher. */
.be-stopp__karte {
    max-width: 58rem;
    margin-inline: auto;
    background: var(--surface-page);
    border: 1px solid rgba(var(--color-primary-rgb), 0.16);
    border-radius: var(--radius-lg, 14px);
    padding: clamp(1.75rem, 4vw, 3rem);
    box-shadow: var(--shadow-md);
}
/* Kopf mittig, Fliesstext linksbuendig: dieselbe Aufteilung wie in den Eckdaten
   darueber. Eine zentrierte Fliesstextspalte ist schwerer zu lesen, weil jede
   Zeile an einer anderen Stelle beginnt. */
.be-stopp__kopf {
    text-align: center;
    margin-bottom: clamp(1.25rem, 3vw, 1.75rem);
}
.be-stopp__kicker {
    display: block;
    font-size: var(--text-xs, .75rem);
    letter-spacing: var(--tracking-wider, .12em);
    text-transform: uppercase;
    color: var(--color-primary);
    margin-bottom: .5rem;
}
.be-stopp__heading {
    font-family: var(--font-heading);
    margin: 0;
}

/* Die weiterfuehrenden Wege
   ------------------------
   Sie ersetzen die getippte Aufzaehlung „Alles zu Team Walk <Stadt>", die das
   Untermenue eins zu eins nachbaute. Drei Ziele statt sieben, jedes mit Symbol.

   ⚠️ `auto-fit` und nicht `repeat(3, 1fr)`: Bei einem vergangenen Stopp ohne
   Fotoseite bleiben zwei Wege uebrig, und die sollen die Breite unter sich
   aufteilen statt eine leere dritte Spalte stehen zu lassen. Dieselbe Falle wie
   seinerzeit bei der Sponsorenwand. */
.be-stopp__wege {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: var(--space-3);
    margin-top: clamp(1.75rem, 4vw, 2.5rem);
}
.be-stopp__weg {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid rgba(var(--color-primary-rgb), 0.18);
    border-radius: var(--radius-md);
    /* ⚠️ Die Wege stehen auf `--surface-raised`, die Karte auf `--surface-page`. Genau
       andersherum als zuerst gebaut: Eine grosse weisse Flaeche springt ins Auge, drei
       kleine Felder darin ordnen die Seite. Die Helligkeit gehoert dorthin, wo etwas
       angeklickt wird. */
    background: var(--surface-raised);
    color: inherit;
    text-decoration: none;
    font-weight: 700;
    line-height: var(--leading-tight, 1.2);
    transition: background var(--transition-fast), border-color var(--transition-fast),
                transform var(--transition-fast);
}
/* ⚠️ Die Schriftfarbe wird im Hover ausdruecklich gesetzt. `main.css` hat
   `a:hover { color: var(--color-primary-dark) }` mit Spezifitaet 0,1,1 und
   schlaegt damit jede Klassenregel, die sie weglaesst. Auf der gefuellten
   Flaeche waere die Beschriftung sonst kaum noch zu lesen. */
.be-stopp__weg:hover,
.be-stopp__weg:focus-visible {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-text-on-primary);
    transform: translateY(-2px);
}
.be-stopp__weg-icon {
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
    color: var(--color-primary);
}
.be-stopp__weg:hover .be-stopp__weg-icon,
.be-stopp__weg:focus-visible .be-stopp__weg-icon {
    color: var(--color-text-on-primary);
}
@media (prefers-reduced-motion: reduce) {
    .be-stopp__weg { transition: none; }
    .be-stopp__weg:hover,
    .be-stopp__weg:focus-visible { transform: none; }
}
