Banner-Slider: einspaltiges Layout, Logo oben links, Foto frei

Logo führt die Slide oben links an (statt großer Logo-Platte rechts); Inhalt
einspaltig, „Anzeige"/Status-Label als Pille unten rechts in der Fußzeile.
Damit gibt die rechte Hälfte das Hintergrundfoto frei — Motivwahl wird viel
einfacher. Logo nur rendern, wenn vorhanden; Wappen (Eigenwerbung) etwas größer.

Breadcrumb-Slide auf einen CTA reduziert: „Neue Website entdecken" → Startseite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
This commit is contained in:
2026-06-19 08:52:21 +02:00
parent d0d78d7a5c
commit d82acc7f9c
3 changed files with 86 additions and 53 deletions

View File

@@ -61,11 +61,6 @@ $total = count($banners);
} }
$style = $styleParts !== [] ? ' style="' . e(implode('; ', $styleParts)) . '"' : ''; $style = $styleParts !== [] ? ' style="' . e(implode('; ', $styleParts)) . '"' : '';
?> ?>
<li class="<?= e($classes) ?>"<?= $style ?> data-banner-slide role="group" aria-roledescription="Folie" aria-label="<?= ($i + 1) ?> von <?= $total ?>"<?= $i === 0 ? '' : ' hidden' ?>>
<div class="ad-banner__content">
<span class="ad-banner__tag"><?= e($banner['tag'] ?? 'Anzeige') ?></span>
<p class="ad-banner__title"><?= e($banner['title']) ?></p>
<p class="ad-banner__text"><?= e($banner['text']) ?></p>
<?php <?php
// Rendert einen CTA-Link; externe Links öffnen im neuen Tab (rel=sponsored), // Rendert einen CTA-Link; externe Links öffnen im neuen Tab (rel=sponsored),
// interne (cta.internal) bleiben normale Links. $btnClass für Primär/Sekundär. // interne (cta.internal) bleiben normale Links. $btnClass für Primär/Sekundär.
@@ -81,15 +76,24 @@ $total = count($banners);
. '</a>'; . '</a>';
}; };
?> ?>
<li class="<?= e($classes) ?>"<?= $style ?> data-banner-slide role="group" aria-roledescription="Folie" aria-label="<?= ($i + 1) ?> von <?= $total ?>"<?= $i === 0 ? '' : ' hidden' ?>>
<?php if (!empty($banner['logo'])): ?>
<div class="ad-banner__logo<?= !empty($banner['logo_light']) ? ' ad-banner__logo--light' : '' ?>">
<img src="<?= e(asset($banner['logo'])) ?>" alt="<?= e($banner['company'] ?? $banner['title']) ?>" loading="lazy" decoding="async">
</div>
<?php endif; ?>
<div class="ad-banner__content">
<p class="ad-banner__title"><?= e($banner['title']) ?></p>
<p class="ad-banner__text"><?= e($banner['text']) ?></p>
</div>
<div class="ad-banner__footer">
<?php if (!empty($banner['cta']) || !empty($banner['cta_secondary'])): ?> <?php if (!empty($banner['cta']) || !empty($banner['cta_secondary'])): ?>
<div class="ad-banner__actions"> <div class="ad-banner__actions">
<?php $renderCta($banner['cta'] ?? null, 'btn'); ?> <?php $renderCta($banner['cta'] ?? null, 'btn'); ?>
<?php $renderCta($banner['cta_secondary'] ?? null, 'btn btn--outline'); ?> <?php $renderCta($banner['cta_secondary'] ?? null, 'btn btn--outline'); ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> <span class="ad-banner__tag"><?= e($banner['tag'] ?? 'Anzeige') ?></span>
<div class="ad-banner__logo<?= !empty($banner['logo_light']) ? ' ad-banner__logo--light' : '' ?>">
<img src="<?= e(asset($banner['logo'])) ?>" alt="<?= e($banner['company'] ?? $banner['title']) ?>" loading="lazy" decoding="async">
</div> </div>
</li> </li>
<?php endforeach; ?> <?php endforeach; ?>

View File

@@ -20,8 +20,7 @@
"logo_light": true, "logo_light": true,
"accent": "#6cbbbc", "accent": "#6cbbbc",
"background": "img/banners/breadcrumb-hero-1600.jpg", "background": "img/banners/breadcrumb-hero-1600.jpg",
"cta": { "label": "Lösungen entdecken", "url": "https://www.breadcrumb-solutions.de/bc/de/loesungen/" }, "cta": { "label": "Neue Website entdecken", "url": "https://www.breadcrumb-solutions.de/" }
"cta_secondary": { "label": "Über uns", "url": "https://www.breadcrumb-solutions.de/bc/de/unternehmen/ueber-uns/" }
} }
] ]
} }

View File

@@ -867,6 +867,35 @@
margin: 0; margin: 0;
} }
/* Gruppierte Abschnitte (fieldset/legend) — gliedert lange Formulare in ruhige
Blöcke, getrennt durch eine dezente Hairline. Reduziert die optische Last. */
.form__group {
margin: 0;
padding: 0;
border: 0;
min-inline-size: 0;
}
.form__group + .form__group {
padding-top: 1.75rem;
border-top: 1px solid var(--clr-glass-border);
}
.form__legend {
width: 100%;
padding: 0;
margin-bottom: 1rem;
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--clr-accent);
}
.form__group-body {
display: grid;
gap: 1.25rem;
}
/* === Werbe-/Sponsoren-Banner (Slider) === */ /* === Werbe-/Sponsoren-Banner (Slider) === */
.ad-banner { .ad-banner {
--banner-interval: 6s; --banner-interval: 6s;
@@ -896,10 +925,10 @@
} }
.ad-banner__slide { .ad-banner__slide {
display: grid; display: flex;
grid-template-columns: 2fr 1fr; flex-direction: column;
gap: 2.5rem; align-items: flex-start;
align-items: center; min-height: 320px;
padding: clamp(1.75rem, 1rem + 2vw, 3rem); padding: clamp(1.75rem, 1rem + 2vw, 3rem);
background: var(--clr-glass-bg); background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border); border: 1px solid var(--clr-glass-border);
@@ -907,6 +936,23 @@
box-shadow: var(--shadow-card); box-shadow: var(--shadow-card);
} }
/* Inhaltsbreite begrenzen, damit Titel/Text die linke Hälfte belegen und das
Foto rechts frei bleibt. */
.ad-banner__content {
max-width: 60ch;
}
/* Fußzeile: CTAs links, Anzeige-/Status-Label rechts — an den unteren Rand. */
.ad-banner__footer {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem 1rem;
width: 100%;
margin-top: auto;
padding-top: 1.5rem;
}
/* Crossfade-Übergang (nur mit JS): Slides im selben Grid-Feld stapeln, sodass /* Crossfade-Übergang (nur mit JS): Slides im selben Grid-Feld stapeln, sodass
die Höhe konstant bleibt (kein Sprung) und ein- wie ausgehende Folie sauber die Höhe konstant bleibt (kein Sprung) und ein- wie ausgehende Folie sauber
überblenden. Die ausgehende driftet leicht nach unten, die eingehende steigt überblenden. Die ausgehende driftet leicht nach unten, die eingehende steigt
@@ -975,12 +1021,6 @@
color: var(--clr-text); color: var(--clr-text);
} }
.ad-banner__slide--bg .ad-banner__logo {
background: rgb(0 0 0 / 0.4);
border-color: rgb(255 255 255 / 0.3);
backdrop-filter: blur(2px);
}
@media (max-width: 768px) { @media (max-width: 768px) {
/* Auf Mobil läuft der Verlauf nach unten, damit der gestapelte Text lesbar bleibt. */ /* Auf Mobil läuft der Verlauf nach unten, damit der gestapelte Text lesbar bleibt. */
.ad-banner__slide--bg { .ad-banner__slide--bg {
@@ -1017,11 +1057,6 @@
color: var(--clr-text); color: var(--clr-text);
} }
.ad-banner__slide--house .ad-banner__logo {
background: rgb(0 0 0 / 0.25);
border-color: rgb(var(--clr-accent-rgb) / 0.45);
}
/* Eigenwerbung MIT Foto-Hintergrund: rot-dunkler Verlauf von links hält den /* Eigenwerbung MIT Foto-Hintergrund: rot-dunkler Verlauf von links hält den
Text lesbar, das Foto bleibt rechts sichtbar. */ Text lesbar, das Foto bleibt rechts sichtbar. */
.ad-banner__slide--house.ad-banner__slide--bg { .ad-banner__slide--house.ad-banner__slide--bg {
@@ -1035,12 +1070,6 @@
border-color: transparent; border-color: transparent;
} }
.ad-banner__slide--house.ad-banner__slide--bg .ad-banner__logo {
background: rgb(0 0 0 / 0.45);
border-color: rgb(255 255 255 / 0.18);
backdrop-filter: blur(2px);
}
@media (max-width: 768px) { @media (max-width: 768px) {
/* Auf Mobil läuft der Verlauf nach unten (Text steht gestapelt darüber). */ /* Auf Mobil läuft der Verlauf nach unten (Text steht gestapelt darüber). */
.ad-banner__slide--house.ad-banner__slide--bg { .ad-banner__slide--house.ad-banner__slide--bg {
@@ -1050,16 +1079,18 @@
} }
} }
/* Anzeige-/Status-Label: sitzt rechts in der Fußzeile (margin-left:auto).
Dunkle Pille, damit es auch über dem Foto lesbar bleibt. */
.ad-banner__tag { .ad-banner__tag {
display: inline-block; margin-left: auto;
margin-bottom: 0.85rem; align-self: center;
padding: 0.2em 0.7em; padding: 0.2em 0.7em;
font-size: var(--fs-300); font-size: var(--fs-300);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em; letter-spacing: 0.08em;
color: var(--clr-text-muted); color: var(--clr-text-muted);
background: rgb(255 255 255 / 0.08); background: rgb(0 0 0 / 0.45);
border: 1px solid var(--clr-glass-border); border: 1px solid rgb(255 255 255 / 0.18);
border-radius: 999px; border-radius: 999px;
} }
@@ -1072,7 +1103,6 @@
.ad-banner__text { .ad-banner__text {
max-width: 52ch; max-width: 52ch;
margin-bottom: 1.5rem;
color: var(--clr-text-muted); color: var(--clr-text-muted);
} }
@@ -1083,35 +1113,35 @@
gap: 0.75rem; gap: 0.75rem;
} }
/* Logo führt die Slide an: kompaktes Badge oben links. */
.ad-banner__logo { .ad-banner__logo {
display: grid; margin-bottom: 1.5rem;
place-items: center;
min-height: 130px;
padding: 1.5rem;
background: rgb(0 0 0 / 0.18);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
} }
/* Helle Platte für dunkle Firmenlogos (Wortmarken). Überschreibt auch die /* Helle Platte für dunkle Firmenlogos (Wortmarken). */
dunkle Logo-Box der Foto-Variante (gleiche Spezifität, später im File). */ .ad-banner__logo--light {
.ad-banner__logo.ad-banner__logo--light { padding: 0.55rem 0.85rem;
background: #fff; background: #fff;
border-color: rgb(255 255 255 / 0.55); border-radius: var(--radius-btn);
backdrop-filter: none;
} }
.ad-banner__logo img { .ad-banner__logo img {
display: block;
width: auto; width: auto;
max-width: 100%; height: auto;
max-height: 96px; max-width: 230px;
max-height: 56px;
object-fit: contain; object-fit: contain;
} }
/* Vereinswappen (Eigenwerbung) darf etwas größer stehen. */
.ad-banner__slide--house .ad-banner__logo img {
max-height: 76px;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.ad-banner__slide { .ad-banner__content {
grid-template-columns: 1fr; max-width: 100%;
gap: 1.75rem;
} }
} }