Files
flimmer/docs/DESIGN.md
T
Florian Wilde 18c87e6b2e fix: Schrift mitliefern statt beim Bauen herunterladen
next/font/google laedt Outfit beim Bauen von Google — das macht den Build von
einer Netzverbindung abhaengig und liess ihn im Container haengen. Die
variable Fassung liegt jetzt als Datei im Repository; weder beim Bauen noch
zur Laufzeit geht eine Anfrage nach aussen.

Ausserdem: npm blockiert seit Version 11 Install-Skripte. Fuer prisma und
@prisma/engines sind sie jetzt gezielt erlaubt, damit im Image die
plattformpassende Engine bereitliegt.
2026-09-01 20:56:32 +02:00

152 lines
6.3 KiB
Markdown
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.
# Flimmer — Design-Sprache
Diese Datei hält fest, warum die Oberfläche aussieht, wie sie aussieht, und
welche Werte dabei gelten. Sie ist die Referenz für alles, was später dazukommt.
## Idee
Der Name kommt von der **Flimmerkiste** und vom warmen Flimmern eines
Bildschirms im abgedunkelten Zimmer. Genau das trägt die Gestaltung: ein sehr
dunkler, blauvioletter Raum, in den ein warmes Licht fällt. Alles Farbige in
der Oberfläche ist dieses Licht — es gibt keine zweite, konkurrierende
Signalfarbe.
## Marke
| Variante | Datei | Einsatz |
|---|---|---|
| Bildmarke | `public/brand/flimmer-icon.svg` | App-Icon, Favicon, Avatare |
| Bildmarke + Wortmarke | `public/brand/flimmer-logo.svg` | Header, Login, README |
| Monochrom | `public/brand/flimmer-mono.svg` | Druck, E-Mail-Footer, Prägung |
| Maskable | `public/brand/flimmer-icon-maskable.svg` | Android-Startbildschirm |
| Wortmarke allein | `public/brand/flimmer-wordmark.svg` | Sonderfälle |
Die Bildmarke ist ein abgerundetes Bildschirm-Rechteck mit weichem, warmem
Glühen und einem Play-Dreieck; der angedeutete Standfuß macht daraus die
Flimmerkiste. Die **Wortmarke ist aus Pfaden konstruiert** (geometrische, leicht
gerundete Sans, Versalhöhe 90, x-Höhe 54, Strichstärke 15, runde Abschlüsse) —
sie braucht damit keine installierte Schrift und sieht überall identisch aus.
Im UI liegt die Marke als React-Komponente vor
(`src/components/brand/FlimmerLogo.tsx`). Die Verläufe stehen einmalig in
`<BrandDefs />` im Root-Layout; alle Instanzen referenzieren sie. Rasterdateien
(Favicon, PWA-Icons, OG-Bild) sind reine Ableitungen und entstehen mit
`npm run icons`.
## Farbwelt
Die Signaturfarbe ist kein einzelner Ton, sondern ein **Verlauf von Bernstein
nach Magenta**. Er trägt Buttons, Fortschrittsbalken, aktive Navigation und das
Glühen des Logos.
### Dunkel (Standard)
| Rolle | Wert | Kontrast auf Grund |
|---|---|---|
| Grund | `#0c0a14` | — |
| Karte | `#171424` | — |
| Rahmen | `#2e2745` | 1,4:1 (dekorativ) |
| Text | `#f4f1fa` | **17,0:1** |
| Text gedämpft | `#aca5c2` | **7,7:1** |
| Text zurückhaltend | `#7c7594` | **4,6:1** |
| Bernstein | `#ffb454` | **11,3:1** |
| Magenta | `#ff4d9d` | **6,0:1** |
| Text auf dem Verlauf | `#1a1024` | min. **5,5:1** (am Magenta-Ende) |
### Hell
| Rolle | Wert | Kontrast auf Grund |
|---|---|---|
| Grund | `#faf7f5` (warmgrau) | — |
| Karte | `#ffffff` | — |
| Text | `#1b1524` | **16,2:1** |
| Text gedämpft | `#5b5268` | **6,7:1** |
| Text zurückhaltend | `#766c84` | **4,6:1** |
| Akzent als Text | `#8a4b00` | **6,4:1** |
| Akzent-Alternative | `#b01262` | **6,4:1** |
| Text auf dem Verlauf | `#23122c` | min. **6,1:1** |
Damit erfüllt jede Text-/Hintergrund-Kombination **WCAG AA**.
### Zwei Verläufe, nicht einer
Der vollfarbige Verlauf funktioniert im Dunkeln überall — auf hellem Grund
verschwindet sein Bernstein-Ende jedoch. Deshalb gibt es zwei Tokens:
- `--fl-gradient` — Flächen (Buttons, Fortschritt, Glühen). In beiden Themes
vollfarbig, weil darauf immer dunkler Text (`--fl-on-accent`) sitzt.
- `--fl-gradient-ink` — **Text** und feine Linien. Im Dunkeln identisch, im
Hellen abgedunkelt auf `#8a4b00 → #b01262`, damit AA gilt.
Analog dazu die Logo-Stops `--fl-brand-1/2/3`: im Hellen tiefer angesetzt
(`#c26a00 → #c9186f`), damit die Wortmarke auf warmem Weiß lesbar bleibt, ohne
die Bewegung von Bernstein nach Magenta aufzugeben.
## Tokens
Alle Werte liegen als CSS-Variablen `--fl-*` in `src/app/globals.css` und werden
über `@theme inline` an Tailwind durchgereicht. Ein Theme-Wechsel setzt nur das
Attribut `data-theme` am `<html>`-Element; ein Inline-Skript im Layout tut das,
bevor der erste Pixel gemalt wird, damit nichts aufblitzt.
Ein zusätzliches Theme braucht daher genau einen neuen Selektor-Block mit
denselben Variablennamen — keine Änderung an Komponenten.
## Bausteine
| Klasse | Zweck |
|---|---|
| `.fl-card` | Karte: halbtransparent, weicher Rahmen, Rückenunschärfe |
| `.fl-poster-card` | Posterkachel mit sanftem Aufglimmen beim Hover |
| `.fl-btn` + `.fl-btn-primary` / `.fl-btn-ghost` | Schaltflächen |
| `.fl-input` | Eingabefelder samt Fokusring im Magenta |
| `.fl-progress` | Fortschrittsbalken im Signaturverlauf |
| `.fl-glimmer` | Mikro-Animation beim Abhaken einer Episode |
## Diagrammfarben
Die Signaturfarben sind für Diagrammflächen auf dunklem Grund zu hell. Für die
beiden Serien der Statistik stehen deshalb abgedunkelte Varianten:
| Serie | Wert | Prüfung |
|---|---|---|
| Episoden | `#c47a18` | Helligkeitsband, Sättigung, Kontrast ≥ 3:1 — in **beiden** Modi |
| Filme | `#d92d78` | dito |
Das schlechteste Paar erreicht ΔE 12,1 unter Deuteranopie und 20,6 bei
normalem Sehen (Ziel: ≥ 8 bzw. ≥ 15). Beide Werte gelten auf hellem wie
dunklem Grund, weshalb es nur **eine** Diagrammpalette gibt statt zweier.
Balken ohne Identitätsbedeutung (Genre-Verteilung) tragen einheitlich
`#c47a18` — die Länge zeigt schon die Größe, die Farbe muss nichts
wiederholen. Streamingdienste tragen ihre Markenfarbe, aber nur, wenn sie auf
hellem *und* dunklem Grund mindestens 3:1 erreicht; sonst fällt der Balken auf
den geprüften Standardton zurück.
Die Aussage hängt nie allein an der Farbe: Legende, Achsenwerte, ein Tooltip
beim Überfahren und eine für Screenreader hinterlegte Tabelle tragen dieselbe
Information.
## Bewegung
Ruhig und kurz: 200–420 ms, `cubic-bezier(0.22, 1, 0.36, 1)`. Keine harten
Blitze — beim Abhaken einer Episode glimmt die Zeile einmal warm auf und
verklingt. `prefers-reduced-motion: reduce` schaltet sämtliche Übergänge ab.
## Typografie
**Outfit** — geometrisch, leicht gerundet, passt zur Wortmarke. Die variable
Fassung (Strichstärke 100–900) liegt als Datei im Repository
(`public/fonts/`), aufgeteilt in Latin und Latin-Extended.
Bewusst nicht `next/font/google`: das lädt die Schrift beim Bauen herunter und
macht den Build von einer Netzverbindung abhängig — im Container blieb er
daran hängen. Mit der mitgelieferten Datei gibt es weder beim Bauen noch zur
Laufzeit einen Abruf nach außen. Rückfallkette: Inter, dann System-Sans.
## Grundhaltung
Posterlastig und filmisch: großzügige Poster, abgerundete Ecken, weiche
Verläufe statt harter Linien. Farbe ist knapp und bedeutet etwas — der Verlauf
markiert, was gerade dran ist. Der Rest bleibt im Dunkeln.