Files
tsv08kulmbach-website/public/assets/css/components.css
fs 3fa521eaf1 Design-System: Typo-Skala schließen, h4–h6 auf Abel, Icon-Größen tokenisieren
Zweiter Teil der Konsolidierung. Vorher standen 31 font-size-Werte außerhalb
der Skala — beim Durchgehen stellte sich heraus, dass 20 davon gar keine
Textgrößen sind: der icon()-Helper rendert 1em, also steuerte font-size dort
die Icon-Größe. Dafür gibt es jetzt eine eigene, kleine Skala (--icon-s/m/l/xl
in rem, --icon-inline-sm/--icon-inline/--icon-inline-lg in em für Icons, die im
Textfluss mitwachsen sollen). Elf Ad-hoc-Werte fallen damit auf sieben Stufen.

h4–h6 laufen nicht mehr über Coolvetica. Sie lagen mit 26px und 21px unter der
--fs-650-Grenze aus CLAUDE.md, ab der der Condensed-Schnitt in Uppercase
unleserlich wird — die Regel war also nur dokumentiert, nicht durchsetzbar.
Jetzt tragen h1–h3 Coolvetica (alle über der Grenze) und h4–h6 Abel mit
Sperrung. Bezeichnend: das einzige <h4> im Markup hatte sich genau dieses
Muster bereits von Hand gebaut. Die Basisregel liefert es jetzt, die Komponente
gibt ihre drei Duplikat-Deklarationen ab — sichtbar ändert sich dadurch nichts.

Neue Stufen schließen die Lücken: --fs-550 (fluider Lead), --fs-690 (Karten-
Überschrift) und --fs-1000 (Display-Hero). Vier fast deckungsgleiche clamp()-
Rampen für Karten-Überschriften (bento__heading, bento__stat-value,
group-card__name, team-card__name) laufen jetzt über --fs-690; team-card__name
wächst dabei am Desktop um ~5px, die anderen drei bleiben im 1px-Bereich.

Die Wappen-Initialen im Matchcenter hingen an zwei Mini-Schriftgrößen (10,4 und
11,2px) unterhalb der Skala. Sie sind in Wahrheit ~0,4 × Kreisdurchmesser,
folgen jetzt also --crest-size statt einer eigenen font-size. Nebenbei fallen
drei redundante Doppel-Selektoren weg: .crest--initials trägt immer auch .crest.

Ebenfalls tokenisiert: 27 letter-spacing-Werte mit elf verschiedenen Zahlen auf
vier Stufen (--ls-tight/caps/wide/wider), maximale Abweichung 0,02em.

Danach steht kein font-size- und kein letter-spacing-Wert mehr außerhalb von
tokens.css.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MSsVdooFLgPA8gPFp7HwZU
2026-07-27 10:17:13 +02:00

4360 lines
102 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================
COMPONENTS — eine Sektion pro Komponente, Banner-Kommentare
============================================================ */
/* === hero === */
.hero {
position: relative;
display: grid;
align-items: end;
/* svh statt vh: stabil gegenüber ein-/ausfahrender Browser-UI auf Phones. */
min-height: min(92vh, 900px);
min-height: min(92svh, 900px);
padding-block: calc(var(--header-h) + 80px) var(--space-section);
overflow: hidden;
}
/* Kompakte Variante: schlanker Unterseiten-Header statt vollflächig. */
.hero--compact {
min-height: min(60vh, 560px);
min-height: min(60svh, 560px);
padding-block: calc(var(--header-h) + 64px) var(--space-5xl);
}
/* Mobile: Höhe am Inhalt statt am Viewport orientieren — weniger Leer-Scroll.
Startseiten-Hero lässt bewusst einen Streifen Folge-Inhalt anblitzen (Scroll-Affordance),
Unterseiten-Heros kollabieren auf Überschrift + Teaser. */
@media (max-width: 768px) {
.hero {
min-height: min(82vh, 700px);
min-height: min(82svh, 700px);
padding-block: calc(var(--header-h) + 48px) var(--space-4xl);
}
.hero--compact {
min-height: 0;
padding-block: calc(var(--header-h) + 44px) var(--space-3xl);
}
}
.hero__media {
position: absolute;
inset: 0;
z-index: -1;
/* Unten ausblenden statt mit grauem BG zudecken: der echte, dunkle
texturierte Seiten-Hintergrund scheint durch → transparent & matcht
den Grund exakt (kein graues, opakes Band mehr). */
-webkit-mask-image: linear-gradient(180deg, #000 0%, #000 58%, transparent 92%);
mask-image: linear-gradient(180deg, #000 0%, #000 58%, transparent 92%);
}
.hero__img {
width: 100%;
height: 100%;
object-fit: cover;
}
.hero__video {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
@media (prefers-reduced-motion: reduce) {
.hero__video {
display: none;
}
}
/* Reine Schwarz-Abdunklung (kein grauer Fill) — der Auslauf zum Grund kommt
aus der Mask auf .hero__media, hier wird nur schwärzer getönt. */
.hero__media::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgb(0 0 0 / 0.45) 0%, rgb(0 0 0 / 0.15) 45%, rgb(0 0 0 / 0.5) 100%);
}
.hero__content {
width: 100%;
}
.hero__title {
text-shadow: 0 2px 24px rgb(0 0 0 / 0.5);
}
/* Keyword-Subline innerhalb der h1 (SEO) — visuell kleinere zweite Zeile */
.hero__tagline {
display: block;
margin-top: var(--space-xs);
font-size: var(--fs-600);
letter-spacing: var(--ls-wide);
}
.hero__text {
margin-top: var(--space-s);
max-width: 60ch;
text-shadow: 0 1px 12px rgb(0 0 0 / 0.6);
text-wrap: pretty;
}
/* Display-Hero: schmaleres Maß fürs Zentrieren — ausgewogene Zeilen statt
vier Zeilen mit unruhigem Flatterrand. */
.hero--display .hero__text {
max-width: 52ch;
}
.hero__actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-xs);
margin-top: var(--space-xl);
}
/* Variante: Text mittig zentriert (z. B. Startseite) */
.hero--center {
align-items: center;
text-align: center;
}
.hero--center .hero__text {
margin-inline: auto;
}
/* letter-spacing schiebt zentrierten Text optisch nach rechts (Spacing nach letztem Char).
text-indent gleich dem letter-spacing-Wert kompensiert das. */
.hero--center .hero__tagline {
text-indent: 0.14em;
}
.hero--center .hero__actions {
justify-content: center;
}
/* Variante: Editorial-Display (Startseite) — linksbündig unten, große Typo */
.hero--display .hero__media::after {
/* zusätzlicher Verlauf von links für Textlesbarkeit über dem Video */
background:
linear-gradient(90deg, rgb(10 10 10 / 0.62) 0%, rgb(10 10 10 / 0.25) 45%, transparent 70%),
linear-gradient(180deg, rgb(0 0 0 / 0.42) 0%, rgb(0 0 0 / 0.15) 45%, rgb(0 0 0 / 0.5) 100%);
}
/* Center+Display: kein Seitenverlauf, nur zentrales Abdunkeln für Lesbarkeit */
.hero--center.hero--display .hero__media::after {
background:
radial-gradient(ellipse 80% 60% at 50% 40%, rgb(10 10 10 / 0.5) 0%, transparent 100%),
linear-gradient(180deg, rgb(0 0 0 / 0.4) 0%, rgb(0 0 0 / 0.14) 45%, rgb(0 0 0 / 0.5) 100%);
}
/* Kicker: einziges gesperrtes Versalien-Element im Hero — bewusst ohne
Schmuck-Linien, damit die Typo-Hierarchie ruhig bleibt (Eyebrow → Titel →
Subline → Text). */
.hero__kicker {
margin-bottom: var(--space-m);
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-wider);
/* Sperrung optisch kompensieren (Spacing nach letztem Zeichen). */
text-indent: 0.18em;
color: rgb(255 255 255 / 0.85);
}
.hero--display .hero__title {
font-size: var(--fs-1000);
}
/* Subline ruhig in Abel, Groß-/Kleinschreibung — konkurriert nicht mehr mit
Kicker (gesperrte Versalien) und Coolvetica-Titel. */
.hero--display .hero__tagline {
margin-top: var(--space-xs);
font-family: var(--ff-body);
font-size: var(--fs-550);
font-weight: 400;
letter-spacing: 0;
text-indent: 0;
text-transform: none;
line-height: 1.35;
color: rgb(255 255 255 / 0.92);
}
.hero__scroll-cue {
position: absolute;
left: 50%;
bottom: 1.25rem;
translate: -50% 0;
display: grid;
place-items: center;
width: 44px;
height: 44px;
color: var(--clr-text-muted);
font-size: var(--icon-l);
transition: color var(--transition);
animation: scroll-cue-bounce 2.4s ease-in-out infinite;
}
.hero__scroll-cue:hover {
color: var(--clr-text);
}
@keyframes scroll-cue-bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(8px); }
}
/* === instagram === */
/* Sektions-Kopf zentriert (einheitlich mit partners/persons/…) */
.instagram > .container > h2,
.instagram > .container > .text-muted {
text-align: center;
}
.instagram > .container > .text-muted {
max-width: 60ch;
margin-inline: auto;
}
.instagram__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: var(--space-s);
margin-top: var(--space-2xl);
}
/* Mobil: Ein-Reihen-Swiper statt 2er-Grid — volle Bildgröße, natürliche
Instagram-Geste. Fluchtet mit dem Text-Container; die angeschnittene
Folgekarte ist die Wisch-Affordance, Scrollbar bleibt darum versteckt. */
@media (max-width: 600px) {
.instagram__grid {
grid-template-columns: none;
grid-auto-flow: column;
grid-auto-columns: min(72vw, 320px);
gap: var(--space-xs);
overflow-x: auto;
scroll-snap-type: x mandatory;
scrollbar-width: none;
}
.instagram__grid::-webkit-scrollbar {
display: none;
}
.instagram__link {
scroll-snap-align: start;
}
}
.instagram__link {
position: relative;
display: block;
border-radius: var(--radius-card);
overflow: hidden;
box-shadow: var(--shadow-card);
}
.instagram__link img {
width: 100%;
height: auto;
/* Instagram-Portrait 1080x1350 */
aspect-ratio: 4 / 5;
object-fit: cover;
transition: transform var(--transition);
}
.instagram__link:hover img,
.instagram__link:focus-visible img {
transform: scale(1.05);
}
.instagram__badge {
position: absolute;
top: 0.75rem;
right: 0.75rem;
display: grid;
place-items: center;
width: 2rem;
height: 2rem;
background: rgb(0 0 0 / 0.6);
border-radius: 50%;
font-size: var(--fs-300);
color: var(--clr-text);
}
.instagram__fallback {
margin-top: var(--space-l);
padding: var(--space-3xl);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
text-align: center;
}
.instagram__fallback p {
margin-inline: auto;
}
.instagram__fallback .btn {
margin-top: var(--space-s);
}
/* === split (Bild/Text-Sektion) === */
.split__inner {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
align-items: center;
gap: var(--space-4xl);
}
/* Sanft aufgehelltes, durchgehendes Band über die volle Breite — generisch für
jede Sektion (Split via tinted: true im JSON, person-grid u.a. per Klasse).
Direkt aufeinanderfolgende tinted-Sektionen verschmelzen nahtlos. */
.section--tinted {
background: linear-gradient(180deg, rgb(255 255 255 / 0.06), rgb(255 255 255 / 0.035));
border-block: 1px solid rgb(255 255 255 / 0.1);
}
/* Abgesetztes, dunkleres Band über die volle Breite — das Gegenstück zu
--tinted, wenn eine Sektion sich nach unten statt nach oben abheben soll. */
.section--sunken {
background: var(--clr-bg-deep);
border-block: 1px solid rgb(255 255 255 / 0.08);
}
.section--tinted + .section--tinted {
border-top: 0;
}
.section--tinted:has(+ .section--tinted) {
border-bottom: 0;
}
/* Bild/Text-Sektionen im Band: mehr Luft nach oben und unten */
.split.section--tinted {
padding-block: clamp(var(--space-6xl), var(--space-5xl) + 3vw, var(--space-7xl));
}
.split--flip .split__text {
order: 2;
}
.split--flip .split__media {
order: 1;
}
.split__text p {
margin-top: var(--space-s);
}
.split__cta {
margin-top: var(--space-l);
}
.split__img {
width: 100%;
border-radius: var(--radius-card);
box-shadow: var(--shadow-card);
}
@media (max-width: 992px) {
.split__inner {
grid-template-columns: 1fr;
gap: var(--space-2xl);
}
.split--flip .split__text {
order: 0;
}
.split--flip .split__media {
order: 0;
}
}
/* === stats === */
.stats {
position: relative;
padding-block: var(--space-7xl);
overflow: hidden;
}
.stats__media {
position: absolute;
inset: 0;
z-index: -1;
}
.stats__img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Abdunkeln + weiche Kanten: oben/unten Verlauf in den Seitenhintergrund,
damit kein harter "Streifen" entsteht */
.stats__media::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(180deg,
var(--clr-bg) 0%,
rgb(15 15 15 / 0.72) 28%,
rgb(15 15 15 / 0.72) 72%,
var(--clr-bg) 100%);
}
.stats__list {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: var(--space-2xl);
text-align: center;
}
@media (max-width: 600px) {
.stats__list {
grid-template-columns: 1fr;
}
}
.stats__item {
display: grid;
gap: var(--space-3xs);
}
.stats__value {
font-family: var(--ff-heading);
font-size: var(--fs-900);
line-height: var(--lh-heading);
color: var(--clr-accent);
text-shadow: 0 2px 18px rgb(0 0 0 / 0.55), 0 0 30px rgb(var(--clr-accent-rgb) / 0.35);
}
.stats__label {
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
}
/* === timeline (Vereinshistorie, Museums-Look) === */
.timeline-intro {
max-width: 60ch;
margin-inline: auto;
padding-block: var(--space-3xl) 0;
text-align: center;
color: var(--clr-text-muted);
}
/* Sprung-Navigation: Jahres-Pills, klebt beim Scrollen oben */
.timeline-nav {
position: sticky;
top: 1rem;
z-index: 5;
display: flex;
justify-content: center;
margin-bottom: var(--space-4xl);
}
.timeline-nav__list {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--space-2xs);
padding: var(--space-2xs);
background: rgb(10 10 10 / 0.82);
border: 1px solid var(--clr-glass-border);
border-radius: 999px;
backdrop-filter: blur(6px);
}
.timeline-nav a {
display: inline-block;
padding: 0.25em 0.85em;
font-family: var(--ff-heading);
/* Coolvetica unter ~28px wird unleserlich (Projekt-Faustregel) */
font-size: var(--fs-650);
letter-spacing: var(--ls-caps);
text-transform: uppercase;
text-decoration: none;
color: var(--clr-text-muted);
border-radius: 999px;
transition: color var(--transition), background var(--transition);
}
.timeline-nav a:hover {
color: var(--clr-text);
}
.timeline-nav a.is-active {
color: var(--clr-text);
background: var(--clr-accent);
}
/* Mittellinie + Stationen */
.timeline {
position: relative;
display: grid;
gap: var(--space-6xl);
padding-block: var(--space-s) var(--space-2xl);
}
.timeline::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 2px;
transform: translateX(-50%);
background: linear-gradient(180deg,
transparent,
rgb(var(--clr-accent-rgb) / 0.55) 6%,
rgb(var(--clr-accent-rgb) / 0.55) 94%,
transparent);
}
.timeline__event {
position: relative;
width: calc(50% - 3.5rem);
}
.timeline__event:nth-child(even) {
margin-left: auto;
}
.timeline__marker {
position: absolute;
top: 0.6rem;
left: calc(100% + 3.5rem);
width: 16px;
height: 16px;
transform: translateX(-50%);
background: var(--clr-accent);
border-radius: 50%;
box-shadow: 0 0 0 4px rgb(var(--clr-accent-rgb) / 0.25), 0 0 18px rgb(var(--clr-accent-rgb) / 0.5);
}
.timeline__event:nth-child(even) .timeline__marker {
left: -3.5rem;
}
.timeline__year {
font-size: var(--fs-900);
color: var(--clr-text);
text-shadow: 0 2px 18px rgb(0 0 0 / 0.5);
margin-bottom: var(--space-s);
}
.timeline__event:nth-child(odd) .timeline__year {
text-align: right;
}
/* Museums-Rahmen: Foto wie ein aufgezogener Print, leicht gedreht */
.timeline__figure {
margin: 0;
padding: var(--space-s) var(--space-s) var(--space-s);
background: var(--clr-sepia-bg);
border-radius: 3px;
box-shadow: 0 12px 35px rgb(0 0 0 / 0.5);
transform: rotate(-1.2deg);
transition: transform var(--transition);
}
.timeline__event:nth-child(even) .timeline__figure {
transform: rotate(1.2deg);
}
.timeline__event:hover .timeline__figure {
transform: rotate(0deg) scale(1.02);
}
.timeline__figure img {
width: 100%;
height: auto;
display: block;
}
.timeline__text {
padding-top: var(--space-s);
font-size: var(--fs-500);
line-height: 1.45;
color: var(--clr-sepia-text);
}
/* Scroll-Reveal nur mit JS (js-reveal), sonst alles sichtbar */
.js-reveal .timeline__event {
opacity: 0;
translate: 0 28px;
transition: opacity 600ms ease, translate 600ms ease;
}
.js-reveal .timeline__event.is-visible {
opacity: 1;
translate: 0 0;
}
@media (max-width: 768px) {
.timeline::before {
left: 8px;
}
.timeline__event,
.timeline__event:nth-child(even) {
width: auto;
margin-left: 0;
padding-left: var(--space-3xl);
}
.timeline__marker,
.timeline__event:nth-child(even) .timeline__marker {
left: 8px;
}
.timeline__event:nth-child(odd) .timeline__year {
text-align: left;
}
}
/* === partners === */
.partners > .container {
text-align: center;
}
.partners > .container > p {
max-width: 60ch;
margin-inline: auto;
}
/* Intro-Abstand zur Überschrift einheitlich mit den anderen Sektionen */
.partners__intro {
margin-top: var(--space-s);
}
.partners__grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 220px));
justify-content: center;
align-items: center;
gap: var(--space-2xl);
margin-block: var(--space-3xl);
}
.partners__item {
display: grid;
place-items: center;
padding: var(--space-l);
/* Dunkles Glas — die Partner-Logos sind weiße Varianten */
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
min-height: 120px;
}
.partners__item img {
max-height: 80px;
width: auto;
max-width: 100%;
object-fit: contain;
}
/* === sponsor-arguments === */
.sponsor-arguments__grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-3xl) var(--space-4xl);
list-style: none;
padding: 0;
}
.sponsor-arguments__item {
display: flex;
gap: var(--space-m);
align-items: flex-start;
}
.sponsor-arguments__icon {
flex-shrink: 0;
width: 2.5rem;
height: 2.5rem;
background: var(--clr-accent);
border-radius: 8px;
display: grid;
place-items: center;
font-size: var(--icon-s);
color: #fff;
margin-top: var(--space-3xs);
}
.sponsor-arguments__title {
font-family: var(--ff-heading);
font-size: var(--fs-675);
text-transform: uppercase;
line-height: var(--lh-heading);
margin: 0 0 var(--space-2xs);
}
.sponsor-arguments__text {
color: var(--clr-text-muted);
font-size: var(--fs-500);
line-height: var(--lh-body);
margin: 0;
}
@media (max-width: 768px) {
.sponsor-arguments__grid {
grid-template-columns: 1fr;
gap: var(--space-2xl);
}
}
/* === sponsor-channels === */
.sponsor-channels > .container {
text-align: center;
}
.sponsor-channels__intro {
max-width: 65ch;
margin-inline: auto;
margin-top: var(--space-s);
color: var(--clr-text-muted);
}
.sponsor-channels__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-l);
margin-top: var(--space-3xl);
list-style: none;
padding: 0;
align-items: stretch;
}
.sponsor-channels__card {
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-top: 3px solid var(--clr-accent);
border-radius: var(--radius-card);
padding: var(--space-2xl);
display: flex;
flex-direction: column;
gap: 0;
text-align: left;
transition: background var(--transition), box-shadow var(--transition);
}
.sponsor-channels__card:hover {
background: rgb(255 255 255 / 0.07);
box-shadow: 0 8px 32px rgb(0 0 0 / 0.35);
}
.sponsor-channels__head {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0;
}
.sponsor-channels__kicker {
font-family: var(--ff-body);
font-size: var(--fs-300);
font-weight: var(--fw-bold);
letter-spacing: var(--ls-wide);
text-transform: uppercase;
color: var(--clr-text-muted);
margin: 0 0 var(--space-s);
}
.sponsor-channels__icon {
width: 2.75rem;
height: 2.75rem;
background: var(--clr-accent);
border-radius: 8px;
display: grid;
place-items: center;
font-size: var(--icon-m);
color: #fff;
margin-bottom: var(--space-m);
}
.sponsor-channels__title {
font-family: var(--ff-heading);
font-size: var(--fs-700);
text-transform: uppercase;
line-height: var(--lh-heading);
margin: 0 0 var(--space-xs);
}
.sponsor-channels__desc {
color: var(--clr-text-muted);
font-size: var(--fs-500);
line-height: var(--lh-body);
margin: 0;
}
.sponsor-channels__divider {
border: none;
border-top: 1px solid var(--clr-glass-border);
margin: var(--space-l) 0;
}
.sponsor-channels__features {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: var(--space-xs);
flex: 1;
}
.sponsor-channels__features li {
display: flex;
align-items: center;
gap: var(--space-xs);
font-size: var(--fs-500);
color: var(--clr-text);
}
.sponsor-channels__check {
flex-shrink: 0;
font-size: var(--icon-s);
color: var(--clr-accent);
}
@media (max-width: 768px) {
.sponsor-channels__grid {
grid-template-columns: 1fr;
}
.sponsor-channels__title {
font-size: var(--fs-700);
}
}
@media (min-width: 769px) and (max-width: 992px) {
.sponsor-channels__grid {
grid-template-columns: repeat(2, 1fr);
}
.sponsor-channels__card:last-child:nth-child(odd) {
grid-column: 1 / -1;
max-width: 50%;
margin-inline: auto;
}
}
/* === persons (Ansprechpartner-Visitenkarten) === */
.persons > .container {
text-align: center;
}
.persons__intro {
margin-inline: auto;
margin-top: var(--space-s);
max-width: 60ch;
color: var(--clr-text-muted);
}
/* Kurze Hairline unter der Bereichs-Überschrift */
.persons h2::after {
content: "";
display: block;
width: 2.5rem;
height: 2px;
margin: var(--space-2xs) auto 0;
background: var(--clr-accent);
}
/* Max. 5 pro Reihe; unvollständige Reihen zentrieren sich automatisch */
.persons__grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: var(--space-m);
margin-top: var(--space-3xl);
text-align: left;
}
/* Fixe Spaltenanzahl (z. B. 3 für 2×3-Layout auf der Startseite) */
.persons__grid--cols-3 {
grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 992px) {
.persons__grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.persons__grid,
.persons__grid--cols-3 {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 500px) {
.persons__grid,
.persons__grid--cols-3 {
grid-template-columns: 1fr;
}
}
.person-card {
display: grid;
height: 100%;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
overflow: hidden;
transition: transform var(--transition), box-shadow var(--transition);
}
.person-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-card);
}
.person-card__media img {
width: 100%;
height: auto;
aspect-ratio: 4 / 5;
object-fit: cover;
/* Ausschnitt nach oben → Gesicht bleibt im Bild, nicht der Bauch */
object-position: center top;
}
.person-card__body {
display: grid;
gap: var(--space-3xs);
padding: var(--space-s) var(--space-m) var(--space-m);
/* Verlauf knüpft an die dunklen Studiofotos an */
background: linear-gradient(180deg, rgb(20 20 20 / 0) 0%, rgb(20 20 20 / 0.35) 100%);
}
/* Kompaktere Kacheln im Ansprechpartner-Grid (faq-contact bleibt unberührt) */
.persons .person-card__media img {
aspect-ratio: 4 / 4.2;
}
.persons .person-card__body {
padding: var(--space-xs) var(--space-s) var(--space-s);
}
.person-card__department {
font-size: var(--fs-650);
letter-spacing: var(--ls-tight);
}
.person-card__name {
color: var(--clr-text-muted);
}
.person-card__contact {
display: inline-flex;
align-items: center;
gap: var(--space-2xs);
margin-top: var(--space-2xs);
padding-block: var(--space-3xs);
color: var(--clr-text);
text-decoration: none;
font-size: var(--fs-500);
}
/* Zweiter Kontakt-Link (z. B. WhatsApp) sitzt enger unter dem ersten */
.person-card__contact + .person-card__contact {
margin-top: 0;
}
.person-card__contact .icon {
color: var(--clr-accent);
flex: none;
}
.person-card__contact span {
overflow-wrap: anywhere;
}
.person-card__contact:hover {
text-decoration: underline;
text-underline-offset: 0.25em;
}
/* === mitmachen / positions (Ehrenamt-Stellen) === */
/* Filter-Stripe (Alle/Fußball/Turnen) — Unterstrich-Tabbar wie group-tabs */
.filter-bar {
display: flex;
flex-wrap: wrap;
margin-bottom: var(--space-2xl);
}
.filter-bar__tab {
padding: var(--space-xs) var(--space-m);
background: none;
border: none;
box-shadow: inset 0 -2px 0 var(--clr-glass-border);
font-family: var(--ff-body);
font-size: var(--fs-500);
color: var(--clr-text-muted);
cursor: pointer;
white-space: nowrap;
transition: color var(--transition), box-shadow var(--transition);
}
.filter-bar__tab:first-child {
padding-inline-start: 0;
}
.filter-bar__tab:hover {
color: var(--clr-text);
}
.filter-bar__tab[aria-pressed="true"] {
color: var(--clr-text);
box-shadow: inset 0 -2px 0 var(--clr-accent);
}
.filter-bar__tab:focus-visible {
outline: 2px solid var(--clr-accent);
outline-offset: -2px;
}
.positions__list {
display: grid;
gap: var(--space-l);
}
.positions__empty {
margin: 0;
padding: var(--space-3xl) 0;
max-width: 60ch;
color: var(--clr-text-muted);
font-size: var(--fs-500);
line-height: var(--lh-body);
}
.positions__empty[hidden] {
display: none;
}
.positions__empty a {
color: var(--clr-text);
text-decoration: underline;
text-underline-offset: 0.2em;
}
/* "Warum mithelfen?": geteiltes sponsor-arguments-Raster, hier mit Überschrift
(nur auf dieser Seite — Partner-/Sportheim-Variante bleibt ohne Heading unberührt) */
#warum-mithelfen > .container {
text-align: center;
}
#warum-mithelfen .sponsor-arguments__intro {
max-width: 60ch;
margin: var(--space-s) auto 0;
color: var(--clr-text-muted);
}
#warum-mithelfen .sponsor-arguments__grid {
margin-top: var(--space-3xl);
text-align: left;
}
/* Aufklappbare Stelle (details/summary, FAQ-Mechanik): eingeklappt nur Bereich + Titel */
.position-card {
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
overflow: hidden;
transition: border-color var(--transition);
}
.position-card[open] {
border-color: var(--clr-glass-border-strong, var(--clr-glass-border));
}
/* display:grid o. Ä. würde sonst [hidden]{display:none} überschreiben — explizit halten */
.position-card[hidden] {
display: none;
}
/* Klickzeile: Icon + Bereich/Titel + Chevron */
.position-card__head {
display: flex;
align-items: center;
gap: var(--space-s);
padding: var(--space-m) var(--space-l);
cursor: pointer;
list-style: none;
transition: background var(--transition);
}
.position-card__head::-webkit-details-marker {
display: none;
}
.position-card__head:hover {
background: rgb(255 255 255 / 0.04);
}
.position-card__head:focus-visible {
outline: 2px solid var(--clr-accent);
outline-offset: -2px;
}
.position-card__icon {
flex-shrink: 0;
width: 2.5rem;
height: 2.5rem;
background: var(--clr-accent);
border-radius: 8px;
display: grid;
place-items: center;
font-size: var(--icon-m);
color: #fff;
}
.position-card__heading {
flex: 1;
min-width: 0;
}
.position-card__area {
display: block;
font-family: var(--ff-body);
font-size: var(--fs-300);
font-weight: var(--fw-bold);
letter-spacing: var(--ls-wide);
text-transform: uppercase;
color: var(--clr-text-muted);
margin: 0 0 var(--space-3xs);
}
.position-card__title {
font-family: var(--ff-heading);
font-size: var(--fs-675);
text-transform: uppercase;
line-height: var(--lh-heading);
margin: 0;
}
.position-card__chevron {
flex: none;
font-size: var(--icon-s);
color: var(--clr-text-muted);
transition: transform var(--transition), color var(--transition);
}
.position-card[open] .position-card__chevron {
transform: rotate(180deg);
color: var(--clr-text);
}
/* Aufgeklappter Inhalt: Detailspalte + Ansprechpartner */
.position-card__body {
display: grid;
grid-template-columns: 1fr minmax(0, 16rem);
gap: var(--space-3xl);
align-items: start;
padding: 0 var(--space-l) var(--space-l) var(--space-6xl);
animation: faq-reveal 260ms ease;
}
.position-card__main > :first-child {
margin-top: 0;
}
.position-card__summary {
color: var(--clr-text-muted);
font-size: var(--fs-500);
line-height: var(--lh-body);
margin: 0;
}
.position-card__tasks {
list-style: none;
padding: 0;
margin: var(--space-m) 0 0;
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
.position-card__tasks li {
display: flex;
align-items: flex-start;
gap: var(--space-xs);
font-size: var(--fs-500);
line-height: var(--lh-body);
}
.position-card__check {
flex-shrink: 0;
margin-top: 0.2em;
font-size: var(--icon-s);
color: var(--clr-accent);
}
.position-card__meta {
margin: var(--space-m) 0 0;
display: grid;
gap: var(--space-xs);
}
.position-card__meta-row {
display: grid;
gap: var(--space-3xs);
}
.position-card__meta dt {
display: inline-flex;
align-items: center;
gap: var(--space-2xs);
font-size: var(--fs-300);
font-weight: var(--fw-bold);
letter-spacing: var(--ls-caps);
text-transform: uppercase;
color: var(--clr-text-muted);
}
.position-card__meta-icon {
color: var(--clr-accent);
}
.position-card__meta dd {
margin: 0;
font-size: var(--fs-500);
line-height: var(--lh-body);
}
/* Kompakte Kontakt-Karte: flacheres Foto als im Ansprechpartner-Grid */
.position-card__contact .person-card__media img {
aspect-ratio: 4 / 3.4;
}
@media (max-width: 768px) {
.position-card__body {
grid-template-columns: 1fr;
gap: var(--space-l);
padding: 0 var(--space-l) var(--space-l);
}
.position-card__contact {
max-width: 18rem;
}
}
/* === contact form === */
.contact__inner {
display: grid;
gap: var(--space-3xl);
justify-items: center;
}
.contact__intro {
max-width: 60ch;
text-align: center;
}
.contact__intro p {
margin-top: var(--space-s);
}
.form {
display: grid;
gap: var(--space-m);
width: 100%;
max-width: 720px;
padding: var(--space-2xl);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.form__row {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: var(--space-m);
}
@media (max-width: 600px) {
.form__row {
grid-template-columns: 1fr;
}
}
/* Floating Label: Label liegt im leeren Feld wie ein Platzhalter und wandert bei
Fokus oder Inhalt nach oben. Rein visuell — das echte <label for> bleibt im DOM
(kein Placeholder-als-Label), darum auch für Screenreader voll nutzbar. */
.form__field {
position: relative;
}
.form__field input,
.form__field select,
.form__field textarea {
width: 100%;
padding: var(--space-l) var(--space-xs) var(--space-2xs);
background: var(--clr-field-bg);
border: 1px solid var(--clr-field-border);
border-radius: var(--radius-btn);
color: var(--clr-text);
transition: border-color var(--transition), background var(--transition), box-shadow var(--transition);
}
/* Label im Ruhezustand — sitzt auf der Eingabezeile (deckt das " "-Placeholder) */
.form__field:not(.form__field--checkbox) > label {
position: absolute;
left: 0.9rem;
top: 1.4rem;
font-size: var(--fs-500);
line-height: 1;
color: var(--clr-text-muted);
pointer-events: none;
transform-origin: left top;
transition: transform var(--transition), color var(--transition);
}
/* Geschwebt: bei Fokus, bei vorhandenem Inhalt (placeholder=" "-Trick) sowie
dauerhaft für Select und Datumsfelder (haben keinen :placeholder-shown-Zustand). */
.form__field:not(.form__field--checkbox):has(input:focus) > label,
.form__field:not(.form__field--checkbox):has(textarea:focus) > label,
.form__field:not(.form__field--checkbox):has(select:focus) > label,
.form__field:not(.form__field--checkbox):has(input:not(:placeholder-shown)) > label,
.form__field:not(.form__field--checkbox):has(textarea:not(:placeholder-shown)) > label,
.form__field:not(.form__field--checkbox):has(select) > label,
.form__field:not(.form__field--checkbox):has(input[type="date"]) > label {
transform: translateY(-0.95rem) scale(0.78);
color: var(--clr-text);
}
.form__field input:hover,
.form__field select:hover,
.form__field textarea:hover {
border-color: var(--clr-field-border-hover);
}
/* Markenroter Fokus-Ring (Akzent nur als Rahmen/Glow, nie als Text). */
.form__field input:focus-visible,
.form__field select:focus-visible,
.form__field textarea:focus-visible {
outline: none;
border-color: var(--clr-accent);
box-shadow: 0 0 0 3px rgb(var(--clr-accent-rgb) / 0.3);
}
/* Der " "-Platzhalter aus dem Floating-Trick bleibt unsichtbar */
.form__field ::placeholder {
color: transparent;
}
/* Fehlerzustand: per JS (aria-invalid) und nativ nach Nutzereingabe (:user-invalid) */
.form__field input[aria-invalid="true"],
.form__field select[aria-invalid="true"],
.form__field textarea[aria-invalid="true"],
.form__field input:user-invalid,
.form__field select:user-invalid,
.form__field textarea:user-invalid {
border-color: var(--clr-error);
}
.form__field select {
appearance: none;
padding-right: var(--space-3xl);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' fill='none'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%23ffffff' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.9rem center;
}
.form__field select option {
background: var(--clr-bg);
color: var(--clr-text);
}
.form__required {
color: var(--clr-accent);
}
.form__hint {
margin-top: var(--space-2xs);
font-size: var(--fs-400);
color: var(--clr-text-muted);
}
.form__error-msg {
margin-top: var(--space-2xs);
font-size: var(--fs-400);
color: var(--clr-error);
}
.form button[disabled] {
opacity: 0.65;
cursor: progress;
}
.form__field textarea {
resize: vertical;
min-height: 8rem;
}
.form__field--checkbox {
display: grid;
grid-template-columns: auto 1fr;
align-items: start;
gap: var(--space-2xs);
}
.form__field--checkbox input {
/* 24px — Mindest-Zielgröße (WCAG 2.5.8) */
width: 1.5rem;
height: 1.5rem;
margin-top: var(--space-4xs);
accent-color: var(--clr-accent);
}
.form__field--checkbox label {
font-size: var(--fs-500);
}
/* Leer: unsichtbar, aber im Accessibility-Tree — display:none würde die
aria-live-Region abmelden und Screenreader verpassen die erste Meldung. */
.form__status:empty {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.form__success {
padding: var(--space-xs) var(--space-s);
border: 1px solid var(--clr-success);
border-radius: var(--radius-btn);
color: var(--clr-success);
}
.form__error {
padding: var(--space-xs) var(--space-s);
border: 1px solid var(--clr-error);
border-radius: var(--radius-btn);
color: var(--clr-error);
}
.form__submit {
margin: 0;
}
/* Gruppierte Abschnitte (fieldset/legend) — jeder Block ein dezent umrandetes
Feld mit Titel auf der Rahmenlinie. Gliedert lange Formulare optisch klar. */
.form__group {
margin: 0;
padding: var(--space-m) var(--space-l) var(--space-l);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
min-inline-size: 0;
}
.form__legend {
padding: 0 var(--space-2xs);
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text);
}
.form__group-body {
display: grid;
gap: var(--space-m);
}
/* === Werbe-/Sponsoren-Banner (Slider) === */
.ad-banner {
--banner-interval: 6s;
}
.ad-banner__track {
list-style: none;
margin: 0;
padding: 0;
}
/* Meta-Zeile unter dem Slider: Label links, Controls rechts */
.ad-banner__meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-s);
margin-top: var(--space-s);
min-height: 2rem;
}
.ad-banner__meta-label {
font-size: var(--fs-400);
color: var(--clr-text-muted);
letter-spacing: var(--ls-tight);
}
.ad-banner__slide[hidden] {
display: none;
}
.ad-banner__slide {
display: flex;
flex-direction: column;
align-items: flex-start;
min-height: 320px;
padding: clamp(var(--space-xl), var(--space-s) + 2vw, var(--space-4xl));
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-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: var(--space-xs) var(--space-s);
width: 100%;
margin-top: auto;
padding-top: var(--space-l);
}
/* 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
überblenden. Die ausgehende driftet leicht nach unten, die eingehende steigt
auf. Ohne JS greift weiter .ad-banner__slide[hidden] (nur erste Folie).
Reduced-Motion: globaler Kill-Switch in reset.css macht den Wechsel instant. */
.ad-banner.is-enhanced .ad-banner__track {
display: grid;
}
.ad-banner.is-enhanced .ad-banner__slide {
grid-area: 1 / 1;
opacity: 0;
transform: translateY(8px);
pointer-events: none;
transition: opacity 0.55s ease, transform 0.55s ease, visibility 0s linear 0.55s;
visibility: hidden;
}
.ad-banner.is-enhanced .ad-banner__slide.is-active {
opacity: 1;
transform: none;
pointer-events: auto;
visibility: visible;
transition: opacity 0.55s ease, transform 0.55s ease, visibility 0s;
}
/* Optionaler Hintergrund pro Banner (data: "background").
Dunkler Verlauf über dem Bild hält Text & CTA links lesbar. */
.ad-banner__slide--bg {
background-image:
linear-gradient(to right, rgb(0 0 0 / 0.82), rgb(0 0 0 / 0.45) 60%, rgb(0 0 0 / 0.3)),
var(--banner-bg);
background-size: cover;
background-position: center;
/* Bild an der Innenkante kappen, nicht unter den 1px-Rahmen malen
(sonst schimmert es an der transparenten Rahmenkante durch). */
background-clip: padding-box;
border-color: transparent;
}
/* Pro-Slide-Akzentfarbe (data: "accent") — z. B. Sponsor-CI statt Vereins-Rot.
--banner-accent kommt als Inline-Variable von der Komponente. */
.ad-banner__slide--accent {
--clr-accent: var(--banner-accent);
--clr-accent-dark: color-mix(in srgb, var(--banner-accent) 82%, #000);
}
/* Solider Button: dunkler, aus der Akzentfarbe abgeleiteter Text — helle
Akzentfarben (z. B. Teal) hätten mit Weiß zu wenig Kontrast (WCAG 1.4.3). */
.ad-banner__slide--accent .ad-banner__cta.btn:not(.btn--outline) {
color: color-mix(in srgb, var(--banner-accent) 22%, #000);
}
.ad-banner__slide--accent .ad-banner__cta.btn--outline {
color: var(--banner-accent);
border-color: var(--banner-accent);
}
.ad-banner__slide--accent .ad-banner__cta.btn--outline:hover {
background: color-mix(in srgb, var(--banner-accent) 16%, transparent);
border-color: var(--banner-accent);
color: var(--banner-accent);
}
.ad-banner__slide--bg .ad-banner__text {
color: var(--clr-text);
}
@media (max-width: 768px) {
/* Auf Mobil läuft der Verlauf nach unten, damit der gestapelte Text lesbar bleibt. */
.ad-banner__slide--bg {
background-image:
linear-gradient(to bottom, rgb(0 0 0 / 0.82), rgb(0 0 0 / 0.5)),
var(--banner-bg);
}
}
/* Eigenwerbung („Hier könnte Ihre Werbung stehen") — rote Glasfläche mit
gestricheltem Frame, das eine freie Werbefläche andeutet. */
.ad-banner__slide--house {
position: relative;
overflow: hidden;
background:
radial-gradient(135% 145% at 100% 0%, rgb(var(--clr-accent-rgb) / 0.24), transparent 55%),
var(--clr-glass-bg);
border-color: rgb(var(--clr-accent-rgb) / 0.5);
}
.ad-banner__slide--house .ad-banner__content,
.ad-banner__slide--house .ad-banner__logo {
position: relative;
z-index: 1;
}
.ad-banner__slide--house .ad-banner__tag {
color: #fff;
background: var(--clr-accent);
border-color: transparent;
}
.ad-banner__slide--house .ad-banner__text {
color: var(--clr-text);
}
/* Eigenwerbung MIT Foto-Hintergrund: rot-dunkler Verlauf von links hält den
Text lesbar, das Foto bleibt rechts sichtbar. */
.ad-banner__slide--house.ad-banner__slide--bg {
background-image:
linear-gradient(to right, rgb(12 10 11 / 0.9), rgb(20 16 17 / 0.55) 55%, rgb(20 16 17 / 0.12) 90%),
var(--banner-bg);
background-size: cover;
background-position: center;
/* wie bei --bg: nicht unter den Rahmen malen (--house-Shorthand setzt es zurück) */
background-clip: padding-box;
border-color: transparent;
}
@media (max-width: 768px) {
/* Auf Mobil läuft der Verlauf nach unten (Text steht gestapelt darüber). */
.ad-banner__slide--house.ad-banner__slide--bg {
background-image:
linear-gradient(to bottom, rgb(12 10 11 / 0.88), rgb(20 16 17 / 0.7)),
var(--banner-bg);
}
}
/* 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 {
margin-left: auto;
align-self: center;
padding: 0.2em 0.7em;
font-size: var(--fs-300);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
background: rgb(0 0 0 / 0.45);
border: 1px solid rgb(255 255 255 / 0.18);
border-radius: 999px;
}
.ad-banner__title {
font-family: var(--ff-heading);
font-size: var(--fs-700);
line-height: var(--lh-heading);
margin-bottom: var(--space-2xs);
}
.ad-banner__text {
max-width: 52ch;
color: var(--clr-text-muted);
}
/* CTA-Reihe: Primär- + optionaler Outline-Sekundär-Button nebeneinander. */
.ad-banner__actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-xs);
}
/* Logo führt die Slide an: kompaktes Badge oben links. */
.ad-banner__logo {
margin-bottom: var(--space-l);
}
/* Helle Platte für dunkle Firmenlogos (Wortmarken). */
.ad-banner__logo--light {
padding: var(--space-2xs) var(--space-xs);
background: #fff;
border-radius: var(--radius-btn);
}
.ad-banner__logo img {
display: block;
width: auto;
height: auto;
max-width: 230px;
max-height: 56px;
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) {
.ad-banner__content {
max-width: 100%;
}
}
/* Steuerung: Pause/Play-Taste + Indikatorleiste — sitzt rechts in .ad-banner__meta. */
.ad-banner__controls {
display: flex;
align-items: center;
gap: var(--space-xs);
flex-shrink: 0;
}
.ad-banner__controls[hidden] {
display: none;
}
.ad-banner__toggle {
display: inline-grid;
place-items: center;
width: 2.25rem;
height: 2.25rem;
padding: 0;
color: var(--clr-text);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: 999px;
cursor: pointer;
transition: background var(--transition);
}
.ad-banner__toggle[hidden] {
display: none;
}
.ad-banner__nav-btn {
display: inline-grid;
place-items: center;
width: 2.25rem;
height: 2.25rem;
padding: 0;
font-size: var(--icon-s);
color: var(--clr-text);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: 999px;
cursor: pointer;
transition: background var(--transition);
}
.ad-banner__nav-btn:hover {
background: rgb(255 255 255 / 0.2);
}
.ad-banner__nav-btn:focus-visible {
outline: 2px solid var(--clr-text);
outline-offset: 3px;
}
.ad-banner__toggle:hover {
background: rgb(255 255 255 / 0.2);
}
.ad-banner__toggle:focus-visible {
outline: 2px solid var(--clr-text);
outline-offset: 3px;
}
.ad-banner__toggle-icon {
font-size: var(--icon-s);
}
/* Pause-Icon im Abspiel-Zustand, Play-Icon wenn pausiert. */
.ad-banner__toggle .ad-banner__toggle-icon--play {
display: none;
}
.ad-banner__toggle[aria-pressed="true"] .ad-banner__toggle-icon--pause {
display: none;
}
.ad-banner__toggle[aria-pressed="true"] .ad-banner__toggle-icon--play {
display: inline-block;
}
/* Indikatorleiste — die aktive Leiste füllt sich über --banner-interval. */
.ad-banner__indicators {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--space-2xs);
}
.ad-banner__dot {
position: relative;
width: 48px;
height: 6px;
padding: 0;
border: 0;
border-radius: 999px;
background: var(--clr-glass-border);
cursor: pointer;
overflow: hidden;
transition: background var(--transition);
}
.ad-banner__dot:hover {
background: rgb(255 255 255 / 0.35);
}
.ad-banner__dot:focus-visible {
outline: 2px solid var(--clr-text);
outline-offset: 3px;
}
.ad-banner__progress {
position: absolute;
inset: 0;
background: var(--clr-accent);
transform: scaleX(0);
transform-origin: left;
}
.ad-banner__dot.is-active .ad-banner__progress {
animation: ad-progress var(--banner-interval) linear forwards;
}
.ad-banner.is-paused .ad-banner__dot.is-active .ad-banner__progress {
animation-play-state: paused;
}
@keyframes ad-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
.ad-banner__dot.is-active .ad-banner__progress {
animation: none;
transform: scaleX(1);
}
}
/* === key-facts (Faktenleiste) === */
.key-facts__grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--space-s);
margin: 0;
padding: 0;
list-style: none;
}
.key-facts__item {
display: flex;
align-items: center;
gap: var(--space-xs);
padding: var(--space-s) var(--space-m);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.key-facts__icon {
display: inline-flex;
font-size: var(--icon-l);
color: var(--clr-accent);
}
.key-facts__text {
display: grid;
gap: var(--space-4xs);
}
.key-facts__label {
font-size: var(--fs-400);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
}
.key-facts__value {
font-family: var(--ff-heading);
font-size: var(--fs-650);
line-height: var(--lh-heading);
}
/* === team-about === */
.team-about p {
max-width: 68ch;
}
/* === training-location (Bento-Grid) === */
.bento {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(0, auto);
gap: var(--space-m);
}
/* Tile-Größen: Trainingszeiten = großer Anker, Spielort = breit, dazu zwei kleine. */
.bento__tile--times { grid-column: span 2; grid-row: span 2; }
.bento__tile--venue { grid-column: span 2; }
.bento__tile--accent { grid-column: span 1; }
.bento__tile--route { grid-column: span 1; }
.bento__tile {
position: relative;
display: flex;
flex-direction: column;
padding: var(--space-xl);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
overflow: hidden;
}
/* Akzent-Tile: gefüllt, weiße Schrift (gut lesbar), zentrierte Kennzahl. */
.bento__tile--accent {
justify-content: center;
gap: var(--space-3xs);
background: var(--clr-accent);
border-color: var(--clr-accent);
text-align: center;
}
.bento__tile--route {
justify-content: center;
align-items: center;
gap: var(--space-s);
text-align: center;
}
/* Inhalt über dem Deko-Icon halten. */
.bento__heading,
.bento__sessions,
.bento__address,
.bento__note {
position: relative;
z-index: 1;
}
.bento__heading {
display: flex;
align-items: center;
gap: var(--space-xs);
margin-bottom: var(--space-l);
font-size: var(--fs-690);
line-height: var(--lh-heading);
}
.bento__hicon {
flex: none;
font-size: var(--icon-l);
color: var(--clr-accent);
}
.bento__sessions {
margin: 0;
padding: 0;
list-style: none;
}
.bento__sessions li {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-s);
padding: var(--space-s) 0;
border-bottom: 1px solid var(--clr-glass-border);
}
.bento__sessions li:first-child { padding-top: 0; }
.bento__sessions li:last-child { padding-bottom: 0; border-bottom: 0; }
.bento__day {
font-size: var(--fs-600);
}
.bento__time {
font-family: var(--ff-heading);
font-size: var(--fs-650);
color: var(--clr-text);
}
.bento__note {
margin-top: var(--space-s);
}
.bento__address {
margin: 0;
font-size: var(--fs-600);
line-height: 1.5;
}
/* Akzent-Tile-Typo. */
.bento__stat-label {
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: rgb(255 255 255 / 0.85);
}
.bento__stat-value {
font-family: var(--ff-heading);
font-size: var(--fs-690);
line-height: var(--lh-heading);
color: #fff;
}
.bento__route-label {
font-family: var(--ff-heading);
font-size: var(--fs-650);
}
/* Großes, angeschnittenes Deko-Icon unten rechts. */
.bento__deco {
position: absolute;
right: -1rem;
bottom: -1.75rem;
z-index: 0;
font-size: var(--fs-deco);
line-height: 1;
color: var(--clr-text);
opacity: 0.06;
pointer-events: none;
}
@media (max-width: 900px) {
.bento {
grid-template-columns: repeat(2, 1fr);
}
.bento__tile--times { grid-column: span 2; grid-row: auto; }
.bento__tile--venue { grid-column: span 2; }
}
@media (max-width: 560px) {
.bento {
grid-template-columns: 1fr;
}
.bento__tile--times,
.bento__tile--venue,
.bento__tile--accent,
.bento__tile--route {
grid-column: span 1;
}
}
/* === turnen-dash (Turn-Disziplin-Dashboard im Bento-Look wie Mannschaftsseiten) === */
.turnen-dash {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-m);
}
/* Eine Gruppe: Trainingszeiten (2/3) + Verantwortlich (1/3), Ort volle Breite darunter. */
.turnen-dash--single {
grid-template-areas:
"train train lead"
"venue venue venue";
}
.turnen-dash--single .turnen-dash__training { grid-area: train; }
.turnen-dash--single .turnen-dash__contact { grid-area: lead; }
.turnen-dash--single .turnen-dash__venue { grid-area: venue; }
/* Mehrere Gruppen: Ort (2/3) + Kontakt rechts (1/3) — Zeiten stehen je Gruppe.
Kontakt steht dadurch konsistent rechts wie bei den Einzel-Disziplinen. */
.turnen-dash:not(.turnen-dash--single) {
grid-template-areas: "venue venue lead";
}
.turnen-dash:not(.turnen-dash--single) .turnen-dash__contact { grid-area: lead; }
.turnen-dash:not(.turnen-dash--single) .turnen-dash__venue { grid-area: venue; }
/* Mit Hinweis-Kachel: rote Banner-Zeile ganz oben (volle Breite). */
.turnen-dash--notice.turnen-dash--single {
grid-template-areas:
"notice notice notice"
"train train lead"
"venue venue venue";
}
.turnen-dash--notice:not(.turnen-dash--single) {
grid-template-areas:
"notice notice notice"
"venue venue lead";
}
.turnen-dash__notice { grid-area: notice; }
/* Hinweis-Kachel: klar rot, weiße Schrift, Icon links (z. B. Wartelisten-Status). */
.turnen-dash__notice {
flex-direction: row;
align-items: flex-start;
gap: var(--space-xs);
background: var(--clr-accent);
border-color: var(--clr-accent);
color: #fff;
}
.turnen-dash__notice p {
margin: 0;
max-width: none;
font-size: var(--fs-600);
line-height: 1.5;
}
.turnen-dash__notice-icon {
flex: none;
margin-top: 0.1em;
font-size: var(--icon-l);
}
/* Trainingsort: Adresse links, Route-Button rechts (wie team-bento__venue). */
.turnen-dash__venue {
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: var(--space-m);
}
.turnen-dash__venue-main {
position: relative;
z-index: 1;
}
.turnen-dash__venue .bento__heading {
margin-bottom: var(--space-2xs);
}
.turnen-dash__route {
position: relative;
z-index: 1;
flex: none;
}
/* Kontakt-Kachel: schlichter weißer Mail-Link (zentriert) auf der Akzentfläche. */
.turnen-dash__mail {
display: inline-flex;
align-self: center;
align-items: center;
gap: var(--space-2xs);
margin-top: var(--space-xs);
color: #fff;
font-size: var(--fs-500);
text-decoration: underline;
text-underline-offset: 0.2em;
}
.turnen-dash__mail:hover,
.turnen-dash__mail:focus-visible {
color: rgb(255 255 255 / 0.82);
}
.turnen-dash__mail-icon {
flex: none;
}
@media (max-width: 900px) {
.turnen-dash,
.turnen-dash--single {
grid-template-columns: 1fr;
grid-template-areas:
"train"
"lead"
"venue";
}
.turnen-dash:not(.turnen-dash--single) {
grid-template-areas:
"lead"
"venue";
}
.turnen-dash--notice,
.turnen-dash--notice.turnen-dash--single {
grid-template-areas:
"notice"
"train"
"lead"
"venue";
}
.turnen-dash--notice:not(.turnen-dash--single) {
grid-template-areas:
"notice"
"lead"
"venue";
}
}
/* === group-list (Turn-Gruppen einer Disziplin) === */
.group-list__title {
margin-bottom: var(--space-l);
text-align: center;
}
/* === group-tabs (Tab-Navigation für rich Gruppen) === */
.group-tabs__bar {
display: flex;
justify-content: center;
overflow-x: auto;
scrollbar-width: none;
margin-bottom: var(--space-2xl);
gap: 0;
}
.group-tabs__bar::-webkit-scrollbar { display: none; }
.group-tabs__tab {
flex-shrink: 0;
padding: var(--space-xs) var(--space-l);
background: none;
border: none;
box-shadow: inset 0 -2px 0 var(--clr-glass-border);
font-family: var(--ff-body);
font-size: var(--fs-500);
color: var(--clr-text-muted);
cursor: pointer;
white-space: nowrap;
transition: color var(--transition), box-shadow var(--transition);
}
.group-tabs__tab:hover {
color: var(--clr-text);
}
.group-tabs__tab[aria-selected="true"] {
color: var(--clr-text);
box-shadow: inset 0 -2px 0 var(--clr-accent);
}
.group-tabs__tab:focus-visible {
outline: 2px solid var(--clr-accent);
outline-offset: -2px;
}
/* Panel-Karte übernimmt das bestehende group-card--stacked-Layout */
.group-tabs__panel {
display: grid;
grid-template-columns: 1.6fr 1fr;
gap: var(--space-4xl);
align-items: start;
padding: var(--space-3xl) var(--space-3xl);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
/* display:grid überschreibt den UA-Stil [hidden]{display:none} — explizit korrigieren */
.group-tabs__panel[hidden] {
display: none;
}
@media (max-width: 768px) {
.group-tabs__panel {
grid-template-columns: 1fr;
gap: var(--space-xl);
padding: var(--space-l) var(--space-xl);
}
}
/* Schlichte Gruppen (z. B. Kurse) als Raster, beschreibende Gruppen gestapelt. */
.group-list--grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: var(--space-m);
}
.group-list--stacked {
display: flex;
flex-direction: column;
gap: var(--space-4xl);
}
.group-card {
padding: var(--space-xl) var(--space-2xl) var(--space-2xl);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
/* Gestapelt: Beschreibung links, Trainingszeiten-Panel rechts. */
.group-list--stacked .group-card {
display: grid;
grid-template-columns: 1.6fr 1fr;
gap: var(--space-4xl);
align-items: start;
padding: var(--space-3xl) var(--space-3xl);
}
@media (max-width: 768px) {
.group-list--stacked .group-card {
grid-template-columns: 1fr;
gap: var(--space-xl);
padding: var(--space-l) var(--space-xl) var(--space-xl);
}
}
/* Beschreibungsspalte: angenehme Zeilenlänge + Lesefluss. */
.group-card__body {
max-width: 64ch;
}
/* Name links, Level-Chip rechts vertikal zentriert */
.group-card__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-s);
flex-wrap: wrap;
}
.group-card__name {
font-size: var(--fs-690);
line-height: var(--lh-heading);
}
.group-card__level {
flex-shrink: 0;
padding: var(--space-4xs) var(--space-2xs);
font-size: var(--fs-400);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
border: 1px solid var(--clr-glass-border-strong);
border-radius: 999px;
white-space: nowrap;
}
/* Intro = Lead-Paragraph, deutlich abgesetzt vom Level-Chip */
.group-card__intro {
margin: var(--space-m) 0 0;
font-size: var(--fs-600);
line-height: 1.65;
color: var(--clr-text);
}
/* Detail-Abschnitte: Akzent-Randstrich links als visueller Anker */
/* Font-Familie, Uppercase und Sperrung kommen jetzt aus der h4-Basisregel —
hier bleibt nur, was diese Überschrift von der Basis unterscheidet. */
.group-card__detail-heading {
margin: var(--space-3xl) 0 0;
padding-left: var(--space-xs);
border-left: 2px solid var(--clr-accent);
font-size: var(--fs-500);
color: var(--clr-text);
}
.group-card__detail-text {
margin: var(--space-2xs) 0 0;
padding-left: var(--space-xs);
font-size: var(--fs-600);
line-height: 1.72;
color: var(--clr-text);
}
.group-card__recommendation {
margin: var(--space-2xl) 0 0;
padding: var(--space-s) var(--space-s) 0;
border-top: 1px solid var(--clr-glass-border);
font-size: var(--fs-500);
font-style: italic;
line-height: 1.6;
color: var(--clr-text-muted);
}
/* Trainingszeiten-Panel in der Karte. */
.group-card__schedule {
margin-top: var(--space-m);
}
.group-list--stacked .group-card__schedule,
.group-tabs .group-card__schedule {
margin-top: 0;
padding: var(--space-xl);
background: var(--clr-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
border-top: 2px solid var(--clr-accent);
}
.group-card__schedule-title {
display: flex;
align-items: center;
gap: var(--space-2xs);
margin: 0 0 var(--space-s);
font-size: var(--fs-650);
letter-spacing: var(--ls-tight);
}
.group-card__schedule-icon {
flex: none;
color: var(--clr-accent);
}
.group-card__trainers {
margin: var(--space-s) 0 0;
padding-top: var(--space-xs);
border-top: 1px solid var(--clr-glass-border);
font-size: var(--fs-500);
line-height: 1.5;
}
.group-card__note {
margin: var(--space-2xs) 0 0;
font-size: var(--fs-500);
}
/* Trainingszeiten-Liste (Tag/Zeit + optional Label, Notiz, Übungsleitung). */
.schedule-list {
margin: 0;
padding: 0;
list-style: none;
}
.schedule-row {
padding: var(--space-xs) 0;
border-bottom: 1px solid var(--clr-glass-border);
}
.schedule-row:first-child { padding-top: 0; }
.schedule-row:last-child { padding-bottom: 0; border-bottom: 0; }
.schedule-row__label {
display: block;
margin-bottom: var(--space-3xs);
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-accent);
font-family: var(--ff-body);
}
.schedule-row__when {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-s);
}
.schedule-row__day {
font-size: var(--fs-600);
color: var(--clr-text);
}
.schedule-row__time {
font-size: var(--fs-600);
color: var(--clr-text);
}
.schedule-row__note {
display: block;
margin-top: var(--space-3xs);
font-size: var(--fs-500);
color: var(--clr-text-muted);
}
.schedule-row__trainers {
display: block;
margin-top: var(--space-3xs);
font-size: var(--fs-500);
line-height: 1.5;
color: var(--clr-text-muted);
}
.schedule-row__trainers-label {
color: var(--clr-text-muted);
}
.group-list__footnote {
margin: var(--space-l) 0 0;
font-size: var(--fs-500);
}
@media (max-width: 600px) {
.schedule-row__when {
flex-direction: column;
gap: var(--space-4xs);
}
.schedule-row__time {
text-align: left;
}
}
/* === cta-band === */
.cta-band__inner {
max-width: 60ch;
margin-inline: auto;
text-align: center;
}
.cta-band__text {
margin-top: var(--space-xs);
margin-inline: auto;
}
.cta-band__actions {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--space-xs);
margin-top: var(--space-xl);
}
/* === faq (Accordion) === */
.faq__inner {
max-width: 760px;
margin-inline: auto;
}
.faq__inner > h2 {
text-align: center;
}
/* Schlichte Trennlinien-Liste statt Kästchen. */
.faq__list {
margin-top: var(--space-3xl);
border-top: 1px solid var(--clr-glass-border);
}
.faq__item {
border-bottom: 1px solid var(--clr-glass-border);
}
.faq__q {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-s);
padding: var(--space-m) var(--space-3xs);
font-size: var(--fs-600);
line-height: 1.3;
cursor: pointer;
list-style: none;
transition: color var(--transition);
}
.faq__q::-webkit-details-marker {
display: none;
}
.faq__q:hover {
color: var(--clr-text-muted);
}
.faq__q:focus-visible {
outline: 2px solid var(--clr-text);
outline-offset: 2px;
}
.faq__chevron {
flex: none;
font-size: var(--icon-s);
color: var(--clr-text-muted);
transition: transform var(--transition), color var(--transition);
}
.faq__item[open] .faq__q {
color: var(--clr-text);
}
.faq__item[open] .faq__chevron {
transform: rotate(180deg);
color: var(--clr-text);
}
.faq__a {
padding: 0 var(--space-3xs) var(--space-l);
color: var(--clr-text-muted);
}
.faq__a p {
max-width: 64ch;
margin: 0;
}
/* Antwort beim Öffnen sanft einblenden (reduced-motion via reset.css deaktiviert). */
.faq__item[open] .faq__a {
animation: faq-reveal 260ms ease;
}
@keyframes faq-reveal {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
/* === age-groups (Jugend-Altersklassen) === */
.age-groups > .container {
text-align: center;
}
.age-groups__grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-xl);
margin: var(--space-3xl) 0 0;
padding: 0;
list-style: none;
text-align: left;
}
@media (max-width: 600px) {
.age-groups__grid {
grid-template-columns: 1fr;
}
}
.age-group {
display: grid;
grid-template-rows: auto 1fr;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
overflow: hidden;
transition: transform var(--transition), box-shadow var(--transition);
}
.age-group:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-card);
}
.age-group__media {
position: relative;
overflow: hidden;
}
.age-group__img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 3 / 2;
object-fit: cover;
transition: transform var(--transition);
}
.age-group:hover .age-group__img {
transform: scale(1.05);
}
.age-group__body {
display: grid;
gap: var(--space-2xs);
align-content: start;
padding: var(--space-l) var(--space-l) var(--space-l);
}
.age-group__name {
font-size: var(--fs-700);
line-height: var(--lh-heading);
}
.age-group__training {
display: inline-flex;
align-items: flex-start;
gap: var(--space-2xs);
margin: 0;
font-size: var(--fs-600);
line-height: 1.45;
color: var(--clr-text-muted);
}
.age-group__icon {
flex: none;
margin-top: 0.2em;
color: var(--clr-accent);
}
/* Platzhalter-Karten (B-/A-Jugend „In Entstehung"): Bild gedämpft, Label oben links. */
.age-group--upcoming .age-group__img {
opacity: 0.5;
filter: grayscale(0.5);
}
.age-group--upcoming:hover .age-group__img {
transform: none;
}
.age-group__soon {
position: absolute;
top: 0.9rem;
left: 0.9rem;
padding: var(--space-3xs) var(--space-xs);
font-family: var(--ff-body);
font-size: var(--fs-400);
letter-spacing: var(--ls-wide);
text-transform: uppercase;
color: #fff;
background: var(--clr-accent);
border-radius: var(--radius-btn);
}
/* === team-cards (Mannschafts-Karten) === */
.team-cards > .container {
text-align: center;
}
.team-cards__intro {
max-width: 60ch;
margin: var(--space-s) auto 0;
}
/* Intro als „Klärtext" unter den Kacheln → mehr Luft nach oben zur Kartenreihe */
.team-cards__intro--below {
margin-top: var(--space-3xl);
}
.team-cards__grid {
display: grid;
/* Zwei Karten pro Reihe (50/50) — bei vier Mannschaften ergibt das ein 2×2-Raster */
grid-template-columns: repeat(2, 1fr);
gap: var(--space-l);
margin: var(--space-3xl) 0 0;
padding: 0;
list-style: none;
text-align: left;
}
@media (max-width: 600px) {
.team-cards__grid {
grid-template-columns: 1fr;
}
}
.team-card {
display: grid;
grid-template-rows: auto 1fr;
height: 100%;
color: var(--clr-text);
text-decoration: none;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
overflow: hidden;
transition: transform var(--transition), box-shadow var(--transition);
}
.team-card:hover,
.team-card:focus-visible {
transform: translateY(-4px);
box-shadow: var(--shadow-card);
}
.team-card__img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 16 / 10;
object-fit: cover;
transition: transform var(--transition);
}
.team-card:hover .team-card__img,
.team-card:focus-visible .team-card__img {
transform: scale(1.04);
}
.team-card__body {
display: flex;
flex-direction: column;
gap: var(--space-3xs);
padding: var(--space-l) var(--space-l) var(--space-l);
}
.team-card__name {
/* Coolvetica/Heading (siehe CLAUDE.md) — bewusst groß und prägnant. */
font-size: var(--fs-690);
line-height: var(--lh-heading);
}
.team-card__meta {
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
}
.team-card__cta {
display: inline-flex;
align-items: center;
gap: var(--space-2xs);
/* an den unteren Rand schieben → CTA aller Karten fluchtet, egal wie lang der Name */
margin-top: auto;
padding-top: var(--space-s);
/* Body-Schrift (Abel) — Coolvetica bleibt den Überschriften vorbehalten */
font-size: var(--fs-500);
color: var(--clr-accent);
}
.team-card__arrow {
transition: transform var(--transition);
}
.team-card:hover .team-card__arrow {
transform: translateX(3px);
}
/* === team-roster (Kader + Trainerstab) === */
.team-roster > .container {
text-align: center;
}
.team-roster__intro {
max-width: 60ch;
margin: var(--space-s) auto 0;
}
/* Positions-Zwischenüberschrift (Trainer & Betreuer, Torwart, Abwehr, …) */
.team-roster__group {
margin-top: var(--space-4xl);
padding-bottom: var(--space-2xs);
border-bottom: 1px solid var(--clr-glass-border);
text-align: left;
font-size: var(--fs-700);
line-height: var(--lh-heading);
}
.team-roster__grid {
display: grid;
/* Feste 5 pro Reihe → größere Cards/Bilder; runter gestuft auf schmaleren Screens */
grid-template-columns: repeat(5, 1fr);
gap: var(--space-m);
margin: var(--space-l) 0 0;
padding: 0;
list-style: none;
text-align: left;
}
@media (max-width: 992px) {
.team-roster__grid {
grid-template-columns: repeat(4, 1fr);
}
}
@media (max-width: 768px) {
.team-roster__grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 500px) {
.team-roster__grid {
grid-template-columns: repeat(2, 1fr);
}
}
.roster-card {
display: grid;
grid-template-rows: auto 1fr;
height: 100%;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
overflow: hidden;
transition: transform var(--transition), box-shadow var(--transition);
}
.roster-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-card);
}
/* Trainerstab dezent mit Akzentkante abgesetzt */
.roster-card--staff {
border-color: var(--clr-accent);
}
.roster-card__media img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 4 / 5;
object-fit: cover;
object-position: center top;
}
.roster-card__body {
display: flex;
flex-direction: column;
gap: var(--space-4xs);
padding: var(--space-xs) var(--space-s) var(--space-s);
background: linear-gradient(180deg, rgb(20 20 20 / 0) 0%, rgb(20 20 20 / 0.35) 100%);
}
.roster-card__role {
font-size: var(--fs-400);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-accent);
}
/* Name in Abel (Body) — Coolvetica wäre unter 28px unzulässig (siehe CLAUDE.md) */
.roster-card__name {
font-size: var(--fs-500);
}
/* --- Variante: Name als Overlay im Foto, unten links, dunkler Verlauf von unten --- */
.roster-card--overlay {
position: relative;
display: block;
}
.roster-card--overlay .roster-card__img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 4 / 5;
object-fit: cover;
object-position: center top;
}
.roster-card__caption {
position: absolute;
inset: auto 0 0 0;
display: flex;
flex-direction: column;
gap: var(--space-4xs);
padding: var(--space-3xl) var(--space-s) var(--space-xs);
/* dunkler Fade von unten → Name bleibt auf jedem Foto lesbar */
background: linear-gradient(180deg, rgb(15 15 15 / 0) 0%, rgb(15 15 15 / 0.55) 45%, rgb(15 15 15 / 0.9) 100%);
}
/* Name hier in Coolvetica (≥28px = fs-650, Mindestgröße eingehalten) */
.roster-card--overlay .roster-card__name {
font-family: var(--ff-heading);
font-size: var(--fs-650);
line-height: var(--lh-heading);
text-transform: uppercase;
color: #fff;
}
.roster-card--overlay .roster-card__role {
/* Auf dem dunklen Foto-Verlauf: klein und weiß statt rot → besser lesbar */
font-size: var(--fs-300);
color: #fff;
}
/* === faq-contact (FAQ 2/3 + Ansprechpartner 1/3) === */
.faq-contact__inner {
display: grid;
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
gap: var(--space-4xl);
align-items: start;
}
/* Ohne Kontakt: FAQ allein, lesbar zentriert. */
.faq-contact--solo .faq-contact__inner {
grid-template-columns: minmax(0, 760px);
justify-content: center;
}
/* Sektions-Kopf zentriert über dem 2-Spalten-Inhalt (FAQ + Kontakt) */
.faq-contact__title {
text-align: center;
margin: 0;
}
/* Gedämpfte Subline unter der Überschrift (einheitlich mit den anderen Sektionen) */
.faq-contact__intro {
max-width: 60ch;
margin-inline: auto;
margin-bottom: var(--space-3xl);
text-align: center;
}
/* Abstände je nachdem, ob eine Subline folgt */
.faq-contact__title + .faq-contact__intro {
margin-top: var(--space-s);
}
.faq-contact__title + .faq-contact__inner {
margin-top: var(--space-3xl);
}
.faq-contact__aside > h2 {
margin-bottom: var(--space-l);
}
/* --- Ansprechpartner-Mini-Slider (mehrere Kontakte) ---
Ohne JS: alle Karten gestapelt sichtbar. Mit JS (--ready): nur eine sichtbar,
wechselt automatisch; Punkte zur manuellen Auswahl. */
.contact-slider {
/* Auf Kartenbreite begrenzt und zentriert → Karte und Punkte teilen dieselbe Mittelachse */
max-width: 320px;
margin-inline: auto;
}
.contact-slider__track {
display: flex;
flex-direction: column;
gap: var(--space-l);
margin: 0;
padding: 0;
list-style: none;
}
.contact-slider__dots {
/* Ohne JS funktionslos → ausgeblendet; erst mit aktivem Slider sichtbar. */
display: none;
}
.contact-slider--ready .contact-slider__dots {
display: flex;
justify-content: center;
gap: var(--space-2xs);
margin-top: var(--space-s);
}
.contact-slider__dot {
/* 24px-Ziel (WCAG 2.5.8), sichtbarer Punkt 10px */
display: grid;
place-items: center;
width: 24px;
height: 24px;
padding: 0;
background: none;
border: 0;
cursor: pointer;
}
.contact-slider__dot::before {
content: '';
width: 10px;
height: 10px;
border-radius: 50%;
border: 1px solid var(--clr-glass-border-strong);
transition: background var(--transition), border-color var(--transition);
}
.contact-slider__dot[aria-current="true"]::before {
background: var(--clr-accent);
border-color: var(--clr-accent);
}
@keyframes contact-slide-fade {
from { opacity: 0; }
to { opacity: 1; }
}
.contact-slider--ready .contact-slider__slide.is-active {
animation: contact-slide-fade 0.4s ease;
}
.faq-contact__main .faq__list {
margin-top: 0;
}
.faq-contact__aside .person-card {
max-width: 320px;
margin-inline: auto;
}
/* Flacheres Foto im Kontakt-Block (Gesicht bleibt oben erhalten). */
.faq-contact__aside .person-card__media img {
aspect-ratio: 4 / 3;
}
@media (max-width: 900px) {
.faq-contact__inner {
grid-template-columns: 1fr;
gap: var(--space-3xl);
}
}
/* === team-photo (Mannschaftsfoto in voller Breite) === */
.team-photo__figure {
margin: 0;
}
.team-photo__img {
display: block;
width: 100%;
height: auto;
border-radius: var(--radius-card);
border: 1px solid var(--clr-glass-border);
}
.team-photo__caption {
margin-top: var(--space-xs);
text-align: center;
color: var(--clr-text-muted);
font-size: var(--fs-400);
}
/* === team-bento (Bild + Einleitung + Training + Spielort als Dashboard) === */
.team-bento {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-m);
grid-template-areas:
"about about about"
"train train klasse"
"venue venue venue";
}
.team-bento__about { grid-area: about; }
.team-bento__training { grid-area: train; }
.team-bento__klasse { grid-area: klasse; }
.team-bento__venue { grid-area: venue; }
.team-bento__about {
justify-content: center;
}
.team-bento__about > h2 {
margin-bottom: var(--space-xs);
}
.team-bento__about p {
color: var(--clr-text-muted);
max-width: 60ch;
}
/* Spielort: breite untere Kachel — Adresse links, Button rechts. */
.team-bento__venue {
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: var(--space-m);
}
.team-bento__venue-main {
position: relative;
z-index: 1;
}
.team-bento__venue .bento__heading {
margin-bottom: var(--space-2xs);
}
.team-bento__route {
position: relative;
z-index: 1;
flex: none;
}
@media (max-width: 900px) {
.team-bento {
grid-template-columns: 1fr;
grid-template-areas:
"about"
"train"
"klasse"
"venue";
}
}
/* === intro-bento (Jugend-Einleitung: Bild + Text + Spielort + Stat) === */
.intro-bento {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-m);
grid-template-areas:
"image about about"
"image venue stat";
}
.intro-bento__image {
grid-area: image;
position: relative;
min-height: 260px;
padding: 0;
overflow: hidden;
}
.intro-bento__img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center top;
}
.intro-bento__about {
grid-area: about;
justify-content: center;
}
.intro-bento__about > h2 {
margin-bottom: var(--space-xs);
}
.intro-bento__about p {
max-width: 60ch;
color: var(--clr-text-muted);
}
.intro-bento__venue {
grid-area: venue;
}
.intro-bento__venue .bento__address {
margin-bottom: var(--space-m);
}
.intro-bento__route {
position: relative;
z-index: 1;
align-self: start;
margin-top: auto;
}
.intro-bento__stat {
grid-area: stat;
}
@media (max-width: 900px) {
.intro-bento {
grid-template-columns: 1fr;
grid-template-areas:
"image"
"about"
"venue"
"stat";
}
.intro-bento__image {
aspect-ratio: 16 / 10;
min-height: 0;
}
}
/* === legal (Impressum, Datenschutz) ===
Schmale, gut lesbare Fließtext-Seite. Top-Padding klärt den absolut
positionierten Header (analog zur Hero-Logik). */
.legal {
padding-block: calc(var(--header-h) + 80px) var(--space-section);
}
.legal__head {
max-width: 60ch;
margin-bottom: clamp(var(--space-3xl), var(--space-l) + 3vw, var(--space-5xl));
}
.legal__kicker {
display: flex;
align-items: center;
gap: var(--space-xs);
margin-bottom: var(--space-m);
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-wider);
}
.legal__kicker::before {
content: '';
width: 3rem;
height: 4px;
background: var(--clr-accent);
border-radius: 2px;
}
.legal__lead {
margin-top: var(--space-m);
color: var(--clr-text-muted);
}
/* Lesespalte: angenehme Zeilenlänge für lange Rechtstexte */
.legal__body {
max-width: 72ch;
}
.legal__body > section + section {
margin-top: clamp(var(--space-3xl), var(--space-xl) + 2vw, var(--space-5xl));
}
.legal__body h2 {
font-size: var(--fs-700);
margin-bottom: var(--space-s);
}
/* Coolvetica nie unter --fs-650 (28px) — Unterüberschriften daher in Abel,
per Laufweite/Uppercase ausgezeichnet statt in der Display-Schrift. */
.legal__body h3 {
font-family: var(--ff-body);
font-size: var(--fs-600);
font-weight: var(--fw-bold);
text-transform: none;
line-height: var(--lh-body);
margin-top: var(--space-xl);
margin-bottom: var(--space-2xs);
}
.legal__body p,
.legal__body ul {
margin-bottom: var(--space-s);
}
.legal__body a {
color: var(--clr-text);
text-decoration: underline;
text-underline-offset: 0.2em;
}
.legal__body a:hover {
color: var(--clr-text-muted);
}
.legal__body ul {
padding-left: var(--space-m);
max-width: 70ch;
}
.legal__body li {
margin-bottom: var(--space-3xs);
}
.legal__body li::marker {
color: var(--clr-accent);
}
/* Adress-/Kontaktblöcke (Verantwortlicher, Bankverbindung) als abgesetzte Karte */
.legal__card {
margin-bottom: var(--space-s);
padding: clamp(var(--space-m), var(--space-s) + 1.5vw, var(--space-xl));
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.legal__card :last-child {
margin-bottom: 0;
}
.legal__card address {
font-style: normal;
line-height: var(--lh-body);
}
.legal__cards {
display: grid;
gap: var(--space-s);
margin-bottom: var(--space-s);
}
@media (min-width: 600px) {
.legal__cards--2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
/* === department-choice (Abteilungs-Auswahl Fußball | Turnen) === */
.department-choice > .container {
text-align: center;
}
.department-choice__intro {
max-width: 60ch;
margin: var(--space-s) auto 0;
}
.department-choice__grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-l);
margin: 0;
padding: 0;
list-style: none;
text-align: left;
}
@media (max-width: 600px) {
.department-choice__grid {
grid-template-columns: 1fr;
}
}
.department-choice__card {
display: flex;
flex-direction: column;
gap: var(--space-3xs);
height: 100%;
padding: clamp(var(--space-xl), var(--space-m) + 2vw, var(--space-4xl));
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.department-choice__heading {
font-size: var(--fs-700);
line-height: var(--lh-heading);
color: var(--clr-text);
}
.department-choice__subtitle {
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: var(--ls-wide);
color: var(--clr-accent);
}
.department-choice__text {
margin-top: var(--space-xs);
color: var(--clr-text-muted);
}
.department-choice__btn {
align-self: start;
margin-top: auto;
display: inline-flex;
align-items: center;
gap: var(--space-2xs);
}
.department-choice__arrow {
font-size: var(--icon-inline);
}
/* === fee-table (Beitragstabellen) === */
.fee-table {
padding: clamp(var(--space-m), var(--space-s) + 1.5vw, var(--space-xl));
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.fee-table__title {
font-size: var(--fs-650);
line-height: var(--lh-heading);
margin-bottom: var(--space-s);
}
.fee-table__list {
margin: 0;
}
.fee-table__row {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-s);
padding: var(--space-xs) 0;
border-bottom: 1px solid var(--clr-glass-border);
}
.fee-table__row:last-child {
border-bottom: 0;
}
.fee-table__label {
margin: 0;
}
.fee-table__price {
margin: 0;
flex: none;
font-family: var(--ff-heading);
font-size: var(--fs-650);
line-height: 1;
color: var(--clr-accent);
}
.fee-table__note {
margin-top: var(--space-s);
font-size: var(--fs-400);
color: var(--clr-text-muted);
}
/* Mehrere Beitragstabellen + Austritts-Hinweis gestapelt (Turn-Übersicht). */
.fee-stack {
display: flex;
flex-direction: column;
gap: var(--space-l);
margin-top: var(--space-l);
}
/* === membership (Mitglied werden) === */
.membership-signup__inner {
max-width: 720px;
margin-inline: auto;
}
/* Zentrierter, ruhiger Sektions-Kopf (einheitlich mit instagram/partners) */
.membership-signup__head {
max-width: 60ch;
margin: 0 auto var(--space-3xl);
text-align: center;
}
.membership-signup__intro {
margin-top: var(--space-s);
color: var(--clr-text-muted);
}
/* Eine einzige Karte: Beitragsinfo + Formular zusammen, durch Hairline getrennt. */
.membership-card {
padding: clamp(var(--space-l), var(--space-s) + 2.5vw, var(--space-3xl));
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
/* Verschachtelte Bausteine verlieren ihre eigene Karten-Optik (eine Karte, ein Rahmen). */
.membership-card .fee-table,
.membership-card .form {
max-width: none;
margin: 0;
padding: 0;
background: none;
border: 0;
border-radius: 0;
}
.membership-card .fee-table {
padding-bottom: var(--space-xl);
margin-bottom: var(--space-xl);
border-bottom: 1px solid var(--clr-glass-border);
}
/* Turnen-Hinweise: ruhige Liste, Icon links, dezente Hairline als Trenner. */
.membership-notes {
margin: 0 0 var(--space-3xl);
padding: 0;
list-style: none;
}
.membership-notes__item {
display: flex;
gap: var(--space-s);
padding: var(--space-m) 0;
border-bottom: 1px solid var(--clr-glass-border);
}
.membership-notes__item:first-child {
padding-top: 0;
}
.membership-notes__item:last-child {
padding-bottom: 0;
border-bottom: 0;
}
.membership-notes__icon {
flex: none;
margin-top: var(--space-4xs);
font-size: var(--icon-l);
line-height: 1;
color: var(--clr-accent);
}
.membership-notes__title {
font-size: var(--fs-650);
line-height: var(--lh-heading);
margin-bottom: var(--space-3xs);
}
.membership-notes__body p {
color: var(--clr-text-muted);
}
/* Download-Block: alles sauber mittig, Texte in lesbarer Breite. */
.membership-download {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-xs);
text-align: center;
}
.membership-download__btn {
display: inline-flex;
align-items: center;
gap: var(--space-2xs);
}
.membership-download__icon {
font-size: var(--icon-inline);
}
.membership-download__hint,
.membership-download__contact {
margin: 0;
max-width: 48ch;
font-size: var(--fs-400);
color: var(--clr-text-muted);
}
.legal__muted {
color: var(--clr-text-muted);
}
/* === facility (Gelände / Drohnen-Luftbild auf der Vereinsseite) === */
.facility > .container {
text-align: center;
}
.facility__lead {
max-width: 70ch;
margin-top: var(--space-s);
margin-inline: auto;
color: var(--clr-text-muted);
}
.facility__figure {
margin: var(--space-3xl) 0 0;
}
.facility__img {
display: block;
width: 100%;
height: auto;
border-radius: var(--radius-card);
box-shadow: var(--shadow-card);
}
.facility__caption {
margin-top: var(--space-xs);
color: var(--clr-text-faint);
font-size: var(--fs-500);
}
.facility__actions {
margin-top: var(--space-xl);
}
/* === matchcenter === */
/* Vereinswappen — gemeinsam für Karten und Tabelle; fehlt das Bild, rendert die
Komponente einen Initialen-Kreis (.crest--initials) statt eines kaputten <img>. */
/* Weißes Chip hält auch helle/weiße Logos auf dunklem Grund sichtbar. */
/* Größe läuft über --crest-size: Kontexte setzen nur diese eine Variable, Breite,
Höhe und die Initialen-Schriftgröße folgen daraus. .crest--initials trägt immer
auch .crest, deshalb genügt überall der Basis-Selektor. */
.crest {
--crest-size: 2.25rem;
box-sizing: border-box;
flex: none;
width: var(--crest-size);
height: var(--crest-size);
padding: 3px;
object-fit: contain;
background: #fff;
border-radius: 50%;
}
.crest--initials {
display: inline-grid;
place-items: center;
padding: 0;
font-family: var(--ff-body);
/* Initialen als Anteil des Durchmessers statt als eigene Stufe der Typo-Skala:
so bleibt der Kreis in jeder Größe gleich proportioniert, und es entstehen
keine Mini-Schriftgrößen unterhalb von --fs-300. */
font-size: calc(var(--crest-size) * 0.4);
font-weight: var(--fw-bold);
line-height: 1;
color: var(--clr-text-muted);
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: 50%;
}
/* Aufmacher des „Nächste Spiele"-Bands: strukturgleich mit .match-row (Heim über
Gast, linksbündig), nur groß — ein Bauprinzip für das ganze Band. Bewusst ohne
eigene Fläche, ohne Badges und ohne Icons: die Wirkung kommt aus der Größe.
Drei Schriftrollen — Meta (Abel gesperrt) · Namen (Coolvetica) · Anstoß (Abel). */
.match-feature {
display: flex;
flex-direction: column;
gap: clamp(var(--space-s), var(--space-xs) + 0.6vw, var(--space-l));
}
.match-feature__meta {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 0.5em;
font-size: var(--fs-400);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
}
.match-feature__sep {
color: var(--clr-text-faint);
}
.match-feature__fixture {
display: flex;
flex-direction: column;
gap: var(--space-2xs);
}
.match-feature__side {
display: flex;
align-items: center;
gap: clamp(var(--space-2xs), var(--space-2xs) + 0.6vw, var(--space-s));
min-width: 0; /* lange Vereinsnamen dürfen umbrechen statt zu überlaufen */
}
.match-feature .crest {
--crest-size: clamp(2.25rem, 1.6rem + 2vw, 3rem);
}
/* Die Vereinsnamen sind das einzige Coolvetica-Element („wer"), alles Beschreibende
bleibt Abel („wann/was"). Coolvetica hat nur einen Schnitt — die eigene Mannschaft
wird deshalb über Helligkeit markiert, nicht über fett (kein Fake-Bold). */
.match-feature__club {
font-family: var(--ff-heading);
font-size: var(--fs-700);
line-height: var(--lh-heading);
text-transform: uppercase;
color: var(--clr-text-muted);
overflow-wrap: anywhere;
}
.match-feature__side.is-own .match-feature__club {
color: var(--clr-text);
}
.match-feature__when {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 0.5em;
font-size: var(--fs-600);
}
/* Band „Nächste Spiele" — abgesetzte Fläche (.section--sunken) mit roter Oberkante,
damit der Bereich nicht als Hero-Überhang gelesen wird. */
.next-matches {
border-top: 2px solid var(--clr-accent);
}
.next-matches__grid {
display: grid;
/* Der Aufmacher trägt mehr Gewicht als die Terminliste. */
grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
align-items: start;
gap: clamp(var(--space-m), var(--space-s) + 1.5vw, var(--space-3xl));
margin-top: clamp(var(--space-l), var(--space-m) + 1vw, var(--space-3xl));
}
.next-matches__list-title {
margin-bottom: var(--space-xs);
/* Coolvetica wäre in dieser Größe unleserlich — Abel mit Sperrung (CLAUDE.md). */
font-family: var(--ff-body);
font-size: var(--fs-400);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-muted);
}
@media (max-width: 992px) {
.next-matches__grid {
grid-template-columns: 1fr;
}
}
/* Pro-Mannschaft-Sektion: Kopf mit Name/Liga + Link zur Mannschaftsseite. */
.matchcenter-team__head {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: var(--space-s);
margin-bottom: var(--space-l);
}
.matchcenter-team__league {
display: inline-flex;
align-items: center;
gap: 0.4em;
margin-top: var(--space-3xs);
color: var(--clr-text-muted);
}
/* Saison-Umschalter: wiederverwendete Stripe-Tabbar (group-tabs__bar/__tab), aber
linksbündig und etwas kompakter als bei den Gruppen-Tabs. Ohne JS sind beide
Panels gestapelt sichtbar (group-tabs.js versteckt erst on init das zweite). */
.matchcenter-team__seasons-bar {
justify-content: flex-start;
margin-bottom: var(--space-m);
}
/* display-neutrales Panel (kein group-tabs__panel-Grid) — das innere
matchcenter-team__grid bringt sein eigenes Layout mit. */
.matchcenter-team__season-panel[hidden] {
display: none;
}
.matchcenter-team__empty {
margin: 0;
color: var(--clr-text-muted);
}
/* kicker-Layout: Tabelle 2/3 links, Spiele 1/3 rechts; gestapelt auf Mobil.
align-items:start + 0-Margins der Karten → beide Spalten starten oben bündig. */
.matchcenter-team__grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: clamp(var(--space-l), var(--space-s) + 2vw, var(--space-4xl));
align-items: start;
}
@media (max-width: 992px) {
.matchcenter-team__grid {
grid-template-columns: 1fr;
}
}
/* min-width:0 erlaubt der Tabellenspalte, schmaler als die min-width:520 der
Tabelle zu werden — sonst schiebt die Tabelle die ganze Seite in den
horizontalen Scroll, statt selbst in ihrer Karte zu scrollen. */
.matchcenter-team__grid > * {
min-width: 0;
}
/* Mehrere Listen (Nächste Spiele / Letzte Ergebnisse) gleichmäßig gestapelt.
max-width hält die kompakten Zeilen gestapelt (≤992px) lesbar schmal, statt sie
über die volle Breite zu ziehen; im 2-spaltigen Desktop greift es nicht (die
1fr-Spalte ist ohnehin schmaler). */
.matchcenter-team__aside {
display: flex;
flex-direction: column;
gap: var(--space-s);
max-width: 30rem;
}
/* Kompakte Spielliste (Seitenspalte) — gleiche Karten-Optik wie die Tabelle. */
.match-list {
margin: 0;
padding: 0;
list-style: none;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
/* Im „Nächste Spiele"-Band trägt die Terminliste keine Kartenfläche — sonst stünde
ein gerahmter Block neben dem flächenlosen Aufmacher. Die Trennlinien der Zeilen
reichen; in den Mannschafts-Sektionen bleibt .match-list die Karte.
Zwei Klassen nötig: die Glas-Registry am Dateiende setzt .match-list den
box-shadow und würde einen Ein-Klassen-Selektor sonst überschreiben. */
.match-list.match-list--plain {
background: none;
border: 0;
border-radius: 0;
box-shadow: none;
}
.match-list--plain .match-row__link {
padding-inline: 0;
}
.match-row {
border-bottom: 1px solid var(--clr-glass-border);
}
.match-row:last-child {
border-bottom: 0;
}
/* Raster und Innenabstand liegen im Wrapper: ist die Zeile ein Link, ist damit
die komplette Zeilenfläche klickbar — ohne Link sieht nichts anders aus. */
.match-row__link {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
column-gap: var(--space-xs);
padding: var(--space-xs) var(--space-s);
color: inherit;
text-decoration: none;
}
a.match-row__link:hover {
background: rgb(255 255 255 / 0.06);
}
.match-row__head {
grid-column: 1 / -1;
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: var(--space-2xs);
margin-bottom: var(--space-2xs);
}
.match-row__date {
font-size: var(--fs-300);
color: var(--clr-text-muted);
}
.match-row__meta {
font-size: var(--fs-300);
text-transform: uppercase;
letter-spacing: var(--ls-caps);
color: var(--clr-text-faint);
}
.match-row__teams {
display: flex;
flex-direction: column;
gap: var(--space-3xs);
min-width: 0; /* erlaubt Ellipsis in den Namen */
}
.match-row__team {
display: flex;
align-items: center;
gap: var(--space-2xs);
min-width: 0;
}
.match-row__team .crest {
--crest-size: 1.6rem;
}
.match-row__name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: var(--fs-400);
}
.match-row__team.is-own .match-row__name {
font-weight: var(--fw-bold);
color: var(--clr-text);
}
.match-row__outcome {
align-self: center;
}
.match-row__score {
font-family: var(--ff-heading);
font-size: var(--fs-650);
line-height: 1;
white-space: nowrap;
}
.match-row__time {
font-size: var(--fs-400);
color: var(--clr-text-muted);
white-space: nowrap;
}
/* Liga-Tabelle: horizontal scrollbar (fokussierbare Region) auf schmalen Screens. */
.table-scroll {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
/* Ruhender Rahmen um den Scroller: trägt den Wisch-Hinweis (Fade am rechten
Rand), der nicht mitscrollen darf. Nur auf Breiten sichtbar, wo die Tabelle
(min-width 520px) tatsächlich überläuft. */
.table-scroll-frame {
position: relative;
}
@media (max-width: 620px) {
.table-scroll-frame::after {
content: '';
position: absolute;
inset: 1px 1px 1px auto;
width: 32px;
border-radius: 0 var(--radius-card) var(--radius-card) 0;
background: linear-gradient(90deg, transparent, rgb(0 0 0 / 0.55));
pointer-events: none;
}
}
.table-scroll:focus-visible {
outline: 2px solid var(--clr-text);
outline-offset: 2px;
}
.league-table {
width: 100%;
min-width: 520px;
border-collapse: collapse;
background: var(--clr-glass-bg);
font-size: var(--fs-400);
}
.league-table th,
.league-table td {
padding: var(--space-2xs) var(--space-2xs);
text-align: center;
border-bottom: 1px solid var(--clr-glass-border);
}
.league-table tbody tr:last-child th,
.league-table tbody tr:last-child td {
border-bottom: 0;
}
/* Spaltenköpfe in Abel (Coolvetica wäre hier zu klein, < 28px). */
.league-table thead th {
font-family: var(--ff-body);
font-weight: var(--fw-bold);
font-size: var(--fs-300);
text-transform: uppercase;
letter-spacing: var(--ls-tight);
color: var(--clr-text-muted);
white-space: nowrap;
}
.league-table thead th abbr {
text-decoration: none;
}
.league-table__rank {
width: 2.75rem;
border-left: 3px solid transparent;
color: var(--clr-text-muted);
}
/* Vereinsspalte (Kopf + Zellen) linksbündig — höhere Spezifität als .league-table th. */
.league-table .league-table__club {
text-align: left;
}
.league-table tbody th.league-table__club {
display: flex;
align-items: center;
gap: var(--space-2xs);
min-width: 0; /* erlaubt Ellipsis im Namen */
font-weight: var(--fw-regular);
}
.league-table tbody .crest {
--crest-size: 1.75rem;
}
/* Lange Vereinsnamen sauber kürzen (voller Name im title-Attribut). */
.league-table__name {
min-width: 0;
overflow: hidden;
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
}
.league-table__pts {
font-weight: var(--fw-bold);
color: var(--clr-text);
}
/* Eigene Vereinszeile hervorheben (rote Tönung hinter weißem Text). */
.league-table tbody tr.is-own {
background: rgb(var(--clr-accent-rgb) / 0.16);
}
.league-table tbody tr.is-own th,
.league-table tbody tr.is-own td {
font-weight: var(--fw-bold);
color: var(--clr-text);
}
/* Auf-/Abstiegszonen: farbiger linker Rand am Rang. */
.league-table tbody tr.zone-promotion .league-table__rank {
border-left-color: var(--clr-success);
}
.league-table tbody tr.zone-promotion-playoff .league-table__rank {
border-left-color: color-mix(in srgb, var(--clr-success) 60%, var(--clr-text-faint));
}
.league-table tbody tr.zone-relegation-playoff .league-table__rank {
border-left-color: color-mix(in srgb, var(--clr-error) 60%, var(--clr-text-faint));
}
.league-table tbody tr.zone-relegation .league-table__rank {
border-left-color: var(--clr-error);
}
/* Hinweis über der Tabelle, solange die Liga noch keinen Spieltag gewertet hat. */
.league-table__note {
margin-bottom: var(--space-xs);
font-size: var(--fs-400);
color: var(--clr-text-muted);
}
.league-table__legend {
display: flex;
flex-wrap: wrap;
gap: var(--space-2xs) var(--space-m);
margin: var(--space-xs) 0 0;
padding: 0;
list-style: none;
font-size: var(--fs-300);
color: var(--clr-text-muted);
}
.league-table__legend-item {
display: inline-flex;
align-items: center;
gap: 0.45em;
}
.league-table__legend-item::before {
content: "";
width: 0.85rem;
height: 0.85rem;
border-radius: 3px;
background: var(--clr-text-faint);
}
.league-table__legend-item.zone-promotion::before {
background: var(--clr-success);
}
.league-table__legend-item.zone-promotion-playoff::before {
background: color-mix(in srgb, var(--clr-success) 60%, var(--clr-text-faint));
}
.league-table__legend-item.zone-relegation-playoff::before {
background: color-mix(in srgb, var(--clr-error) 60%, var(--clr-text-faint));
}
.league-table__legend-item.zone-relegation::before {
background: var(--clr-error);
}
/* Fallback ohne Cache. */
.matchcenter-empty {
max-width: 540px;
margin-inline: auto;
padding: clamp(var(--space-l), var(--space-s) + 2vw, var(--space-3xl));
text-align: center;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.matchcenter-empty__icon {
font-size: var(--icon-xl);
color: var(--clr-accent);
}
.matchcenter-empty p {
margin-top: var(--space-xs);
color: var(--clr-text-muted);
}
.matchcenter-empty__actions {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--space-xs);
margin-top: var(--space-l);
}
/* === sportheim === */
/* Bento: großes Foto links (2 Spalten × 2 Zeilen),
kleines Foto + roter CTA oben rechts, Karte + Adresse unten rechts */
.sportheim-bento {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 220px;
gap: var(--space-m);
grid-template-areas:
"p1 p1 p2 cta"
"p1 p1 map adr";
}
/* --- Foto-Kacheln --- */
.sportheim-bento__photo {
position: relative;
overflow: hidden;
border-radius: var(--radius-card);
}
.sportheim-bento__photo img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 600ms ease;
}
.sportheim-bento__photo:hover img {
transform: scale(1.04);
}
.sportheim-bento__photo--main { grid-area: p1; }
.sportheim-bento__photo--sec { grid-area: p2; }
/* --- Karten-Kachel --- */
.sportheim-bento__map {
grid-area: map;
position: relative;
overflow: hidden;
border-radius: var(--radius-card);
}
.sportheim-bento__map img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* --- Adress-Kachel --- */
.sportheim-bento__addr {
grid-area: adr;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
padding: var(--space-l);
display: flex;
flex-direction: column;
justify-content: center;
font-style: normal;
}
.sportheim-bento__addr-label {
font-size: var(--fs-300);
font-weight: var(--fw-bold);
letter-spacing: var(--ls-wide);
text-transform: uppercase;
color: var(--clr-text-muted);
margin: 0 0 var(--space-xs);
}
.sportheim-bento__addr-text {
font-size: var(--fs-500);
line-height: 1.6;
margin: 0;
}
/* --- CTA-Kachel (rot, volle Höhe) --- */
.sportheim-bento__cta {
grid-area: cta;
background: var(--clr-accent);
border-radius: var(--radius-card);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: var(--space-l);
text-align: center;
padding: var(--space-2xl) var(--space-m);
}
.sportheim-bento__cta-title {
font-family: var(--ff-heading);
font-size: var(--fs-650);
text-transform: uppercase;
line-height: var(--lh-heading);
color: #fff;
margin: 0;
}
/* Tablet: 2-spaltig, Foto groß oben, darunter Kleinzeug */
@media (max-width: 900px) {
.sportheim-bento {
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 200px;
grid-template-areas:
"p1 p1"
"p1 p1"
"p2 cta"
"map adr";
}
}
/* Mobile: alles gestapelt */
@media (max-width: 500px) {
.sportheim-bento {
grid-template-columns: 1fr;
grid-auto-rows: 220px;
grid-template-areas:
"p1"
"p2"
"map"
"cta"
"adr";
}
.sportheim-bento__addr,
.sportheim-bento__cta {
grid-row: auto;
height: auto;
min-height: 140px;
}
}
/* ============================================================
FROSTED GLASS — globaler Look für alle Glas-Oberflächen.
EINZIGE Stelle für Blur + Ruhe-Glow (DRY statt 28× wiederholt).
Neue Glas-Karte? Hier zur passenden Liste ergänzen:
• Leaf = eigenständige Karte → bekommt Blur + Glow
• Container = umschließt selbst Glas-Karten → nur Glow
(kein Blur, sonst Doppel-Frost bei verschachtelten Karten)
Bewusst ausgenommen: Form-Inputs, Wappen-Initialen, Banner-/Slider-Controls.
Glas-Bg/-Border kommen weiterhin aus den Komponenten (var(--clr-glass-*)).
============================================================ */
/* Ruhe-Glow + Top-Sheen für ALLE Glas-Flächen (Leaf + Container).
Hover-Lift bleibt pro Komponente erhalten (:hover hat höhere Spezifität). */
.instagram__fallback,
.sponsor-channels__card,
.person-card,
.position-card,
.partners__item,
.key-facts__item,
.bento__tile,
.group-card,
.group-tabs__panel,
.age-group,
.match-list,
.matchcenter-empty,
.roster-card,
.team-card,
.department-choice__card,
.legal__card,
.fee-table,
.league-table,
.membership-card,
.sportheim-bento__addr,
.form {
box-shadow: var(--glass-shadow);
}
/* Echtes Frosted-Glass-Blur nur auf Leaf-Karten — Container (.match-list,
.group-tabs__panel, .age-group, Tabellen) bleiben blur-frei, damit darin
liegende Glas-Karten nicht doppelt verschwimmen. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
.instagram__fallback,
.sponsor-channels__card,
.person-card,
.position-card,
.partners__item,
.key-facts__item,
.bento__tile,
.group-card,
.matchcenter-empty,
.roster-card,
.team-card,
.department-choice__card,
.legal__card,
.membership-card,
.sportheim-bento__addr,
.form {
-webkit-backdrop-filter: var(--glass-blur);
backdrop-filter: var(--glass-blur);
}
}