feat(theming): forest variant from @mana/themes (sprint 9m)

Cards is the first app on the new 12-token mana-vereinsweite
theming system (mana/docs/THEMING.md). Forest-Variant aus
@mana/themes/variants/forest.css konsumiert via app.css-Import,
data-theme="forest" in app.html.

Token-Welt umgestellt — 158 renames + 304 hsl-wraps in 17 Files
(Python-Refactor, BSD-sed war zu unzuverlässig):
- --color-bg          → --color-background
- --color-fg          → --color-foreground
- --color-muted       → --color-muted-foreground
- --color-primary-fg  → --color-primary-foreground
- --color-danger      → --color-error
- bare var(--color-X) → hsl(var(--color-X)) durchgängig

Bridge-Aliase in app.css mappen die shared-ui@0.1.x-Erwartungen
(card, accent, surface-elevated-*, …) auf das 12er-Set. Mit
shared-ui@2.0-Refactor entfällt diese Sektion. --brand-cards-forest
als App-Identitäts-Hex separiert von Theme-Tokens.

Header konsumiert PillTabGroup aus @mana/shared-ui@0.1.1 für die
Routen-Navigation (Decks/Lernen/Library/Import/Stats) und den
DE/EN-Sprach-Switcher — visuell konsistent mit Vereins-Standard.

Cards' primary-Grün wurde dabei von 142 76% 36% (alter Live-Stand)
auf 142 76% 28% verdunkelt, damit primary-foreground/primary-
Kontrast WCAG-AA-konform (≥4.5) ist. Der alte Live-Stand hatte
Ratio 3.35.

i18n: deck_stack.aria_label, deck_detail.fan_aria, deck_detail.
card_open, decks.card_count_more, study_session.manage_link.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-09 18:01:37 +02:00
parent 404ddec62d
commit 19a0036b82
20 changed files with 323 additions and 261 deletions

View file

@ -1,17 +1,53 @@
@import 'tailwindcss';
@import '@mana/themes/variants/forest.css';
/**
* Cards Theming-Setup.
*
* 12-Token-Vokabular kommt aus `@mana/themes/variants/forest.css`.
* `data-theme="forest"` ist in `app.html` gesetzt; Light/Dark via
* Class `.dark` auf <html>. Konvention: `hsl(var(--color-X))`. Bare
* `var(--color-X)` ist verboten (silent inherit-fallback). Detail in
* mana/docs/THEMING.md.
*
* Diese Datei trägt nur Cards-spezifische Ergänzungen:
* 1. Bridge-Aliase für shared-ui@0.1.x bis shared-ui@2.0 entfällt
* 2. Brand-Literals (--brand-cards-forest)
* 3. Layer-Base-Regeln (html, focus-ring, sr-only, skip-link)
* 4. Reduced-Motion-Override
*/
@theme {
--color-bg: oklch(0.99 0.005 240);
--color-fg: oklch(0.20 0.02 240);
--color-muted: oklch(0.55 0.02 240);
--color-border: oklch(0.92 0.01 240);
--color-card: oklch(1 0 0);
--color-primary: oklch(0.55 0.15 250);
--color-primary-fg: oklch(1 0 0);
--color-success: oklch(0.6 0.15 145);
--color-warning: oklch(0.75 0.15 75);
--color-danger: oklch(0.55 0.18 25);
/* ===== Bridge-Aliase für shared-ui@0.1.x =====
* shared-ui@0.1.x erwartet ein 30-Token-Vokabular aus dem alten
* managarten-System. Damit Komponenten wie PillTabGroup nicht
* silent-fallback brechen, mappen wir die fehlenden Tokens auf
* unser 12er-Set. Mit shared-ui@2.0 entfällt diese Sektion.
*/
--color-card: var(--color-surface);
--color-card-foreground: var(--color-foreground);
--color-popover: var(--color-surface);
--color-popover-foreground: var(--color-foreground);
--color-secondary: var(--color-surface);
--color-secondary-foreground: var(--color-foreground);
--color-accent: var(--color-primary);
--color-accent-foreground: var(--color-primary-foreground);
--color-input: var(--color-border);
--color-ring: var(--color-primary);
--color-border-strong: var(--color-foreground);
--color-surface-elevated: var(--color-surface);
--color-surface-elevated-1: var(--color-surface);
--color-surface-elevated-2: var(--color-surface);
--color-surface-elevated-3: var(--color-surface);
--color-app-accent: var(--color-primary);
--color-mana: var(--color-primary);
--color-destructive: var(--color-error);
--color-destructive-foreground: var(--color-primary-foreground);
/* ===== Brand-Literals (NICHT theme-aware) ===== */
--brand-cards-forest: #16a34a;
/* ===== Fonts ===== */
--font-sans:
ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
@ -19,19 +55,20 @@
@layer base {
html {
background-color: var(--color-bg);
color: var(--color-fg);
background-color: hsl(var(--color-background));
color: hsl(var(--color-foreground));
font-family: var(--font-sans);
}
body {
min-height: 100dvh;
}
/* Sichtbarer Fokus-Ring für Tastatur-Nutzer. Tailwind 4 strippt
die Browser-Defaults; wir setzen einen expliziten Outline.
Nur :focus-visible, damit Maus-Klicks visuell sauber bleiben. */
die Browser-Defaults; expliziter Outline. Nur :focus-visible,
damit Maus-Klicks visuell sauber bleiben. */
:focus-visible {
outline: 2px solid var(--color-primary);
outline: 2px solid hsl(var(--color-primary));
outline-offset: 2px;
border-radius: 2px;
}
@ -56,8 +93,8 @@
top: 0;
left: 0;
padding: 0.5rem 0.75rem;
background: var(--color-primary);
color: var(--color-primary-fg);
background: hsl(var(--color-primary));
color: hsl(var(--color-primary-foreground));
z-index: 50;
transform: translateY(-200%);
transition: transform 0.15s;
@ -79,15 +116,3 @@
scroll-behavior: auto !important;
}
}
@media (prefers-color-scheme: dark) {
@theme {
--color-bg: oklch(0.18 0.02 240);
--color-fg: oklch(0.95 0.01 240);
--color-muted: oklch(0.65 0.02 240);
--color-border: oklch(0.30 0.02 240);
--color-card: oklch(0.22 0.02 240);
--color-primary: oklch(0.70 0.18 250);
--color-primary-fg: oklch(0.18 0.02 240);
}
}