Stadionzeitung, Veranstaltungen, News-Artikel, Lightbox und Anzeigen-Verteilung
Stadionzeitung: Live-Seiten (Tabellen, Ergebnisse, Vorschau, Termine, News, Kontakt, Historie, Sportheim, Partner, Momente, Impressum), automatisches Cover, Swipe-Viewer mit Vollbildmodus und die Druckfassung als Falt-Heft. Anzeigen kommen jetzt aus dem Bestand und werden gleichmäßig verteilt, nie mehr als zwei hintereinander (vorher vier Blöcke à fünf). Die Doppelseiten-Regel rechnet das Skript selbst, statt sie von Hand zu prüfen. Veranstaltungen: Bereich /veranstaltungen mit Detailseite pro Fest, Lebenszyklus über das Datum (Ankündigung vor dem Fest, Rückblick danach), Galerie mit Lightbox. veranstaltungen.json ist dritte Termin-Quelle, damit ein Fest nie doppelt gepflegt wird. News-Artikel als dritte dynamische Prefix-Route, gemeinsamer detail-head. Behobene Fehler: - Wappen-Kontexte setzten Zeilen-Layout auf .crest statt auf die Zeile; das Wappen wurde zum Grid, Vereinsname und Tore rutschten darunter zusammen (Ergebnis-Rückblick, Vorschau, Cover). - --header-h (60px) unterschätzt die Kopfleiste um 32px (Logo 72px + 20px Versatz): neues abgeleitetes --header-space, sonst klebten Zurück-Links unter dem Logo. - base_url in der Produktions-Config ohne www, während .htaccess auf www umleitet; preflight prüft das jetzt. - .lightbox brauchte display:none mit (0,2,0), sonst lag das Overlay offen. Neue Werkzeuge: bin/anzeige-add.php (Anzeigen-Bestand), bin/veranstaltung-bilder.php (Plakate und Galerien, Alt-Texte folgen der Quelldatei), bin/qr.php (Druck-QR mit Warnung, wenn base_url nicht auf die echte Domain zeigt). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
This commit is contained in:
@@ -17,6 +17,38 @@
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* Nur für Fließtext auf der Stadionzeitungs-Vorwort-Seite (--ff-serif,
|
||||
tokens.css) — self-hosted wie Coolvetica/Abel, keine Google-Fonts-CDN.
|
||||
Quelle: PT Serif (ParaType, OFL-Lizenz). */
|
||||
@font-face {
|
||||
font-family: 'PT Serif';
|
||||
src: url('../fonts/pt-serif.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PT Serif';
|
||||
src: url('../fonts/pt-serif-italic.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* Nur für die Unterschrift des Vorwort-Unterzeichners in der Stadionzeitung
|
||||
(--ff-signature, tokens.css) — handschriftliche Signatur-Anmutung wie in
|
||||
der Canva-Vorlage. Self-hosted, keine Google-Fonts-CDN.
|
||||
Quelle: Mr Dafoe (Sudtipos, OFL-Lizenz), Latin-Subset inkl. Umlaute —
|
||||
von Felix aus sechs OFL-Kandidaten ausgewählt (29.07.2026). */
|
||||
@font-face {
|
||||
font-family: 'Mr Dafoe';
|
||||
src: url('../fonts/mr-dafoe.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--ff-body);
|
||||
font-size: var(--fs-600);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
112
public/assets/css/dateien.css
Normal file
112
public/assets/css/dateien.css
Normal file
@@ -0,0 +1,112 @@
|
||||
/* ============================================================
|
||||
DATEIEN — Marken-Skin für die Dateiablage (Files Gallery, /dateien)
|
||||
|
||||
KEIN Teil des Seiten-Layouts und deshalb bewusst die 7. CSS-Datei: geladen wird
|
||||
sie ausschließlich von storage/dateien/system/include/head.html, also in einem
|
||||
fremden Dokument, das wir nicht rendern. Sie steht NACH der files.css der App und
|
||||
gewinnt damit über die Variablen.
|
||||
|
||||
Zusammen mit tokens.css geladen (Farbwerte kommen von dort, nie als Hex von hier).
|
||||
Die App ist durchgängig variablengesteuert — wir setzen deshalb ihre Variablen und
|
||||
fassen ihre Selektoren fast nicht an. Das übersteht Updates.
|
||||
============================================================ */
|
||||
|
||||
/* Die Schrift bleibt bewusst die der App (system-ui): ein Datei-Manager ist ein
|
||||
Werkzeug, nicht eine Seite der Website — nah am Standard heißt hier vertraute
|
||||
Bedienung, und die Systemschrift ist in kleinen Größen und langen Dateinamen
|
||||
ohnehin robuster als unsere Abel. Die Marke tragen Wappen und Rot. */
|
||||
|
||||
:root {
|
||||
/* Farbton der App auf das Markenrot ziehen. Die App leitet daraus Flächen,
|
||||
Ränder und Ordnerfarben ab (hsl(var(--hue), 20%, …)) — alles bekommt einen
|
||||
warmen Rotstich statt Blau, ohne dass wir einzelne Regeln überschreiben. */
|
||||
--hue: var(--clr-accent-h);
|
||||
|
||||
/* Der Akzent selbst (Buttons, Links, Auswahl) exakt auf --clr-accent.
|
||||
Die App wählt je Theme eine der drei Varianten. */
|
||||
--hsl-primary-dark: var(--clr-accent-hsl);
|
||||
--hsl-primary-light: var(--clr-accent-hsl);
|
||||
--hsl-primary-contrast: var(--clr-accent-hsl);
|
||||
|
||||
/* --- Kontrast (gemessen, nicht geschätzt) ---
|
||||
Die App leitet Flächen UND Ordnerfarben aus --hue ab. Mit dem Markenrot als
|
||||
Farbton stand ein dunkelroter Ordner auf dunkelroter Fläche: 1,07:1, praktisch
|
||||
unsichtbar. Deshalb hier drei Korrekturen. */
|
||||
|
||||
/* Flächen etwas tiefer als das Seiten-Grau (#222 ≈ 13 %): der Ordner ist ein
|
||||
gefülltes Rot, und Rot ist von Natur aus dunkel — es braucht den Abstand nach
|
||||
unten. Bei 13 % kommt das Rot nur auf 3,03:1, bei 10 % auf 3,30:1. */
|
||||
--surface-base-lightness-dark: 10%;
|
||||
|
||||
/* Text heller als die Vorgabe der App (80 %): hebt Dateinamen auf 11,97:1 und
|
||||
zieht die abgeleiteten Meta-Töne (Brotkrumen, Anzahl-Badge) mit nach oben. */
|
||||
--text-base-lightness-dark: 88%;
|
||||
|
||||
/* Ordner im Markenrot. Vorderseite ist die große Fläche und trägt die Erkennbarkeit
|
||||
(gemessen 3,91:1 — über den 3:1, die WCAG 1.4.11 für Grafik verlangt), Rückseite dunkler
|
||||
als Kante. Erste Zeile ist der Fallback für Browser ohne color-mix(). */
|
||||
--svg-folder-fg-dark: var(--clr-accent);
|
||||
--svg-folder-fg-dark: color-mix(in srgb, var(--clr-accent) 80%, white);
|
||||
--svg-folder-fg-large-dark: var(--clr-accent);
|
||||
--svg-folder-fg-large-dark: color-mix(in srgb, var(--clr-accent) 80%, white);
|
||||
--svg-folder-bg-dark: var(--clr-accent-dark);
|
||||
--svg-folder-bg-large-dark: var(--clr-accent-dark);
|
||||
}
|
||||
|
||||
/* --- Login-Seite ---
|
||||
Die Login-Seite der App rendert nur „Einloggen" und ihr Formular; sie bindet
|
||||
include/footer.html nicht ein (index.php:561 rendert eine eigene, knappe Seite) und
|
||||
kennt keinen Platz für eigenes Markup. Damit man sieht, wessen Ablage das ist, kommt
|
||||
das Vereinswappen als dekorative Fläche darüber — Bild statt CSS-Textinhalt, damit
|
||||
nichts Sinntragendes im Stylesheet landet. */
|
||||
.page-login-body .login-container::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 96px;
|
||||
height: 124px;
|
||||
margin: 0 auto 1.5rem;
|
||||
background: url('../img/logo.svg') center / contain no-repeat;
|
||||
}
|
||||
|
||||
/* --- Fußzeile (storage/dateien/system/include/footer.html) ---
|
||||
.custom-footer-fixed ist der Hook der App (fest am unteren Rand, volle Breite).
|
||||
Wir geben ihm nur Typografie und Abstand. */
|
||||
.tsv-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.375rem 1rem;
|
||||
border-top: 2px solid hsl(var(--clr-accent-hsl));
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.tsv-footer a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
color: var(--text1);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Wappen in der Fußzeile: echtes <img> mit Maßen (kein Layout-Sprung), dekorativ —
|
||||
der Linktext trägt die Bedeutung. Die offizielle `logo`-Option der App fällt hier
|
||||
aus: sie wird über _c.config in js/custom.js gesetzt, und dieser Hook braucht wie
|
||||
css/custom.css eine öffentliche URL, die unser storage_path nicht hat. */
|
||||
.tsv-footer a img {
|
||||
height: 2.6em; /* darunter wird das Wappen zum Fleck */
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.tsv-footer a:hover,
|
||||
.tsv-footer a:focus-visible {
|
||||
color: hsl(var(--clr-accent-hsl));
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Die App reserviert keinen Platz für die feste Fußzeile — sonst verschwindet die
|
||||
letzte Dateizeile bzw. der letzte Menüpunkt darunter. */
|
||||
#files-container,
|
||||
#sidebar-inner {
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
/* --- Header --- */
|
||||
.site-header {
|
||||
position: absolute;
|
||||
inset: 20px 0 auto 0;
|
||||
inset: var(--header-top) 0 auto 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,13 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* CTAs im Menü-Overlay: nur im Burger-Modus sichtbar (dort ersetzen sie die
|
||||
Header-Buttons — Best Practice: mobil kein Dauer-Button neben dem Burger,
|
||||
die Handlungsaufrufe stehen prominent am Ende des Menüs). */
|
||||
.site-nav__ctas {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-nav__toggle {
|
||||
display: none;
|
||||
}
|
||||
@@ -262,12 +269,22 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Header-CTAs weichen in den Burger (site-nav__ctas) — kein Dauer-Button
|
||||
neben dem Burger, der Header bleibt ruhig: Logo links, Burger rechts. */
|
||||
.site-header__actions {
|
||||
order: 2;
|
||||
margin-left: auto;
|
||||
/* CTAs bleiben über dem Menü-Overlay sichtbar */
|
||||
position: relative;
|
||||
z-index: 30;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-nav__ctas {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-s);
|
||||
margin-top: var(--space-2xl);
|
||||
}
|
||||
|
||||
.site-nav__ctas .btn {
|
||||
justify-content: center;
|
||||
font-size: var(--btn-font-lg);
|
||||
}
|
||||
|
||||
/* Logo/Brand ebenfalls über dem Overlay halten — Orientierung bei offenem Menü. */
|
||||
@@ -337,6 +354,10 @@
|
||||
inset: 0;
|
||||
z-index: 20;
|
||||
flex-direction: column;
|
||||
/* Desktop-Leiste wrappt (horizontale Nav) — im Overlay MUSS das aus,
|
||||
sonst bricht die Spalte bei Überlänge (offenes Untermenü + CTAs)
|
||||
in eine zweite Spalte um, statt zu scrollen. */
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
@@ -492,15 +513,6 @@
|
||||
.site-header__name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* CTA(s) kompakter neben dem Burger. */
|
||||
.site-header__actions a:not(:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-header__actions .btn {
|
||||
font-size: var(--btn-font-sm);
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Back-to-top --- */
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
--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 */
|
||||
--clr-bg: #222222; /* Grund-Hintergrund (mit Textur) */
|
||||
--clr-bg-deep: #161616; /* abgesetzte Sektionen */
|
||||
--clr-bg-footer: #000000;
|
||||
@@ -16,19 +19,29 @@
|
||||
--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 */
|
||||
@@ -111,6 +124,7 @@
|
||||
/* --- 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 */
|
||||
|
||||
@@ -122,8 +136,15 @@
|
||||
--container-max: 1200px;
|
||||
--container-pad: var(--space-s);
|
||||
--space-section: var(--space-6xl);
|
||||
--header-h: 60px;
|
||||
--logo-h: 72px;
|
||||
--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;
|
||||
|
||||
Reference in New Issue
Block a user