Die Oberfläche wirkte zusammengesetzt, nicht entworfen. Vier Gründe, alle am Quelltext belegbar. Die Farben waren von der App abgedriftet: elevated, placeholder, text, text-dim, text-muted und die Trennlinie wichen in der letzten Stelle ab, und der Standardakzent war in der App Lilac, im Browser Orchid. Einzeln unsichtbar, zusammen genau der Grund, warum App und Browser nicht wie dasselbe Programm aussahen. Alles auf FlaroDesign zurückgeführt. Vier konkurrierende Radien — 6 auf Plakaten, 8 auf Karten, 999 auf jedem Knopf, zweimal nacktes 3 — sind jetzt drei, und die ersten beiden stimmen wieder mit FlaroDesign überein. Pillen bleiben, wo sie hingehören: Suche und Filter. Sechs Überschriftengrössen ohne Verhältnis zueinander sind eine Skala. Der Kacheltitel war mit 13 px/500 leiser als die Metazeile daneben; das erzeugt keine Hierarchie, sondern Rauschen. Und der Akzent sass auf neun Dingen gleichzeitig. Wenn alles Akzent ist, markiert er nichts. Der Primärknopf ist jetzt hell mit dunkler Schrift — genau das macht Netflix, dessen Rot nur im Schriftzug vorkommt. Dazu drei Dinge, die vorher ganz fehlten: ein sichtbarer Fokusring auf allem Bedienbaren, ohne den die Oberfläche mit der Tastatur praktisch unbedienbar war; Rücksicht auf "Bewegung reduzieren", das im Projekt nirgends vorkam; und ein Hover, der mehr tut als zwei Bildpunkte zu heben — mitsamt einem Abspielknopf, der nicht länger das halbe Plakat verdeckt. Tools/tokens-pruefen.py vergleicht beide Quellen und läuft im Veröffentlichungsskript mit. Kein Generator: erzeugter Swift liest sich schlechter als geschriebener, und die Prüfung fängt dasselbe ab. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Flaro Web
Die Weboberfläche für Rechner, auf denen es keine App gibt — Windows vor allem.
Aufbau
| Ordner | Was |
|---|---|
app/ |
Das Frontend (Vite, TypeScript) |
server/ |
Ein Server ohne Abhängigkeiten, der die Anfragen weiterreicht und die gebauten Dateien ausliefert |
frontend/ |
Die erste Fassung als einzelne Datei. Läuft, wird abgelöst. |
jellyfin-theme/ |
Ein Kleid für Jellyfins eigene Oberfläche — die kleine Lösung von vorher |
Warum ein eigener Server?
Er löst zwei Dinge, an denen die einzelne Datei scheitert, und zwar unabhängig davon, wie gut das Frontend geschrieben ist:
- Herkunft. Anfragen laufen über
/apiund damit über dieselbe Adresse wie die Seite. Kein CORS, auch nicht beim Streamen. - Klartext und Verschlüsselung. Läuft der Medienserver über
httpund die Seite überhttps, blockiert der Browser den Stream. Dagegen kann keine Zeile im Frontend etwas tun — ein Server davor schon.
Nebenbei bleibt der Zugangsschlüssel beim Server, statt im Browser zu liegen.
Betreiben
cd app && npm install && npm run build
cd ../server && FLARO_SERVER=http://jellyfin:8096 node index.js
Dann auf http://localhost:8080. Der Port lässt sich über PORT ändern.
Entwickeln
cd app && FLARO_SERVER=http://jellyfin:8096 npm run dev
Vite übernimmt dabei das Weiterreichen, der eigene Server wird nicht gebraucht.