Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,4 @@ sbom*.xml
NOTES.local.md
TODO.local.md
SCRATCH.md
CLAUDE.md
26 changes: 22 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,21 @@

**Auth-Entscheidung (2026-05-24):** Wir bleiben bei selbst geschriebenem Auth (Argon2id + DB-Sessions in `src/lib/auth/*`) statt `next-auth`. Begründung: passt zum Zero-Knowledge-Modell (ADR 0003), keine OAuth-Provider geplant, kein Beta-Code im Auth-Pfad. `next-auth` wurde aus `package.json` entfernt.

> **Letzte Aktualisierung:** 2026-06-07 — **Post-Backlog-Aufräumrunde:** (1) **Mind-Map-Parent-Links
> **Letzte Aktualisierung:** 2026-07-13 — **Frontend-Redesign: msk-shop Design-System übernommen**
> ([ADR 0025](docs/architecture/0025-adopt-msk-shop-design-system.md), löst ADR 0024 „Modern Minimal" ab).
> Die zuvor angefangene „Modern Minimal"-Identität (Geist-Fonts, mintgrüner `#2ee6a6`-Akzent) wurde
> **komplett verworfen** und durch das Design-System des Schwester-Projekts `msk-shop` ersetzt, für einen
> einheitlichen MSK-Marken-Look über beide Produkte: GitHub-Dark-Flächen (bg `#0d1117`, card `#161b22`,
> border `#30363d`) + MSK-Grün (`--color-primary` `#5eb131` dark / `#4ea426` light), Fonts **Inter Variable
> + JetBrains Mono** (self-hosted via `@fontsource-variable`, Geist entfernt), `next-themes`
> `defaultTheme="dark"`. Die **shadcn/ui + Radix-Primitives** (`src/components/ui/`) bleiben, neu eingefärbt.
> Token-Vokabular + Idiome (`.eyebrow`, `.msk-card`, `.msk-btn-*`, `.container-page`) 1:1 aus msk-shop in
> `src/app/globals.css`, mit **Legacy-Alias-Bridge** für die non-breaking Screen-Migration. Alle ~40 Screens
> auf die Primitives + kanonische Tokens migriert (native Checkboxen/Selects/File-Inputs/dnd-Handles bewusst
> nativ). typecheck + lint + build grün, Em-Dashes aus UI-Copy entfernt. Commit `feat(design): adopt
> msk-shop design system`.
>
> _Vorheriger Stand (2026-06-07):_ **Post-Backlog-Aufräumrunde:** (1) **Mind-Map-Parent-Links
> round-trippen jetzt durch Board-Export/Import** (`ExportedCard.parentId` + Remap-Pass im Importer,
> #49-Folgeschritt erledigt; `tests/unit/board-import.test.ts`). (2) **CSP-`style-src`-„offen"-Item
> geschlossen via [ADR 0022](docs/architecture/0022-csp-style-src-unsafe-inline.md):** `'unsafe-inline'`
Expand Down Expand Up @@ -336,9 +350,11 @@ Konsistent mit Moritz' bestehendem `msk-shop`-Projekt:
- **Next.js 16** (App Router, React Server Components, Server Actions, Turbopack)
- **React 19**
- **TypeScript 5.x** (strict mode, `noUncheckedIndexedAccess`)
- **TailwindCSS 4** + **shadcn/ui** (Radix-basiert, accessibility-first)
- **TailwindCSS 4** (CSS-first `@theme`) + **shadcn/ui** (Radix-Primitives, copy-in unter `src/components/ui/`, accessibility-first)
- **Design-System = msk-shop** ([ADR 0025](docs/architecture/0025-adopt-msk-shop-design-system.md), löst ADR 0024 „Modern Minimal" ab): GitHub-Dark-Flächen (`#0d1117`/`#161b22`) + MSK-Grün (`--color-primary` `#5eb131` dark / `#4ea426` light). Token-Vokabular + Idiome (`.eyebrow`, `.msk-card`, `.msk-btn-*`, `.container-page`, `.hero-decor-gradient`) 1:1 aus msk-shop in `src/app/globals.css`, plus Legacy-Alias-Bridge für die Migration.
- **Fonts:** Inter Variable + JetBrains Mono, self-hosted via `@fontsource-variable/*` (kein CDN, kein Build-Time-Fetch, `font-src 'self'`). Ersetzt Geist.
- **lucide-react** für Icons
- **next-themes** (Dark/Light/System)
- **next-themes** (Dark/Light/System, `defaultTheme="dark"` wie msk-shop)
- **next-intl** für i18n (mind. DE + EN)
- **react-markdown** + **remark-gfm** + **rehype-sanitize** für sanitisiertes Markdown-Rendering (Card-Beschreibungen + Kommentare, #33)

Expand Down Expand Up @@ -650,7 +666,7 @@ Cross-Origin-Resource-Policy: same-origin
### 5.8 Import & Export

- **Import von ✅ (#50):** MSKanban-JSON, Trello (JSON), GitHub Projects (`gh project item-list --format json`), Jira (CSV), Wekan (JSON), Plain CSV — alle Konverter in `src/lib/import/foreign.ts` münden in `ExportedBoardV1` → `importBoard()` (E2EE unter frischem BoardKey).
- **Export nach:** MSKanban-natives JSON, **Trello-kompatibles JSON ✅** (`downloadTrelloExport`, „Export Trello"-Button), Markdown (pro Board als .md-Datei mit allen Karten). CSV-Export noch offen.
- **Export nach:** MSKanban-natives JSON, **Trello-kompatibles JSON ✅** (`downloadTrelloExport`, „Export Trello"-Button), Markdown (pro Board als .md-Datei mit allen Karten), **CSV ✅** (`toCsv`/`downloadCsvExport`, „Export CSV"-Button — flach, eine Zeile pro Karte, Custom-Fields als Spalten, RFC-4180-Escaping, UTF-8-BOM für Excel; `tests/unit/csv-export.test.ts`).

### 5.9 Public Read-Only Boards

Expand Down Expand Up @@ -1544,6 +1560,8 @@ mskanban` (+ optional `mskanban-ws`) → `/api/health` Check → deploy-Tag.
| 0021 | Offline-first — hand-rolled Precache-SW (kein Workbox) + card-scoped Write-Outbox (Server-Autorität, LWW, nur idempotente Ops) | accepted |
| 0022 | `style-src 'unsafe-inline'` beibehalten — CSP-Nonces decken keine inline `style`-Attribute (@dnd-kit-Transform); Script-Sink bleibt nonce-gelockt | accepted |
| 0023 | Offline-Create via client-generierte IDs + idempotenter Create (card/comment), Comment-Edit offline-fähig — kein Temp-ID-Reconcile | accepted |
| 0024 | Frontend-Redesign „Modern Minimal" (Geist, `#2ee6a6`) — nur Foundation + Landing gebaut, dann verworfen | superseded by 0025 |
| 0025 | msk-shop Design-System übernehmen (GitHub-Dark + MSK-Grün, Inter/JetBrains Mono, shadcn/ui behalten, kanonische Tokens + Legacy-Alias-Bridge) | accepted |

---

Expand Down
12 changes: 8 additions & 4 deletions docs/architecture/0024-frontend-redesign-modern-minimal.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# 0024 — Frontend redesign: "Modern Minimal" identity + shadcn/ui + Radix

- **Status:** accepted (rollout in phases — this ADR covers the decision; PR1
ships the token + font foundation)
- **Status:** superseded by [ADR 0025](0025-adopt-msk-shop-design-system.md)
(2026-07-12). The "Modern Minimal" identity (Geist, `#2ee6a6` accent) was
dropped in favour of adopting the msk-shop design system verbatim. The
shadcn/ui + Radix primitive foundation introduced here (PR2) is retained and
re-skinned. Kept for historical context.
- **Date:** 2026-06-07
- **Deciders:** Moritz Kohm
- **Supersedes (visual):** the original "MSK design language" (dark + `#00E676`
Expand Down Expand Up @@ -84,6 +87,7 @@ buttons) are then migrated screen-by-screen onto the new primitives in later PRs

## References

- `docs/design/modern-minimal-mockup.html` — the approved direction preview.
- `src/app/globals.css` (tokens), `src/app/layout.tsx` (Geist wiring).
- `docs/design/modern-minimal-mockup.html` — the direction preview (removed
when this ADR was superseded; see the git history of ADR 0025).
- Superseded by [ADR 0025](0025-adopt-msk-shop-design-system.md).
- Memory `design-overhaul-direction`.
103 changes: 103 additions & 0 deletions docs/architecture/0025-adopt-msk-shop-design-system.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# 0025 — Adopt the msk-shop design system (supersedes ADR 0024)

- **Status:** accepted
- **Date:** 2026-07-12
- **Deciders:** Moritz Kohm
- **Supersedes:** [ADR 0024](0024-frontend-redesign-modern-minimal.md) ("Modern
Minimal") — its visual identity (Geist fonts, `#2ee6a6` accent, neutral-gray
surfaces) is dropped. The **shadcn/ui + Radix primitive foundation from ADR
0024 PR2 is kept** and re-skinned; only the identity is replaced.

## Context

ADR 0024 introduced a "Modern Minimal / Linear-esque" identity and installed
shadcn/ui + Radix primitives, but only the landing page was migrated onto it
(the authenticated app still ran on the old hand-rolled idiom). The user then
decided the app should instead look **exactly like the sibling `msk-shop`
project** (`../msk-shop`, www.msk-scripts.de) for a single, consistent MSK brand
across both products, and to keep using shadcn/ui.

`msk-shop` already ships a mature Tailwind v4 CSS-first design system
(`msk-shop/app/globals.css`): GitHub-Dark surfaces + MSK green, Inter + JetBrains
Mono (self-hosted via `@fontsource-variable`), and a set of signature idioms
(`.eyebrow`, `.msk-card`, `.msk-btn-*`, `.container-page`, `.hero-decor-gradient`).

## Decision

### 1. Visual identity → the msk-shop design system, verbatim

Adopt msk-shop's token **values and vocabulary**:

- **Surfaces (dark, default-dark app):** bg `#0d1117`, card/panel `#161b22`,
border `#30363d`, secondary `#21262d`. Light mode: bg `#ffffff`, muted
`#f4f4f5`, border `#e4e4e7`.
- **Brand:** MSK green — `--color-primary` `#5eb131` (dark) / `#4ea426` (light),
white foreground. This is the single action colour (`--color-accent` aliases
the same green in mskanban — we do not introduce msk-shop's separate bright
highlight accent, to avoid a contrast regression on existing buttons).
- **Type:** Inter Variable (sans) + JetBrains Mono (mono), self-hosted via
`@fontsource-variable/*` — no CDN, no build-time fetch (satisfies §16.8 /
`font-src 'self'`). Replaces Geist.
- **Idioms:** `.eyebrow` (mono-uppercase green section label), `.msk-card`,
`.msk-btn-*`, `.container-page`, `.hero-decor-gradient`, `.pulse-dot`.

`next-themes` `defaultTheme` moves from `"system"` to `"dark"` (matches msk-shop
and the "durchgängig dark" MSK brand; `enableSystem` stays so users can still
switch).

### 2. Token vocabulary → msk-shop canonical names, with legacy aliases

The canonical tokens are msk-shop's (`--color-background`, `--color-foreground`,
`--color-primary`, `--color-card`, `--color-muted`, `--color-border`,
`--color-ring`, `--color-secondary`, …). To migrate the ~40 existing screens
**without a breaking big-bang**, `globals.css` also defines a **legacy-alias
block** mapping the old ADR-0024 token names (`--color-bg`, `--color-accent`,
`--color-text-primary`, `--color-bg-panel`, …) onto the canonical ones. Every
not-yet-migrated component therefore keeps rendering correctly in the new
palette. The alias block is removed once all screens use canonical names.

### 3. Component foundation → keep shadcn/ui + Radix, re-skinned

The `src/components/ui/*` primitives (button, input, card, badge, dialog,
dropdown-menu, tabs, tooltip, switch, avatar, label, separator, textarea) are
kept and re-styled on the msk-shop tokens/idioms. Missing primitives are added
via the shadcn copy-in approach as screens need them.

### 4. Rollout → foundation first, then per-screen migration

- **Foundation (one commit):** re-theme `globals.css` (tokens + idioms), swap
fonts (Geist → Inter/JetBrains Mono), `defaultTheme="dark"`, re-skin the
tone-setting primitives (button/input/card/badge). The whole app re-skins to
the msk-shop look immediately via the legacy aliases.
- **Per-screen migration:** each of the ~40 screens is migrated onto the ui/
primitives + msk-shop idioms + canonical tokens. **Presentation only** — no
logic, data-flow, hook, prop, API or crypto changes; all a11y attributes
preserved.
- **Cleanup:** remove the legacy-alias block once no screen references the old
names.

## Consequences

**Positive**

- One consistent MSK brand across msk-shop and MSKanban; components/tokens are
portable between the two repos.
- Whole-app re-skin lands safely in one foundational commit (alias bridge).
- Keeps the a11y-first Radix primitives; no new runtime/CDN/telemetry beyond the
bundled `@fontsource-variable` packages (Geist is removed, net-neutral).

**Negative / interim**

- During the per-screen migration the app runs on a mix of canonical + legacy
token names (both valid, identical output).
- msk-shop's green-on-white / white-on-green button contrast is below WCAG AA
for normal text; we replicate it for brand parity. `color-contrast` stays
ungated in the a11y test suite (§5.10), consistent with the prior decision.

## References

- `../msk-shop/app/globals.css`, `../msk-shop/app/layout.tsx` — the source design
system.
- `src/app/globals.css` (tokens + idioms + legacy aliases), `src/app/layout.tsx`
(font wiring), `src/components/theme-provider.tsx` (`defaultTheme="dark"`).
- Memory `design-overhaul-direction`.
Loading
Loading