Damit die Abteilungen das Wappen selbst holen können, statt jedes Mal zu fragen: drei Varianten (farbig, einfarbig schwarz, einfarbig weiß) in SVG, PDF, PNG und JPG, dazu ein ZIP über alles und die Vereinsfarben. Verlinkt nur in der Fußzeile. Bisher lag das Logo genau einmal im Projekt, als eine einzige SVG. Es gab kein PNG, kein JPG, kein PDF und keine einfarbige Fassung. bin/logo-build.php erzeugt alle Dateien aus einer Master-SVG unter storage/logo-quellen/. Gerastert wird mit headless Chrome, weil GD kein SVG lesen kann und weder Inkscape noch rsvg-convert noch ImageMagick verfügbar sind; das PDF ist dabei echter Vektor. Das Skript läuft einmalig lokal, nichts davon im Request-Pfad. bin/preflight.php meldet als Fehler, wenn eine Download-Datei fehlt: die Komponente ließe den Knopf sonst still weg. Die beiden einfarbigen Fassungen sind exakte Negative voneinander, nur Linien, alle Flächen frei. EPS gibt es bewusst nicht, dafür fehlt jedes Werkzeug; SVG und PDF decken die Druckereien ab. Frühere Vereinslogos sind vorbereitet, aber im Projekt liegt bisher kein einziges historisches Wappen vor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J9mubC8gtpjtJntbhSJBRS
188 lines
12 KiB
CSS
188 lines
12 KiB
CSS
/* ============================================================
|
||
DESIGN-TOKENS — EINZIGE Quelle für Farben, Typo, Spacing etc.
|
||
Werte extrahiert und verifiziert aus der alten Seite
|
||
(CSS bc-style + DB main_layout). Siehe CLAUDE.md.
|
||
============================================================ */
|
||
:root {
|
||
/* --- Farben --- */
|
||
--clr-accent: #e20612; /* Marken-Rot (alte DB: primary_accent) */
|
||
--clr-accent-dark: #b00510; /* Hover/Active auf Rot */
|
||
--clr-accent-rgb: 226 6 18; /* für rgb(var(--clr-accent-rgb) / α) */
|
||
--clr-accent-hsl: 356.7 94.8% 45.5%; /* dasselbe Rot als H S L */
|
||
--clr-accent-h: 356.7; /* nur der Farbton — die Dateiablage (/dateien)
|
||
leitet daraus ihre Flächen ab, siehe dateien.css */
|
||
/* Akzentfarben einzelner Werbe-Banner (Sponsor-CI statt Vereins-Rot).
|
||
Sie stehen hier und nicht in data/banners.json, weil ein Hex-Wert aus der JSON
|
||
nur per Inline-Style in die Seite käme — und den verwirft die CSP
|
||
(default-src 'self', kein style-src). Die JSON nennt nur den Namen
|
||
("accent": "breadcrumb"), components.css bildet ihn auf dieses Token ab.
|
||
Neuer Sponsor mit eigener CI = eine Zeile hier plus eine Klasse dort. */
|
||
--clr-banner-accent-breadcrumb: #6cbbbc;
|
||
|
||
--clr-bg: #222222; /* Grund-Hintergrund (mit Textur) */
|
||
--clr-bg-deep: #161616; /* abgesetzte Sektionen */
|
||
--clr-bg-footer: #000000;
|
||
--clr-bg-corporate: #383838; /* Scrollbar-Thumb */
|
||
--clr-checker-a: #dcdcdc; /* Karomuster hinter freigestellten Logos (/logo):
|
||
zeigt, dass der Grund frei ist. Bewusst hell,
|
||
damit die schwarzen Konturen des Wappens tragen. */
|
||
--clr-checker-b: #f2f2f2;
|
||
--clr-text: #ffffff;
|
||
--clr-text-muted: #b3b3b3; /* 7.7:1 auf --clr-bg */
|
||
--clr-text-faint: #8c8c8c; /* 4.5:1 auf --clr-bg (AA) */
|
||
--clr-sepia-bg: #f3efe4; /* Timeline-Museumsrahmen (Foto-Mount) */
|
||
--clr-logo-card: #ffffff; /* Partner-Logowall: Farb-Logos brauchen neutralen weißen Grund */
|
||
--clr-photo-frame: #faf9f6; /* Polaroid-Rahmen (split--polaroid): fast reinweiß, minimal warm */
|
||
--clr-tape: rgb(255 250 235 / 0.4); /* Klebestreifen auf Polaroids: milchig, leicht vergilbt */
|
||
--clr-sepia-text: #3a372f; /* Timeline-Text auf hellem Sepia-Grund */
|
||
--clr-glass-bg: rgb(0 0 0 / 0.22); /* dunkles Glas (dunkler als der Grund) */
|
||
--clr-glass-border: rgb(255 255 255 / 0.14); /* sehr dezenter Card-Rand — Glow/Sheen tragen die Kontur */
|
||
--clr-glass-border-strong: rgb(255 255 255 / 0.45); /* Back-to-Top, position-/group-card etc.: ≥3:1 (WCAG 1.4.11) */
|
||
--clr-field-bg: rgb(255 255 255 / 0.07); /* Formularfelder: sanfte Füllfläche (etwas heller als das Glas) */
|
||
--clr-field-bg-solid: #313131; /* dieselbe Fläche, aber OPAK (--clr-field-bg über --clr-bg gerechnet) —
|
||
nötig für den Autofill-Fix (box-shadow inset kann keine Transparenz
|
||
über die native Browser-Füllung legen, siehe components.css) */
|
||
--clr-field-border: rgb(255 255 255 / 0.22); /* Feld-Rand weich — Fläche + Rand machen das Feld erkennbar */
|
||
--clr-field-border-hover: rgb(255 255 255 / 0.4); /* Feld-Hover: dezent */
|
||
--clr-lightbox-bg: rgb(0 0 0 / 0.93); /* Bild-Großansicht (lightbox): fast schwarz, damit das Foto
|
||
allein wirkt und der Seitenhintergrund nicht durchdrückt */
|
||
--clr-error: #ff8a8a; /* Formularfehler, lesbar auf dunkel */
|
||
--clr-success: #8ce99a;
|
||
|
||
/* --- Typografie --- */
|
||
--ff-heading: 'Coolvetica', 'Arial Narrow', system-ui, sans-serif;
|
||
--ff-body: 'Abel', 'Helvetica Neue', system-ui, sans-serif;
|
||
--ff-serif: 'PT Serif', Georgia, 'Times New Roman', serif; /* nur Stadionzeitung-Vorwort-Fließtext */
|
||
--ff-signature: 'Mr Dafoe', cursive; /* nur Unterschrift des Vorwort-Unterzeichners (Stadionzeitung) */
|
||
--fs-300: 0.8125rem; /* 13px Buttons klein */
|
||
--fs-400: 0.9375rem; /* 15px Footer, Meta */
|
||
--fs-500: 1.125rem; /* 18px Navigation */
|
||
--fs-550: clamp(1.25rem, 0.95rem + 1.3vw, 1.75rem); /* 20–28px fluider Lead/Tagline */
|
||
--fs-600: 1.3125rem; /* 21px Body */
|
||
--fs-650: 1.75rem; /* 28px Zwischengröße (z.B. Footer-Headings) */
|
||
--fs-675: 2.125rem; /* 34px Header-Wortmarke */
|
||
--fs-690: clamp(2rem, 1.5rem + 1.6vw, 2.75rem); /* 32–44px Karten-/Kachel-Überschrift */
|
||
--fs-700: clamp(2rem, 1.2rem + 3.5vw, 3.125rem); /* 50px h3 */
|
||
/* Mobil-Minima bewusst hoch: Coolvetica Condensed wirkt bei gleicher
|
||
nomineller Größe deutlich kleiner als normale Schnitte. */
|
||
--fs-800: clamp(2.625rem, 1.3rem + 4.5vw, 3.75rem); /* 42–60px h2 */
|
||
--fs-900: clamp(3.5rem, 1.75rem + 5.5vw, 6rem); /* 56–96px h1 */
|
||
--fs-1000: clamp(3.5rem, 2rem + 7.5vw, 7.5rem); /* 56–120px Display-Hero (nur Startseite) */
|
||
--fs-deco: 9rem; /* dekorative Ziffer hinter Bento-Kacheln */
|
||
--lh-heading: 0.9;
|
||
--lh-body: 1.5;
|
||
--fw-regular: 400;
|
||
--fw-bold: 700;
|
||
/* Sperrung. Coolvetica ist Condensed und hat nur einen Schnitt: unter 28px
|
||
wird es in Uppercase unleserlich (siehe CLAUDE.md). Kleinere Auszeichnungen
|
||
laufen deshalb über --ff-body + uppercase + --ls-caps statt --ff-heading. */
|
||
--ls-heading: 0.012em; /* Coolvetica-Überschriften unter ~40px: nur ein Hauch Luft
|
||
zwischen den Versalien (0,4px bei 34px). Der Schnitt ist
|
||
condensed, ohne Sperrung kleben die Buchstaben — mit
|
||
--ls-caps (0.08em) wirkt eine Überschrift dagegen
|
||
auseinandergezogen. Nicht für kleine Labels, dafür
|
||
--ls-caps/--ls-wide. */
|
||
--ls-tight: 0.03em; /* dezente Straffung in Fließtext-Größen */
|
||
--ls-caps: 0.08em; /* Standard für gesperrte Uppercase-Auszeichnungen */
|
||
--ls-wide: 0.12em; /* kleine Labels, Meta-Zeilen */
|
||
--ls-wider: 0.18em; /* sehr kleine Kicker/Overlines */
|
||
|
||
/* --- Icon-Größen ---
|
||
Der icon()-Helper rendert 1em, die font-size steuert also die Icon-Größe.
|
||
rem-Stufen für eigenständige Icons, em-Stufen für Icons, die im Textfluss
|
||
mit ihrer Zeile mitwachsen sollen (Chevrons, Pfeile). */
|
||
--icon-s: 1rem; /* 16px */
|
||
--icon-m: 1.25rem; /* 20px */
|
||
--icon-l: 1.5rem; /* 24px */
|
||
--icon-xl: 2.5rem; /* 40px */
|
||
--icon-inline-sm: 0.75em;
|
||
--icon-inline: 0.9em;
|
||
--icon-inline-lg: 1.25em;
|
||
|
||
/* --- Spacing ---
|
||
4px-Raster. EINZIGE Quelle für padding/margin/gap — keine rohen rem-Werte
|
||
mehr in den anderen CSS-Dateien. Stufen wurden aus dem Ist-Bestand
|
||
geclustert, die häufigsten Werte treffen exakt (--space-s ist mit Abstand
|
||
der meistgenutzte). Nach oben wird das Raster gröber, weil große Abstände
|
||
das vertragen. --space-4xs (2px) ist ausschließlich für optische
|
||
Korrekturen gedacht (Icon-/Baseline-Nudges), nicht für Layout. */
|
||
/* Karten-Innenabstände. Fluid statt fest, damit auf schmalen Handys nicht ein
|
||
Viertel der Bildschirmbreite in gestapelten Innenabständen verschwindet
|
||
(gemessen bei 309px: Container 11,5 + Karte 32 je Seite → nur 71% der Breite
|
||
blieben für das Eingabefeld). Ein harter Breakpoint bei ~310px wäre die
|
||
Alternative gewesen, sieht aber bei 311px wieder falsch aus.
|
||
Die OBERGRENZEN entsprechen genau den bisherigen festen Werten, am Desktop
|
||
ändert sich also nichts — es wird nur nach unten schmaler.
|
||
Vier Karten (fee-table, membership-card, legal__card, matchcenter-empty)
|
||
hatten diese clamp()-Formeln schon einzeln stehen; sie behalten ihre eigenen
|
||
Werte, damit ihr Desktop-Bild unangetastet bleibt. Sie hier einzusammeln ist
|
||
eine Aufräumung für später. */
|
||
--pad-card: clamp(var(--space-m), var(--space-s) + 1.5vw, var(--space-2xl)); /* 20…32px */
|
||
--pad-card-lg: clamp(var(--space-l), var(--space-s) + 2.5vw, var(--space-3xl)); /* 24…40px */
|
||
|
||
--space-4xs: 0.125rem; /* 2px */
|
||
--space-3xs: 0.25rem; /* 4px */
|
||
--space-2xs: 0.5rem; /* 8px */
|
||
--space-xs: 0.75rem; /* 12px */
|
||
--space-s: 1rem; /* 16px */
|
||
--space-m: 1.25rem; /* 20px */
|
||
--space-l: 1.5rem; /* 24px */
|
||
--space-xl: 1.75rem; /* 28px */
|
||
--space-2xl: 2rem; /* 32px */
|
||
--space-3xl: 2.5rem; /* 40px */
|
||
--space-4xl: 3rem; /* 48px */
|
||
--space-5xl: 4rem; /* 64px */
|
||
--space-6xl: 5rem; /* 80px */
|
||
--space-7xl: 7rem; /* 112px */
|
||
|
||
/* --- Buttons --- */
|
||
--btn-font: 1rem; /* 16px – Default (moderat) */
|
||
--btn-font-sm: var(--fs-300); /* 13px – dezente Buttons */
|
||
--btn-font-lg: var(--fs-500); /* 18px – Hero-CTAs */
|
||
--btn-pad-y: 0.625em; /* skaliert mit font-size */
|
||
--btn-pad-x: 1.25em;
|
||
--btn-line: 1.2;
|
||
|
||
/* --- Interaktion --- */
|
||
/* Mindest-Trefferfläche (WCAG 2.5.5 AAA). Controls, die optisch kleiner
|
||
bleiben sollen, strecken ihre Hit-Area per .tap-target auf diesen Wert —
|
||
gewertet wird die Trefferfläche, nicht die sichtbare Fläche. */
|
||
--tap-min: 44px;
|
||
/* Fokus immer weiß: 15,9:1 auf --clr-bg. Rot käme nur auf 3,2:1 und würde
|
||
WCAG 1.4.11 gerade so schaffen — als einziger Fokus-Indikator zu knapp. */
|
||
--focus-ring: 2px solid var(--clr-text);
|
||
--focus-offset: 3px;
|
||
|
||
/* --- Form & Tiefe --- */
|
||
--radius-btn: 8px;
|
||
--radius-card: 15px;
|
||
--radius-photo: 4px; /* Polaroid-/Fotorahmen (split--polaroid): fast eckig wie ein echter Abzug */
|
||
--shadow: 0 0 14px rgb(0 0 0 / 0.15);
|
||
--shadow-card: 0 14px 38px rgb(0 0 0 / 0.42), inset 0 1px 0 rgb(255 255 255 / 0.18); /* Hover-Lift + Top-Sheen */
|
||
|
||
/* --- Glas-Oberflächen (Frosted Glass) — siehe „Frosted Glass"-Block in components.css --- */
|
||
--glass-blur: blur(13px) saturate(1.4);
|
||
--glass-shadow: 0 6px 22px rgb(0 0 0 / 0.30), inset 0 1px 0 rgb(255 255 255 / 0.15); /* Ruhe-Glow + Top-Sheen */
|
||
|
||
/* --- Layout --- */
|
||
--container-max: 1200px;
|
||
--container-pad: var(--space-s);
|
||
--space-section: var(--space-6xl);
|
||
--header-h: 60px; /* Mindesthöhe der Kopfleiste (.site-header__inner) */
|
||
--logo-h: 72px; /* Logo — größer als --header-h, bestimmt also faktisch die Höhe */
|
||
--header-top: 20px; /* Versatz der Leiste von oben (.site-header) */
|
||
/* Was die Kopfleiste vom Seitenanfang wegnimmt. NICHT --header-h dafür
|
||
nehmen: die Leiste ist wegen des Logos 72px hoch, nicht 60px, und sitzt
|
||
zusätzlich 20px versetzt — wer mit --header-h rechnet, landet 32px zu
|
||
hoch und schiebt seinen Inhalt unter das Logo. Abgeleitet statt fest,
|
||
damit es nicht auseinanderläuft, wenn Logo oder Versatz sich ändern. */
|
||
--header-space: calc(var(--header-top) + var(--logo-h));
|
||
|
||
/* --- Bewegung --- */
|
||
--transition: 300ms ease;
|
||
}
|
||
|
||
/* Breakpoints (Referenz — Custom Properties funktionieren nicht in Media Queries,
|
||
Werte müssen in den CSS-Dateien synchron gehalten werden):
|
||
1249px Burger-Menü | 1024px | 992px | 768px | 600px | 500px */
|