Files
vulncheck/DESIGN.md
T
vulncheckandClaude Opus 5 e8e4707f8e feat(ui): Farbe bedeutet Zustand — Token-Schicht statt Regenbogen
Die Vulnerabilities-Seite trug auf neun Job-Buttons, sieben Filtern und
einem Dutzend Row-Badges je einen eigenen Farbton (blau/amber/lila/rot/
orange/emerald/sky/cyan/gelb). Wenn alles schreit, hoert man nichts: das
Rot von KEV konkurrierte mit dem Lila von "EOL Check".

Statt Hexcodes zu tauschen erst eine Token-Schicht in OKLCH (Neutral /
Brand / Semantisch, Werte fuer light + mid + dark), dann die Komponenten
darauf umgestellt. Farbwechsel ist ab jetzt eine Token-Aenderung.

Die Regel dahinter, dokumentiert in DESIGN.md: ein Farbton bedeutet
Zustand, sonst nichts.

- Job-Buttons neutral, genau ein Brand-Button (Refresh Threat Intel).
- Filter sind neutrale Pills und faerben sich nur, wenn sie greifen —
  ueber :has(input:checked), ohne JS. Informativer als vorher, weil man
  jetzt sieht, welche Filter aktiv sind.
- Badges nur noch danger/warn/ok/info. Was bloss eine Identitaet nennt
  (Scanner-Name, Paketname, PoC-Zaehler), bleibt neutral. MSF und SSVC
  "widespread" behalten die einzige Vollton-Flaeche, sie sind die
  hoechste Stufe. Jedes Tag traegt weiterhin seinen Text, damit der
  Zustand nicht allein an der Farbe haengt.
- Die acht Data-Jobs sind keine Filter und standen mitten in der
  Filterzeile — jetzt in einem zugeklappten <details>.

Die .tv-*-Klassen sind ausschliesslich aus Tokens gebaut und laufen
dadurch in allen drei Themes ohne Eintrag in der Utility-Remap-Schicht.
Das ist der Weg, die Schicht langfristig loszuwerden.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KRCKYPm4DQ2vwDkNugGvHK
2026-09-10 10:01:34 +02:00

3.1 KiB

TrueVuln — Design-Tokens

Alle Farben liegen als CSS-Variablen in frontend/app/globals.css. Farbwechsel = Token-Werte ändern, nichts anderes. Keine neuen Hex-Werte in Komponenten.

Format ist OKLCH (L C H): wahrnehmungsgleichmäßige Helligkeit, dunkle und helle Stufen verlieren die Sättigung nicht. Chroma bleibt für UI unter ~0.22, Neutrale unter 0.02.

Die Regel

Drei Gruppen, und nur die Zuordnung entscheidet — nicht der Geschmack:

Gruppe Wofür Tokens
Neutral Der Großteil der UI: Flächen, Text, Border, alles was nur benennt --tv-fg, --tv-fg-soft, --tv-fg-muted, --tv-line, --tv-line-strong, --tv-btn-bg, --tv-mute-*
Brand Genau eine Sache: die primäre Aktion und der aktive Filter --tv-brand, --tv-brand-solid, --tv-brand-hover, --tv-brand-soft, --tv-brand-ring
Semantisch Nur Zustand --tv-danger*, --tv-warn*, --tv-ok*, --tv-info*

Ein Farbton bedeutet Zustand, sonst nichts. Ein Label, das nur eine Identität nennt (Scanner-Name, Paketname, PoC-Anzahl), bleibt neutral — sonst konkurriert es mit dem Rot, das wirklich zählt. Vorher trug jeder Job-Button und jeder Filter eine eigene Farbe; dadurch stach nichts mehr hervor.

Zustände nie nur über Farbe: jedes Tag trägt zusätzlich seinen Text (KEV, PATCH AVAILABLE, TI-TOTAL), damit es auch bei Farbfehl- sichtigkeit lesbar bleibt.

Semantik-Zuordnung (Vulnerabilities)

Token Bedeutung Beispiele
--tv-danger akute Bedrohung / offen CRITICAL, KEV, RANSOM, TI-TOTAL, EXPLOITABLE, Status open, CPR/Priority-Balken hoch
--tv-danger-solid (.tv-tag--alarm) eine Stufe darüber: waffenfähig MSF, SSVC widespread
--tv-warn erhöht, aber nicht akut HIGH, EDB, AUTO, EU-CRIT, VPR ≥ 7, SSVC active
--tv-ok erledigt / bestätigt gut PATCH AVAILABLE, Status patched, cross-confirmed
--tv-info Einordnung ohne Dringlichkeit MEDIUM, EUVD, EOL, aktiver Suchbegriff
neutral reine Identität Scanner-Namen, Paketnamen, PoC-Zähler, deferred, LOW, NON-CVE

Komponenten-Klassen

.tv-btn / .tv-btn--primary, .tv-chip (+ .tv-chip__box), .tv-tag (+ --danger --warn --ok --info --alarm --lg), .tv-bar (+ __hi __mid __low), .tv-pop, .tv-drawer.

Sie sind ausschließlich aus Tokens gebaut und funktionieren dadurch in allen drei Themes (light / mid / dark) ohne Eintrag in der Utility-Remap-Schicht darüber. Neue UI bitte damit bauen, nicht mit bg-red-100 text-red-700-Ketten — das ist der Weg, die Remap-Schicht langfristig loszuwerden.

Der aktive Zustand eines Filter-Chips kommt aus :has(input:checked) — kein JS, kein State-Prop.

Themes

:root = light. html[data-theme="mid"|"dark"] überschreiben nur die Token-Werte: Neutrale hängen sich an die vorhandene Surface-Skala, semantische Flächen werden über color-mix(… , transparent) zu Tints (eine Pastellfläche würde auf dunklem Grund ein Loch reißen), und die Vordergrundfarben steigen in der Helligkeit, damit AA bleibt. --tv-brand-solid bleibt in beiden Modi dunkel genug für weißen Button-Text.