feat(ui): UI-001 Designsystem-Grundlage - Dark Mode + Readiness-Farbtokens
Epic 20 (UI-Redesign) angelegt, Stufe 1: CSS-Variablen für Dark Mode (System-Präferenz + manueller Schalter via ThemeToggle, localStorage- persistiert) und eigene Farbtokens für Einsatzbereitschaft (ready/ limited/not-ready/unknown), Basis für ReadinessBadge in UI-003. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
@@ -272,10 +272,11 @@ eigenes Modul (MAINT-\*, MABEA hat nur Prüfung, keine Wartung)**.
|
|||||||
| `17_zustaendigkeit.md` | ZUST-001 … ZUST-002 (vollständig, nachträglich ergänzt) |
|
| `17_zustaendigkeit.md` | ZUST-001 … ZUST-002 (vollständig, nachträglich ergänzt) |
|
||||||
| `18_notifications.md` | NOTIF-001 … NOTIF-002 (vollständig, nachträglich ergänzt) |
|
| `18_notifications.md` | NOTIF-001 … NOTIF-002 (vollständig, nachträglich ergänzt) |
|
||||||
| `19_satelliten_server.md` | SAT-001 (Platzhalter, nachträglich ergänzt, bewusst zurückgestellt) |
|
| `19_satelliten_server.md` | SAT-001 (Platzhalter, nachträglich ergänzt, bewusst zurückgestellt) |
|
||||||
|
| `20_ui_redesign.md` | UI-001 … UI-008 (vollständig, nachträglich ergänzt, in Umsetzung) |
|
||||||
|
|
||||||
**Alle 19 Epics durchgegangen** (16 ursprüngliche + 17 Zuständigkeit/18 Notifications/19
|
**Alle 20 Epics durchgegangen** (16 ursprüngliche + 17 Zuständigkeit/18 Notifications/19
|
||||||
Satelliten-Server, nachträglich aus dem Abgleich mit den alten Arbeitskarten ergänzt).
|
Satelliten-Server/20 UI-Redesign, nachträglich ergänzt). Detaillierungsphase
|
||||||
Detaillierungsphase abgeschlossen (2026-09-05).
|
abgeschlossen (2026-09-05), UI-Redesign-Epic ergänzt (2026-09-06).
|
||||||
|
|
||||||
## Nachtrag: Externe Roadmap-Bewertung Shelf/Resgrid/Emergency Mgmt (2026-09-05)
|
## Nachtrag: Externe Roadmap-Bewertung Shelf/Resgrid/Emergency Mgmt (2026-09-05)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
# Epic 20 — UI-Redesign (moderne BOS-Plattform-Optik)
|
||||||
|
|
||||||
|
Ausgangspunkt: externer Redesign-Prompt vom 2026-09-06 (Nutzer-Vorgabe, siehe
|
||||||
|
Referenzen). **Keine Neuentwicklung, keine Entfernung bestehender Funktionen** —
|
||||||
|
bestehende API/Fachlogik/PWA/Offline-Sync bleiben unverändert, nur die Darstellung
|
||||||
|
wird modernisiert. React/Vite/TypeScript bleibt, kein Framework-Wechsel.
|
||||||
|
|
||||||
|
Aktueller Stand vor Redesign: 39 Seiten-/Komponenten-Dateien, ~7.000 Zeilen, einfaches
|
||||||
|
`global.css` (560 Zeilen) ohne Designsystem, keine UI-Bibliothek.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UI-001 — Designsystem-Grundlage
|
||||||
|
|
||||||
|
- **Ziel:** Ein zentrales Set an Design-Tokens (Farben, Typografie, Abstände,
|
||||||
|
Radien, Schatten) statt verstreuter Inline-Styles.
|
||||||
|
- **Beschreibung:** CSS-Variablen (Light + Dark), zentrale Status-Farben
|
||||||
|
(einsatzbereit/eingeschränkt/nicht einsatzbereit/unbekannt), Basis-Komponenten
|
||||||
|
(Button, Card, Input, Badge, Table) vereinheitlicht.
|
||||||
|
- **Benutzerwert:** Konsistentes, hochwertiges Erscheinungsbild in der ganzen App.
|
||||||
|
- **Abhängigkeiten:** keine
|
||||||
|
- **Backend:** keins
|
||||||
|
- **Frontend:** `styles/tokens.css`, überarbeitetes `global.css`, Dark-Mode via
|
||||||
|
`prefers-color-scheme` + manuellem Umschalter
|
||||||
|
- **Mobile:** Basis für alle Folge-Kacheln
|
||||||
|
- **Rechte:** keine Änderung
|
||||||
|
- **Akzeptanzkriterien:** Dark Mode umschaltbar, alle Basis-Elemente nutzen Tokens
|
||||||
|
statt Hardcoded-Werten.
|
||||||
|
- **Tests:** keine (reines Styling), visuelle Kontrolle.
|
||||||
|
- **DoD:** offen — noch nicht begonnen.
|
||||||
|
|
||||||
|
## UI-002 — App-Shell & Navigation
|
||||||
|
|
||||||
|
- **Ziel:** Moderne Sidebar (Desktop) / kompakte Navigation (Mobile) statt
|
||||||
|
bisheriger einfacher Navigation in `AppShell.tsx`.
|
||||||
|
- **Beschreibung:** Bereiche Dashboard/Objekte/Fahrzeuge/Material/Lager/
|
||||||
|
Kontrollen/Prüfungen/Mängel/Personal/Administration. Globale Suche `Ctrl/⌘+K`.
|
||||||
|
Quick Actions (QR scannen, Kontrolle starten, Mangel melden, Material buchen).
|
||||||
|
- **Benutzerwert:** Schnelle Orientierung, weniger Klicks zu Kernaktionen.
|
||||||
|
- **Abhängigkeiten:** UI-001
|
||||||
|
- **Backend:** keins (Suche client-seitig über bereits geladene Objekt-/Material-Listen,
|
||||||
|
kein neuer Such-Endpunkt in Phase 1)
|
||||||
|
- **Frontend:** `AppShell.tsx` umgebaut, neue `CommandPalette`-Komponente
|
||||||
|
- **Mobile:** Bottom-Navigation oder Drawer statt Sidebar
|
||||||
|
- **Rechte:** Navigationspunkte nach Rolle gefiltert (bereits vorhandene Rollen-Logik
|
||||||
|
wiederverwenden)
|
||||||
|
- **Akzeptanzkriterien:** alle bestehenden Routen weiter erreichbar, Suche findet
|
||||||
|
Objekte per Name/Code.
|
||||||
|
- **Tests:** keine neuen (reines Routing/UI).
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
## UI-003 — Zentrale Statuskomponenten
|
||||||
|
|
||||||
|
- **Ziel:** Wiederverwendbare Status-Anzeigen statt an mehreren Stellen dupliziertem
|
||||||
|
Badge-Markup.
|
||||||
|
- **Beschreibung:** `ReadinessBadge` (einsatzbereit/eingeschränkt/nicht
|
||||||
|
einsatzbereit/unbekannt — „unbekannt" NIE als einsatzbereit darstellen),
|
||||||
|
`SyncStatus` (online/offline/synchronisiert), `InspectionStatus`,
|
||||||
|
`InventoryStatus`. Jede Komponente kapselt Farbe+Icon+Text an einer Stelle.
|
||||||
|
- **Benutzerwert:** Konsistente, sofort verständliche Statusdarstellung überall.
|
||||||
|
- **Abhängigkeiten:** UI-001
|
||||||
|
- **Backend:** keins
|
||||||
|
- **Frontend:** `components/status/ReadinessBadge.tsx` etc., bestehende Ad-hoc-Badges
|
||||||
|
(`DashboardPage.tsx`, `AktePage.tsx`, `ObjektListPage.tsx`) darauf umgestellt
|
||||||
|
- **Rechte:** keine Änderung
|
||||||
|
- **Akzeptanzkriterien:** kein Status mehr als Inline-`<span className="badge...">`
|
||||||
|
dupliziert.
|
||||||
|
- **Tests:** ggf. kleiner Komponententest je Status-Mapping.
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
## UI-004 — Dashboard neu
|
||||||
|
|
||||||
|
- **Ziel:** „Was ist einsatzbereit und was muss ich jetzt tun?" in 5 Sekunden
|
||||||
|
beantwortbar.
|
||||||
|
- **Beschreibung:** Einsatzbereitschaft-Übersicht (einsatzbereit/eingeschränkt/
|
||||||
|
nicht einsatzbereit/unbekannt), offene Mängel, fällige Kontrollen/Prüfungen,
|
||||||
|
fehlendes Material, aktuelle Aufgaben — alles aus bereits vorhandenen
|
||||||
|
Dashboard-/Fehlbestand-/Mangel-Endpunkten, keine Fake-Daten.
|
||||||
|
- **Benutzerwert:** Kernversprechen der Kachel — sofortiger Überblick.
|
||||||
|
- **Abhängigkeiten:** UI-001, UI-003
|
||||||
|
- **Backend:** keins zusätzlich (bestehende Dashboard-Kennzahlen wiederverwenden)
|
||||||
|
- **Frontend:** `DashboardPage.tsx` neu strukturiert, Card-Grid statt Liste
|
||||||
|
- **Mobile:** gestapeltes Layout
|
||||||
|
- **Rechte:** keine Änderung
|
||||||
|
- **Akzeptanzkriterien:** alle geforderten Kennzahlen sichtbar, keine Platzhalter-/
|
||||||
|
Fake-Werte.
|
||||||
|
- **Tests:** bestehende Dashboard-Tests bleiben grün.
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
## UI-005 — Objektakte modernisiert
|
||||||
|
|
||||||
|
- **Ziel:** `AktePage.tsx` (bereits FILE-006/Akte-Aggregation) optisch/strukturell
|
||||||
|
aufwerten, inkl. begründeter Einsatzbereitschafts-Anzeige.
|
||||||
|
- **Beschreibung:** Status mit Begründung (z. B. „🔴 Nicht einsatzbereit — Funkgerät
|
||||||
|
defekt, 2 Beladungspositionen fehlen, Prüfung überfällig"), Tabs oder klar
|
||||||
|
getrennte Bereiche für Beladung/Kontrollen/Mängel/Prüfungen/Wartungen/
|
||||||
|
Dokumente/Historie.
|
||||||
|
- **Benutzerwert:** Sofort verständlich, WARUM ein Objekt nicht einsatzbereit ist.
|
||||||
|
- **Abhängigkeiten:** UI-001, UI-003
|
||||||
|
- **Backend:** ggf. kleine Ergänzung am `/akte/objekt/{id}`-Endpunkt, falls die
|
||||||
|
Begründungs-Texte nicht schon aus den Einzelfeldern ableitbar sind (prüfen vor
|
||||||
|
Umsetzung)
|
||||||
|
- **Frontend:** `AktePage.tsx` Umbau, bisherige 6 gleichartigen Card-Blöcke
|
||||||
|
(bereits als Simplification-Fund dokumentiert) auf gemeinsame Komponente
|
||||||
|
vereinheitlichen
|
||||||
|
- **Rechte:** keine Änderung
|
||||||
|
- **Akzeptanzkriterien:** „unbekannt/nie kontrolliert" wird nie als einsatzbereit
|
||||||
|
dargestellt (harte Regel, Akzeptanzkriterium testbar).
|
||||||
|
- **Tests:** Begründungslogik testen (welche Bedingungen führen zu welchem Status).
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
## UI-006 — Kontrolle & Beladung modernisiert
|
||||||
|
|
||||||
|
- **Ziel:** Bestehenden Kontrollworkflow (QR/Objekt → Kontrolle starten → Position
|
||||||
|
prüfen → OK/Abweichung → speichern → Abschluss) beibehalten, Fortschritt
|
||||||
|
(`38 / 40 geprüft`) und fehlerhafte Positionen visuell hervorheben.
|
||||||
|
- **Benutzerwert:** Schnellere, fehlerfreiere Kontrolle vor Ort.
|
||||||
|
- **Abhängigkeiten:** UI-001, UI-003
|
||||||
|
- **Backend:** keins
|
||||||
|
- **Frontend:** `KontrollPage.tsx` + `pages/kontrolle/*` Fortschrittsanzeige,
|
||||||
|
hervorgehobene Abweichungen
|
||||||
|
- **Mobile:** Priorität — Haupteinsatzort dieses Screens
|
||||||
|
- **Rechte:** keine Änderung
|
||||||
|
- **Akzeptanzkriterien:** Fortschritt live sichtbar, Abweichungen nicht zu übersehen.
|
||||||
|
- **Tests:** bestehende Kontroll-Tests bleiben grün.
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
## UI-007 — QR-Scan-Aktionsleiste
|
||||||
|
|
||||||
|
- **Ziel:** Nach Scan direkt Aktionen anbieten (Kontrolle starten/Mangel melden/
|
||||||
|
Informationen), nicht nur Direkt-Navigation.
|
||||||
|
- **Beschreibung:** Baut auf MOBILE-002-Fix (Scan → Akte) auf, ergänzt auf der
|
||||||
|
Akte-Seite eine hervorgehobene Aktionsleiste statt nur einem Button.
|
||||||
|
- **Benutzerwert:** Weniger Klicks nach dem Scan.
|
||||||
|
- **Abhängigkeiten:** UI-005, MOBILE-002 (bereits erledigt)
|
||||||
|
- **Backend:** keins
|
||||||
|
- **Frontend:** Aktionsleiste in `AktePage.tsx`
|
||||||
|
- **Rechte:** je Aktion bestehende Rollenprüfung wiederverwenden
|
||||||
|
- **Akzeptanzkriterien:** alle drei Aktionen von der Akte aus erreichbar.
|
||||||
|
- **Tests:** keine neuen.
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
## UI-008 — Restliche Module (Material, Lager, Personal, Administration)
|
||||||
|
|
||||||
|
- **Ziel:** Verbleibende Seiten im neuen Designsystem angleichen.
|
||||||
|
- **Beschreibung:** Admin-Tabs (`LagerSection.tsx` u.a.), `MangelListePage.tsx`,
|
||||||
|
`FehlbestandListePage.tsx` auf Tokens/Statuskomponenten umstellen.
|
||||||
|
- **Benutzerwert:** Durchgängiges Erscheinungsbild, keine Stilbrüche.
|
||||||
|
- **Abhängigkeiten:** UI-001..003
|
||||||
|
- **Backend:** keins
|
||||||
|
- **Frontend:** verbleibende Seiten
|
||||||
|
- **Rechte:** keine Änderung
|
||||||
|
- **Akzeptanzkriterien:** keine Seite mehr im alten Stil.
|
||||||
|
- **Tests:** bestehende Tests bleiben grün.
|
||||||
|
- **DoD:** offen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Reihenfolge (zwingend, laut Vorgabe):** UI-001 → UI-002 → UI-003 → UI-004 → UI-005
|
||||||
|
→ UI-006 → UI-007 → UI-008. Jede Stufe wird einzeln abgeschlossen und bestätigt,
|
||||||
|
bevor die nächste beginnt (Arbeitskacheln-Methodik: kein Direktcoden ohne Freigabe
|
||||||
|
je Schritt).
|
||||||
|
|
||||||
|
**Nicht-Ziele:** kein Framework-Wechsel, keine Breaking Changes an API/Fachlogik,
|
||||||
|
keine Fake-Daten, Offline/PWA/IndexedDB-Sync bleibt unangetastet, bestehende Tests
|
||||||
|
bleiben grün und werden erweitert wo sinnvoll.
|
||||||
|
|
||||||
|
**WCAG 2.2 AA:** als Leitplanke bei UI-001 (Kontraste/Fokus-Stile) und UI-002
|
||||||
|
(Tastaturbedienung Command Palette) mitgedacht, kein separater Prüf-Task.
|
||||||
|
|
||||||
|
## Referenzen
|
||||||
|
Externer Redesign-Prompt, vom Nutzer am 2026-09-06 eingebracht (kompakte Version
|
||||||
|
für Coding-KI, Zielrepo MABEA).
|
||||||
@@ -2,6 +2,7 @@ import type { ReactNode } from "react";
|
|||||||
import { NavLink, useNavigate } from "react-router-dom";
|
import { NavLink, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { useAuth } from "../auth/AuthContext";
|
import { useAuth } from "../auth/AuthContext";
|
||||||
|
import { ThemeToggle } from "./ThemeToggle";
|
||||||
|
|
||||||
/** Gemeinsamer Rahmen (Kopfzeile + Navigation) für alle eingeloggten Screens. */
|
/** Gemeinsamer Rahmen (Kopfzeile + Navigation) für alle eingeloggten Screens. */
|
||||||
export function AppShell({ children }: { children: ReactNode }) {
|
export function AppShell({ children }: { children: ReactNode }) {
|
||||||
@@ -41,6 +42,7 @@ export function AppShell({ children }: { children: ReactNode }) {
|
|||||||
{istAdmin ? "Administration" : "Verwaltung"}
|
{istAdmin ? "Administration" : "Verwaltung"}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
)}
|
)}
|
||||||
|
<ThemeToggle />
|
||||||
<button className="btn btn-secondary" onClick={handleLogout}>
|
<button className="btn btn-secondary" onClick={handleLogout}>
|
||||||
Abmelden
|
Abmelden
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
type Theme = "system" | "light" | "dark";
|
||||||
|
|
||||||
|
const SPEICHER_KEY = "mabea-theme";
|
||||||
|
|
||||||
|
function angewandtesTheme(theme: Theme): void {
|
||||||
|
if (theme === "system") {
|
||||||
|
document.documentElement.removeAttribute("data-theme");
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute("data-theme", theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function gespeichertesTheme(): Theme {
|
||||||
|
try {
|
||||||
|
const wert = localStorage.getItem(SPEICHER_KEY);
|
||||||
|
if (wert === "light" || wert === "dark") return wert;
|
||||||
|
} catch {
|
||||||
|
// localStorage evtl. blockiert (privater Modus) - Systemeinstellung als Fallback
|
||||||
|
}
|
||||||
|
return "system";
|
||||||
|
}
|
||||||
|
|
||||||
|
const REIHENFOLGE: Theme[] = ["system", "light", "dark"];
|
||||||
|
const LABEL: Record<Theme, string> = { system: "System", light: "Hell", dark: "Dunkel" };
|
||||||
|
|
||||||
|
/** UI-001 (Epic 20): manueller Dark-Mode-Schalter, Präferenz überlebt Reload. */
|
||||||
|
export function ThemeToggle() {
|
||||||
|
const [theme, setTheme] = useState<Theme>(() => gespeichertesTheme());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
angewandtesTheme(theme);
|
||||||
|
try {
|
||||||
|
if (theme === "system") localStorage.removeItem(SPEICHER_KEY);
|
||||||
|
else localStorage.setItem(SPEICHER_KEY, theme);
|
||||||
|
} catch {
|
||||||
|
// Speichern optional - beim nächsten Laden greift dann Systemeinstellung
|
||||||
|
}
|
||||||
|
}, [theme]);
|
||||||
|
|
||||||
|
function weiterschalten() {
|
||||||
|
const naechster = REIHENFOLGE[(REIHENFOLGE.indexOf(theme) + 1) % REIHENFOLGE.length];
|
||||||
|
setTheme(naechster);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="theme-toggle"
|
||||||
|
onClick={weiterschalten}
|
||||||
|
title="Farbschema wechseln (System/Hell/Dunkel)"
|
||||||
|
aria-label={`Farbschema: ${LABEL[theme]}, klicken zum Wechseln`}
|
||||||
|
>
|
||||||
|
{theme === "dark" ? "🌙" : theme === "light" ? "☀️" : "🖥️"} {LABEL[theme]}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -21,6 +21,14 @@
|
|||||||
--color-success: #1e7a34;
|
--color-success: #1e7a34;
|
||||||
--color-success-bg: #e7f5ea;
|
--color-success-bg: #e7f5ea;
|
||||||
--color-muted-bg: #eef0f3;
|
--color-muted-bg: #eef0f3;
|
||||||
|
--color-ready: #1e7a34;
|
||||||
|
--color-ready-bg: #e7f5ea;
|
||||||
|
--color-limited: #9a6700;
|
||||||
|
--color-limited-bg: #fff3d6;
|
||||||
|
--color-not-ready: #b3261e;
|
||||||
|
--color-not-ready-bg: #fbeaea;
|
||||||
|
--color-unknown: #55606b;
|
||||||
|
--color-unknown-bg: #e9ebee;
|
||||||
--radius: 8px;
|
--radius: 8px;
|
||||||
--radius-sm: 6px;
|
--radius-sm: 6px;
|
||||||
--shadow-sm: none;
|
--shadow-sm: none;
|
||||||
@@ -29,6 +37,73 @@
|
|||||||
--font-sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
|
--font-sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* UI-001 (Epic 20): Dark Mode - Systemeinstellung per prefers-color-scheme,
|
||||||
|
manueller Override per [data-theme] auf <html> (ThemeToggle-Komponente,
|
||||||
|
Präferenz in localStorage). Reihenfolge wichtig: System-Media-Query zuerst,
|
||||||
|
[data-theme="dark"] danach, damit der manuelle Schalter in beide Richtungen
|
||||||
|
gewinnt. */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root:not([data-theme="light"]) {
|
||||||
|
--color-bg: #14171a;
|
||||||
|
--color-surface: #1c2024;
|
||||||
|
--color-surface-sunken: #22262b;
|
||||||
|
--color-border: #333941;
|
||||||
|
--color-border-strong: #454c55;
|
||||||
|
--color-text: #e8eaed;
|
||||||
|
--color-text-muted: #9aa4ae;
|
||||||
|
--color-primary: #5b9bd8;
|
||||||
|
--color-primary-hover: #7bb0e2;
|
||||||
|
--color-primary-soft: #1e2c3a;
|
||||||
|
--color-danger: #e37c76;
|
||||||
|
--color-danger-bg: #3a2224;
|
||||||
|
--color-warning: #e0b34d;
|
||||||
|
--color-warning-bg: #3a3120;
|
||||||
|
--color-success: #6cc386;
|
||||||
|
--color-success-bg: #1f3324;
|
||||||
|
--color-muted-bg: #262b31;
|
||||||
|
--color-ready: #6cc386;
|
||||||
|
--color-ready-bg: #1f3324;
|
||||||
|
--color-limited: #e0b34d;
|
||||||
|
--color-limited-bg: #3a3120;
|
||||||
|
--color-not-ready: #e37c76;
|
||||||
|
--color-not-ready-bg: #3a2224;
|
||||||
|
--color-unknown: #9aa4ae;
|
||||||
|
--color-unknown-bg: #262b31;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="dark"] {
|
||||||
|
--color-bg: #14171a;
|
||||||
|
--color-surface: #1c2024;
|
||||||
|
--color-surface-sunken: #22262b;
|
||||||
|
--color-border: #333941;
|
||||||
|
--color-border-strong: #454c55;
|
||||||
|
--color-text: #e8eaed;
|
||||||
|
--color-text-muted: #9aa4ae;
|
||||||
|
--color-primary: #5b9bd8;
|
||||||
|
--color-primary-hover: #7bb0e2;
|
||||||
|
--color-primary-soft: #1e2c3a;
|
||||||
|
--color-danger: #e37c76;
|
||||||
|
--color-danger-bg: #3a2224;
|
||||||
|
--color-warning: #e0b34d;
|
||||||
|
--color-warning-bg: #3a3120;
|
||||||
|
--color-success: #6cc386;
|
||||||
|
--color-success-bg: #1f3324;
|
||||||
|
--color-muted-bg: #262b31;
|
||||||
|
--color-ready: #6cc386;
|
||||||
|
--color-ready-bg: #1f3324;
|
||||||
|
--color-limited: #e0b34d;
|
||||||
|
--color-limited-bg: #3a3120;
|
||||||
|
--color-not-ready: #e37c76;
|
||||||
|
--color-not-ready-bg: #3a2224;
|
||||||
|
--color-unknown: #9aa4ae;
|
||||||
|
--color-unknown-bg: #262b31;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
transition: background-color 0.15s ease, color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -348,6 +423,45 @@ select.input:focus {
|
|||||||
color: var(--color-danger);
|
color: var(--color-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* UI-003 (Epic 20): Einsatzbereitschafts-Status - eigene Klassen statt
|
||||||
|
Wiederverwendung von badge-success/warning/danger, weil "unbekannt" fachlich
|
||||||
|
NIE wie "einsatzbereit" aussehen darf (siehe ReadinessBadge-Komponente). */
|
||||||
|
.badge-ready {
|
||||||
|
background: var(--color-ready-bg);
|
||||||
|
color: var(--color-ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-limited {
|
||||||
|
background: var(--color-limited-bg);
|
||||||
|
color: var(--color-limited);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-not-ready {
|
||||||
|
background: var(--color-not-ready-bg);
|
||||||
|
color: var(--color-not-ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-unknown {
|
||||||
|
background: var(--color-unknown-bg);
|
||||||
|
color: var(--color-unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--color-border-strong);
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
padding: 0.4rem 0.6rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:hover {
|
||||||
|
background: var(--color-surface-sunken);
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
.alert {
|
.alert {
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 0.75rem 1rem;
|
padding: 0.75rem 1rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user