Basis: Certvia dev@a48c5fb als Fundament für Craftvia
CI / build-and-check (push) Canceled after 0s
CI / audit (push) Canceled after 0s
CI / sbom (push) Canceled after 0s

Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation
und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 11:05:39 +02:00
co-authored by Claude Opus 5
commit c8e6f30a27
720 changed files with 140143 additions and 0 deletions
+149
View File
@@ -0,0 +1,149 @@
# Branding-Umstellung auf Certvia — Inventar & Umsetzung
> Branch `dev-branding-certvia` (Basis `dev`) · Quelle: `Aufgabenpaket-Branding-Certvia.md` + `Certvia-Assets/`
> Leitplanke: **GEFIM bleibt Dachmarke** („Ein Produkt von GEFIM"), nur die **Produktmarke** wird Certvia.
> Reines Branding — **keine Funktionsänderung**, kein Umbau von Logik oder Datenmodell.
---
## 1. Design-Tokens (verbindliche Referenz)
**Markenfarben** (Logo, Print, Verläufe — `--brand-*`):
| Rolle | Token | Hex |
|---|---|---|
| Violett (Marke) | `--brand-violet` | `#5d52a3` |
| Magenta (Akzent „via", Haken) | `--brand-magenta` | `#812d80` |
| Hellblau | `--brand-blue` | `#8dc4e0` |
| Anthrazit (Text/Headlines) | `--brand-anthracite` | `#3b3b3a` |
| Violett auf Dunkel | `--brand-violet-on-dark` | `#7d6fd6` |
| Magenta auf Dunkel | `--brand-magenta-on-dark` | `#d17bcf` |
**UI Dark-Theme** (unverändert — **ist** die Certvia-Produktpalette, nicht „korrigieren"):
`--ui-primary #7d6fd6` · `--ui-primary-deep #5d52a3` · `--ui-blue #8dc4e0` · `--ui-magenta #b45bb0` ·
`--bg-0 #0e1220` · `--bg-1 #141a2e` · `--elevated #1a2138` · `--panel rgba(30,38,64,.72)` ·
`--panel-brd rgba(120,135,180,.18)` · `--foreground #e8ecf7` · `--muted-foreground #8b93ad` ·
`--ok #39c07f` · `--warn #f0ad4e` · `--risk #ff6b6b` · Primär-Verlauf `linear-gradient(135deg,#5d52a3,#7d6fd6)`
· Fokus-Ring `rgba(125,111,214,.35)`.
Single Source of Truth: **`src/app/globals.css`** (CSS) und **`src/lib/brand.ts`** (JS/TS — für alles,
was CSS-Variablen nicht auflösen kann: Canvas-/PNG-Export, Metadaten, künftige Dokument-Exporte).
**Typografie:** Headlines/Wortmarke **Poppins**, Fließtext **Open Sans** — self-hosted (`src/app/fonts/`).
---
## 2. Inventar (Story S0)
### 2.1 Produktmarke → Certvia
| Datei | Fundstelle | Maßnahme | Story |
|---|---|---|---|
| `src/app/globals.css` | `--gefim-violet/-deep/-blue/-magenta`, Kommentare „GEFIM-Theme" | Umbenannt auf `--brand-*` / `--ui-*`, Kommentare auf Certvia | S1/S9 |
| `src/app/globals.css` | Flächenfarben direkt als Hex (`#0e1220`, `#141a2e`, …) | Über `--bg-0`/`--bg-1`/`--elevated` geführt, semantische Tokens referenzieren sie | S1 |
| `src/components/risk-modals.tsx` | `bg-[#0e1220]` (Rest-Risiko-Marker, Legende) | → `bg-[var(--bg-0)]` | S1 |
| `src/app/(app)/risks/page.tsx` | `bg-[#0e1220]/75`, `hover:bg-[#0e1220]` (Heatmap-Chip) | → Token `--chip-overlay` / `var(--bg-0)` | S1 |
| `src/components/dependency-graph.tsx` | `#8dc4e0`, `#ff6b6b`, `#141a2e`, `#0e1220`, `#4a5372`, `#8b93ad` | CSS-Vars wo möglich; PNG-Export nutzt `BRAND.ui` aus `src/lib/brand.ts` (html-to-image löst keine CSS-Vars auf) | S1 |
| `public/gefim-logo.png` | Produktlogo in Sidebar + Login | Verschoben nach `public/assets/logo/gefim-logo.png`, dient nur noch der **Dachmarke** | S2 |
| `src/app/(app)/layout.tsx` | Sidebar-Logo `/gefim-logo.png`, Alt-Text „GEFIM …" | `<CertviaLogo variant="lockup" theme="dark">` über den Branding-Resolver | S2/S8 |
| `src/app/login/page.tsx` | Logo `/gefim-logo.png`, Alt-Text | Certvia-Lockup + Tagline + Dachmarken-Fußnote | S2/S7 |
| `src/app/platform/login/page.tsx` | kein Logo | Certvia-Lockup + „Plattform-Administration" | S2/S7 |
| `src/app/(platform)/layout.tsx` | `ShieldCheck` + „ISMS · Plattform-Administration" | Certvia-Mark + „Certvia · Plattform-Administration" | S2/S3 |
| `src/app/layout.tsx` | `title: "ISMS-Tool"`, keine Icons/OG/Manifest | Vollständige Certvia-Metadaten inkl. Icons, Manifest, `themeColor` | S3 |
| `src/app/favicon.ico` | Next-Default-Favicon | Entfernt; Icons laufen über `public/favicon/` + `metadata.icons` | S2 |
| `messages/de.json`, `messages/en.json` | `common.appName` = „ISMS-Tool"/„ISMS Tool" | → „Certvia" (+ `appTagline`, `appByline`) | S3 |
| `src/server/mfa.ts` | TOTP-Issuer `"ISMS-Tool · Plattform"` | → `"Certvia · Plattform"` | S3 |
| `src/components/ui/button.tsx` | Kommentar „GEFIM-Verlauf" | → „Certvia-Verlauf" | S9 |
| `src/components/mockup-ui.tsx` | Kommentar-Referenz auf Mockup-Datei | Formulierung entschärft (Dateiname bleibt, s. u.) | S9 |
| `src/lib/control-titles.ts` | Kommentar „aus dem GEFIM-Mockup übernommen" | → neutral „aus dem UI-Mockup" | S9 |
| `src/app/(app)/settings/page.tsx` | Hinweis „Logo-Upload folgt in Phase 2" | Ergänzt um Certvia-Default-Aussage | S8 |
| `src/proxy.ts` | Matcher schloss `.webmanifest` nicht aus | `/site.webmanifest` lieferte die Login-HTML statt JSON → Endung ergänzt (siehe §5) | S3 |
### 2.2 Dachmarke GEFIM → bleibt bewusst erhalten
| Ort | Grund |
|---|---|
| `public/assets/logo/gefim-logo.png` | Dachmarken-Logo für „Ein Produkt von GEFIM" |
| `src/components/brand/powered-by-gefim.tsx` | Neue Komponente, die genau diesen Hinweis rendert (Login, Plattform-Login, Print-/Export-Fußzeile, Mail-Footer) |
| `docs/ISMS-*-GEFIM.html`, Verweise in `README.md`/`AGENTS.md`/`docs/SPEC.md` | Historische Mockups/Spezifikation — Projektartefakte, keine Produkt-UI |
| `prisma/seed.ts` (`ORG_NAME` „GEFIM Demo GmbH") | **Demo-Mandantendaten** (fiktiver Kunde), nicht der Produktname |
| `prisma/import-managed.ts` (`portal.gefim.example`) | Demo-Registerzeile, nicht der Produktname |
Nach der Umstellung liefert `rg -i "gefim"` ausschließlich diese Kategorien.
---
## 3. Umgesetzte Stories
| Story | Inhalt | Status |
|---|---|---|
| **S0** | Inventar (dieses Dokument) | ✅ |
| **S1** | Token-Zentralisierung `--brand-*` / `--ui-*`, `src/lib/brand.ts`, hartkodierte Farben ersetzt | ✅ |
| **S2** | Assets eingebunden, `<CertviaLogo>`, Favicon/PWA-Icons, Sidebar + beide Logins | ✅ |
| **S3** | App-Name/Meta/OG/Manifest/i18n/MFA-Issuer auf Certvia | ✅ |
| **S4** | Poppins + Open Sans self-hosted bestätigt (waren es bereits), Fallback-Stack + `swap` geprüft | ✅ |
| **S7** | Login, Plattform-Login, Change-Password, Enroll-MFA, Konto-deaktiviert, 404, 500 gebranded | ✅ |
| **S9** | Produkt-Referenzen bereinigt, Dachmarke belassen | ✅ |
| **S5** | Branding-Layer für Dokument-/Export-CD (`src/lib/brand.ts` + Print-Stylesheet) | ✅ (Andockpunkt) |
| **S8** | Branding-Resolver mit Certvia-Default, Custom überschreibt nur wenn gesetzt | ✅ |
| **S6** | Brandfähige E-Mail-Template-Basis (SMTP selbst folgt in Paket 4) | ✅ (Basis) |
---
## 4. Wo liegt was (neu)
| Pfad | Inhalt |
|---|---|
| `src/lib/brand.ts` | Marken-/UI-Farben als JS-Konstanten, Produktname/Tagline/Byline, Asset-Pfade, `resolveTenantBranding()` |
| `src/lib/document-brand.ts` | Dokument-CD (helles Theme, Kopf-/Fußzeilen-Bausteine) — Andockpunkt für DOCX/PDF |
| `src/lib/email-brand.ts` | Brandfähige HTML-/Text-Mail-Basis für Paket 4 |
| `src/components/brand/certvia-logo.tsx` | `<CertviaLogo variant="lockup\|mark" theme="light\|dark" />` als Inline-SVG |
| `src/components/brand/tenant-brand.tsx` | Mandanten-Marke mit Certvia-Fallback |
| `src/components/brand/powered-by-gefim.tsx` | Dachmarken-Hinweis inkl. GEFIM-Logo |
| `public/assets/logo/` | Certvia-SVGs/PNGs + GEFIM-Dachmarkenlogo |
| `public/favicon/`, `public/favicon.ico`, `public/site.webmanifest` | App-Icons und PWA-Manifest |
| `docs/branding/` | Aufgabenpaket + Logo-README aus dem Design-Paket |
| `src/app/globals.css` (`@media print`) | Druck-/Dokument-CD |
---
## 5. Beim Einbau aufgefallen (Abweichungen vom Aufgabenpaket)
- **Lockup-SVG trägt Poppins jetzt eingebettet.** `public/assets/logo/certvia-lockup-positiv.svg`
enthält Poppins 300 + 700 als woff2-Data-URI (≈22 KB). Damit erscheint die Wortmarke auch
außerhalb der App korrekt (Druck, Export, Mail) — der offene Punkt „Text in Pfade wandeln" aus
`docs/branding/README-Logo.md` ist damit erledigt. Geometrie und Farben sind unverändert.
In der App rendert `<CertviaLogo>` das Zeichen ohnehin inline und nutzt die App-Schrift direkt.
- **`/site.webmanifest` war nicht erreichbar.** Der Route-Gate-Matcher in `src/proxy.ts` nahm nur
`svg|png|jpg|ico` aus — für `.webmanifest` lieferte der Server die Login-Seite statt JSON, das
PWA-Manifest wäre also wirkungslos geblieben. Endung ergänzt. Bewusst **keine** Verzeichnis-
Ausnahme für `assets/`: das ist zugleich die App-Route des Asset-Inventars und bleibt hinter dem
Gate (nachgeprüft: `/assets`, `/assets/xyz` → 307 auf `/login`).
- **`src/app/favicon.ico` entfernt.** Die Datei-Konvention von Next.js und eine `public/favicon.ico`
schließen sich gegenseitig aus; die Icons laufen jetzt vollständig über `metadata.icons`.
- **404-/500-Seiten neu angelegt** (`src/app/not-found.tsx`, `src/app/error.tsx`) — es gab bisher
keine. Sie erscheinen für angemeldete Nutzer; anonyme Aufrufe fängt weiterhin das Login-Gate ab.
### Kontrast (WCAG AA, geprüft)
| Kombination | Kontrast | Bewertung |
|---|---|---|
| Magenta `#812d80` auf Weiß (Wortmarke/Print) | 8,0 : 1 | AA + AAA |
| Magenta `#d17bcf` auf Karte `#141a2e` | 6,1 : 1 | AA |
| Magenta `#d17bcf` auf Seitengrund `#0e1220` | 6,6 : 1 | AA |
---
## 6. Bewusste Abgrenzungen
- **UI-Palette unverändert.** Die Dark-Theme-Farben wurden nur konsolidiert/umbenannt, nicht geändert.
`--brand-violet` (`#5d52a3`) gilt für Logo/Print/Verläufe, `--ui-primary` (`#7d6fd6`) für Interaktion.
- **Kein Light-Mode.** Die App ist bewusst dark-only; `<CertviaLogo theme="light">` existiert für
Dokument-/Druck-/Mail-Kontexte, wird in der UI aber nicht verwendet.
- **Poppins 400** ist nicht als woff2 im Repo (vorhanden: 300/500/600/700). Aktuell nutzt nichts
Poppins 400 — Headlines laufen auf 600/700, die Wortmarke auf 300/700. Sollte 400 gebraucht werden,
muss die woff2 ergänzt werden; ein CDN-Fetch bleibt ausgeschlossen.
- **Logo-Upload je Mandant** braucht Objektspeicher (Admin Phase 2). Der Resolver ist bereits darauf
vorbereitet (`logoUrl` optional), das Feld existiert im Schema noch nicht — bewusst keine Migration.
- **DOCX/PDF-Export** existiert noch nicht. S5 liefert den Branding-Layer (Konstanten + Kopf-/Fußzeile
+ Print-CSS), an den das Export-Feature andockt.