Files
schalli bec0530a2b
Tessera CI/CD / Lint & Type Check (push) Successful in 47s
Tessera CI/CD / Tests (push) Successful in 50s
Tessera CI/CD / Build & Publish Images (push) Successful in 1m51s
docs(quick-260907-fgv): Abnahme dokumentiert, Quick-Task abgeschlossen
Task 3 (Browser-Abnahme) ist durchgefuehrt. Von den beiden zur Freigabe gestellten
Gestaltungsfragen wurde eine zurueckgewiesen und eine blieb offen:

Die Anordnung auf dem Anmelde-Panel hat der User weder als "Marke oben" noch als
"Marke unten" abgenommen, sondern eine dritte Loesung verlangt — Logo links, Text
rechts daneben, wie in der gelieferten Schriftzug-Datei. Nachgezogen mit 11c0ec6.

Zur Schriftzugfarbe hat er sich nicht geaeussert; sie bleibt vorerst dunkel, die
Rueckkehr zu Gelb wurde als jederzeit moeglich angeboten.

Ausserdem in der SUMMARY festgehalten, dass die Abnahme einen Defekt ausserhalb dieses
Plans aufgedeckt hat: die Tailwind-Dunkelvariante war nie an die .dark-Klasse gebunden
(WINDOWS #13, behoben mit f8d7da0). Der Logo-Einbau hat ihn nur sichtbar gemacht,
verursacht hat er ihn nicht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5jtbGzC5Sf9npJ3JCjKhq
2026-09-07 12:50:43 +02:00

17 KiB

phase, plan, subsystem, tags, requires, provides, affects, actuals, plan_head_before, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals plan_head_before tech-stack key-files key-decisions requirements-completed coverage duration completed status
quick-260907-fgv 01 ui
branding
nextjs
app-router
next-intl
tailwind
vitest
favicon
Zentrale Bildmarken-Komponente TesseraLogo (mark/horizontal/stacked) fuer alle Marken-Stellen der Oberflaeche
brand.ts als einzige Markenfarben-Quelle im Web-Quellcode (BRAND_YELLOW, BRAND_OLIVE, BRAND_PLATE)
Dateibasierte Next.js-Icon-Metadaten (icon.svg, apple-icon.png) fuer den Browser-Tab
common.brand.logoAlt in de.json/en.json mit Schluesselparitaets-Test
branding
login
reset-password
account-settings
header
sidebar
tokens tasks commits
4931 2 2
17a8355
added patterns
Markenfarben ausschliesslich als benannte TypeScript-Konstanten (nicht als CSS-Variable), damit sowohl JSX-Fuellwerte als auch ein <input type="color">-Vorgabewert dieselbe Quelle lesen koennen
Bildmarke als handgesetztes JSX-SVG statt eingebetteter Fremd-Datei -- verhindert jede Form von dangerouslySetInnerHTML fuer Lieferanten-Content (T-FGV-01)
Schriftzug ohne eigene Textfarben-Klasse: er erbt die Vordergrundfarbe ueber normale CSS-Kaskade vom naechsten Vorfahren (body text-foreground im Normalfall, text-gray-900 auf dem gelben Anmelde-Panel) statt uber sich gegenseitig ueberschreibende Tailwind-Utilities gleicher Spezifitaet
created modified
apps/web/src/app/icon.svg
apps/web/src/app/apple-icon.png
apps/web/src/components/brand/brand.ts
apps/web/src/components/brand/tessera-logo.tsx
apps/web/src/components/brand/tessera-logo.test.tsx
apps/web/src/messages/de.json
apps/web/src/messages/en.json
apps/web/src/components/layout/header.tsx
apps/web/src/components/layout/sidebar.tsx
apps/web/src/components/layout/sidebar.test.tsx
apps/web/src/app/(auth)/login/page.tsx
apps/web/src/app/(auth)/reset-password/page.tsx
apps/web/src/app/(auth)/reset-password/[token]/page.tsx
apps/web/src/components/settings/account-settings-form.tsx
Von den sechs gelieferten Dateien wurden nur favicon.svg (-> icon.svg) und apple-touch-icon.png (-> apple-icon.png) ins Repository uebernommen. tessera-logo.svg entfaellt, weil cmp sie byteidentisch zu favicon.svg ausweist. tessera-logo-schriftzug.svg entfaellt, weil ihre Textfarbe zweimal fest eingebacken ist (im dunklen Erscheinungsbild unsichtbar) UND weil sie die nicht geladene Schriftart Archivo voraussetzt -- die Anwendung laedt ausschliesslich Inter. favicon-16.png/favicon-32.png entfallen, weil jeder unterstuetzte Browser SVG-Favicons zeigt. tessera-logo-512.png entfaellt, weil kein Web-App-Manifest existiert, das sie braeuchte.
Der Schriftzug ist echter HTML-Text aus common.appName, keine Bilddatei -- er erbt automatisch die richtige Farbe, bricht nie um und bleibt uebersetzbar.
Die dunkle Grundplatte bekommt im dunklen Erscheinungsbild eine halbtransparente helle Haarlinie (Tailwind dark:stroke-white/25), weil sie sonst mit dem fast identischen dunklen Anwendungshintergrund verschmelzen wuerde. Ueber plateOutline={false} ist die Kontur auf dem immer-gelben Anmelde-Panel abgeschaltet, wo sie falsch waere.
Der Gelbwert der Marke steht jetzt an genau einer Stelle (brand.ts:BRAND_YELLOW). Anmelde-Panel und der Vorgabewert der persoenlichen Akzentfarbe lesen ihn von dort. Der Token --primary in globals.css bleibt bewusst unberuehrt -- er ist rechnerisch ein anderer Ton und steuert Schaltflaechen/Fokusringe/Aktivmarkierungen der gesamten Anwendung; ihn auf den Markenwert zu ziehen waere eine Umfaerbung, die nicht Teil dieser Aufgabe ist.
Rule 1 (Bugfix waehrend Task 2 entdeckt): TesseraLogo setzte in Task 1 noch eine feste text-foreground-Klasse auf den Schriftzug. Auf dem immer-gelben Anmelde-Panel (Task 2) haette das im dunklen Erscheinungsbild helle Schrift auf Gelb erzeugt -- kaum lesbar. Behoben, indem der Schriftzug gar keine eigene Farb-Klasse mehr setzt und stattdessen per CSS-Vererbung die Farbe des umgebenden Containers uebernimmt (body text-foreground normalerweise, text-gray-900 auf dem Anmelde-Panel).
QUICK-260907-FGV
id description requirement verification human_judgment
D1 Icon-Dateien fuer den Browser-Tab (icon.svg, apple-icon.png) byteidentisch zur Lieferung unter src/app/ QUICK-260907-FGV
kind ref status
other cmp user-files/logo/favicon.svg apps/web/src/app/icon.svg && cmp user-files/logo/apple-touch-icon.png apps/web/src/app/apple-icon.png pass
false
id description requirement verification human_judgment
D2 brand.ts als einzige Markenfarben-Quelle; Gelbwert kommt im Web-Quellcode genau einmal vor QUICK-260907-FGV
kind ref status
other grep -rl 'ffed00' apps/web/src --include='*.ts' --include='*.tsx' -> nur brand.ts pass
false
id description requirement verification human_judgment
D3 TesseraLogo-Komponente mit drei Varianten (mark/horizontal/stacked), dunkle Kontur nur im dunklen Erscheinungsbild und nur wenn plateOutline nicht deaktiviert ist QUICK-260907-FGV
kind ref status
unit apps/web/src/components/brand/tessera-logo.test.tsx (8 Tests) pass
false
id description requirement verification human_judgment
D4 common.brand.logoAlt in de.json und en.json, Schluesselparitaet abgesichert QUICK-260907-FGV
kind ref status
unit apps/web/src/components/brand/tessera-logo.test.tsx#common.brand i18n namespace — de/en key parity pass
false
id description requirement verification human_judgment
D5 Alle sechs Marken-Stellen (Kopfleiste, Seitenleisten-Schublade, Anmeldeseite breit+schmal, beide Passwort-Seiten) ziehen TesseraLogo; Platzhalter-Icon und Hand-Schriftzug entfernt QUICK-260907-FGV
kind ref status
other grep -q TesseraLogo je Datei + grep font-extrabold in (auth) liefert 0 Treffer pass
false
id description verification human_judgment rationale
D6 Visuelle Abnahme im Browser (Task 3, checkpoint:human-verify) -- beide Erscheinungsbilder, sieben Stellen, plus zwei Gestaltungsfragen (Schriftzugfarbe, Reihenfolge auf dem Anmelde-Panel)
true Kontrast, Kontur-Sichtbarkeit und die zwei zur Freigabe gestellten Gestaltungsaenderungen lassen sich nur visuell beurteilen. Task 3 ist absichtlich noch nicht ausgefuehrt -- der Orchestrator uebernimmt Docker-Neubau und Browser-Pruefung.
35min 2026-09-07 complete

Phase quick-260907-fgv Plan 01: Tessera-Logo und Favicon fest einbauen — Summary

TesseraLogo-Komponente und brand.ts eingefuehrt, sechs Marken-Stellen umgestellt, Icon-Dateien byteidentisch uebernommen — Task 3 (Browser-Abnahme) steht noch aus.

Performance

  • Duration: ca. 35 min
  • Tasks: 2 von 3 (Task 3 ist checkpoint:human-verify, bewusst nicht ausgefuehrt)
  • Files modified: 14 (5 neu, 9 geaendert)

Accomplishments

  • Gelieferte favicon.svg und apple-touch-icon.png byteidentisch nach apps/web/src/app/icon.svg bzw. apps/web/src/app/apple-icon.png kopiert; die uebrigen vier gelieferten Dateien bleiben mit dokumentierter Begruendung ausserhalb des Repositories.
  • apps/web/src/components/brand/brand.ts angelegt: die drei Markenfarben (BRAND_YELLOW, BRAND_OLIVE, BRAND_PLATE) stehen jetzt an genau einer Stelle im Web-Quellcode.
  • TesseraLogo-Komponente gebaut (Varianten mark/horizontal/stacked), als handgesetztes JSX-SVG ohne dangerouslySetInnerHTML, mit schaltbarer dunkler Kontur der Grundplatte (plateOutline).
  • Alle sechs Marken-Stellen umgestellt: Kopfleiste, Seitenleisten-Schublade, Anmeldeseite (breite und schmale Ansicht), beide Passwort-Seiten. Der handgezeichnete Vier-Quadrate-Platzhalter auf der Anmeldeseite ist entfernt.
  • common.brand.logoAlt in de.json und en.json ergaenzt, Schluesselparitaet per Test abgesichert.
  • Vollstaendige Web-Testsuite (37 Testdateien, 221 Tests) und Typpruefung sind gruen.

Warum der Schriftzug Text ist, kein Bild

Zwei unabhaengige Gruende. Erstens die Farbe: tessera-logo-schriftzug.svg haelt die Textfarbe zweimal fest als dunklen Ton — im dunklen Erscheinungsbild der Anwendung waere der Schriftzug unsichtbar. Zweitens die Schrift: die Datei verlangt Archivo in Schnitt 900, die Anwendung laedt aber ausschliesslich Inter (--font-sans in globals.css) — der Browser wuerde eine Ersatzschrift mit anderen Buchstabenbreiten in einen starr fixierten Zeichenbereich zwingen. "Tessera" als normaler HTML-Text aus common.appName loest beide Probleme: er erbt die richtige Farbe, bricht nie um, bleibt uebersetzbar.

Kontur der dunklen Platte

Nachgerechnet: die Plattenfarbe (#1a1a1a) und der dunkle Anwendungshintergrund (oklch(0.23 0.01 260) = #1a1d22) sind praktisch derselbe Ton — ohne Gegenmassnahme wuerde die Platte im dunklen Erscheinungsbild verschwinden und die fuenf Kacheln wuerden frei schweben. Deshalb bekommt die Platte ueber eine dark:stroke-white/25-Utility eine halbtransparente helle Haarlinie, die im hellen Erscheinungsbild unsichtbar bleibt (stroke-transparent). Auf dem gelben Anmelde-Panel ist die Kontur ueber plateOutline={false} abgeschaltet, weil dieses Panel unabhaengig vom Erscheinungsbild immer gelb ist und dort ohnehin maximaler Kontrast besteht.

Gelbwert: eine Quelle, --primary bewusst unberuehrt

brand.ts:BRAND_YELLOW ist jetzt die einzige Stelle im Web-Quellcode, an der der Markengelbwert notiert steht. Das Anmelde-Panel (Inline-style) und der Vorgabewert der persoenlichen Akzentfarbe (account-settings-form.tsx:DEFAULT_ACCENT) lesen ihn von dort. Der bestehende Design-Token --primary in globals.css bleibt unveraendert — er ist rechnerisch ein leicht anderer Ton und steuert Schaltflaechen, Fokusringe und Aktivmarkierungen der gesamten Anwendung. Ihn auf den Markenwert zu ziehen waere eine Umfaerbung der gesamten Oberflaeche und war nicht Teil dieser Aufgabe.

Task Commits

  1. Task 1: Markenbausteine — Icon-Dateien, Farbkonstanten, TesseraLogo-Komponente, i18n-Schluessel — 49d3df4 (feat)
  2. Task 2: Alle sechs Marken-Stellen auf die Komponente umstellen und den Gelbwert zusammenfuehren — c4cc05a (feat)

Task 3 (checkpoint:human-verify, Browser-Abnahme in beiden Erscheinungsbildern) ist noch offen — siehe unten.

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] Schriftzug-Textfarbe entfernt statt fest gesetzt

  • Found during: Task 2 (Einbau auf dem gelben Anmelde-Panel)
  • Issue: tessera-logo.tsx setzte in Task 1 noch text-foreground direkt auf den Schriftzug. Auf dem immer-gelben Anmelde-Panel haette das im dunklen Erscheinungsbild helle Schrift auf gelbem Grund erzeugt (kaum lesbar), weil eine explizite Tailwind-Farbklasse nicht zuverlaessig von einer Vorfahren-Klasse gleicher Spezifitaet ueberschrieben werden kann.
  • Fix: Der Schriftzug setzt keine eigene Textfarben-Klasse mehr und erbt die Farbe stattdessen per normaler CSS-Kaskade vom umgebenden Container. Auf normalen Seiten ist das text-foreground von <body> (layout.tsx), auf dem Anmelde-Panel das explizit gesetzte text-gray-900 am inneren Container.
  • Files modified: apps/web/src/components/brand/tessera-logo.tsx
  • Commit: c4cc05a

2. [Rule 1 - Bug] Ungenutzte Variable tCommon in sidebar.tsx entfernt

  • Found during: Task 2
  • Issue: Nach dem Ersetzen des Schriftzugs durch TesseraLogo war const tCommon = useTranslations('common'); in sidebar.tsx nicht mehr referenziert.
  • Fix: Zeile entfernt.
  • Files modified: apps/web/src/components/layout/sidebar.tsx
  • Commit: c4cc05a

Bewusst ausgelassen (per Ausfuehrungs-Anweisung)

Der Docker-Neubau (docker compose build web && docker compose up -d --force-recreate web) und der curl-Health-Check am Ende des Task-2-Verify-Blocks wurden NICHT ausgefuehrt — die Ausfuehrungs-Anweisung fuer diesen Lauf untersagt es ausdruecklich ("Do NOT rebuild Docker images — the orchestrator does that"). Alle anderen Verify-Schritte (Byte-Vergleich der Icons, vollstaendige Testsuite, Typpruefung, grep-Checks) wurden real ausgefuehrt und sind gruen.

Known Stubs

Keine.

Threat Flags

Keine neue, im Plan nicht bereits erfasste Angriffsflaeche. Die drei im Plan gefuehrten Bedrohungen (T-FGV-01 Tampering ueber tessera-logo.tsx, T-FGV-02 Information Disclosure ueber icon.svg, T-FGV-03 Tampering ueber user-files/logo/) sind wie geplant behandelt: kein dangerouslySetInnerHTML, keine Laufzeit-Dateilesung, Byte-Vergleich im Verify-Schritt bestanden.

Ausstehend: Task 3 (Browser-Abnahme)

Task 3 ist ein checkpoint:human-verify mit gate="blocking-human" und wurde absichtlich nicht ausgefuehrt. Der Orchestrator baut das lokale Web-Abbild neu, startet den Container und fuehrt die Browser-Pruefung durch. Zwei Gestaltungsfragen stehen dabei zur Freigabe oder Zurueckweisung:

  1. Schriftzugfarbe: "Tessera" ist in Kopfleiste und Schublade jetzt dunkel (bzw. hell im dunklen Erscheinungsbild) statt wie bisher gelb. Passt das, oder soll das bisherige Gelb zurueck?
  2. Reihenfolge auf dem Anmelde-Panel: Die Bildmarke steht jetzt oben auf dem gelben Panel statt wie bisher unten unter dem Text. Passt diese Reihenfolge, oder soll die Marke wieder unter den Text?

Task 3 — Abnahme durchgefuehrt am 2026-09-07

Der Orchestrator hat das Web-Abbild neu gebaut und die Oberflaeche im echten Browser in hellem und dunklem Erscheinungsbild geprueft. Ergebnis:

Frage 2 (Anordnung auf dem Anmelde-Panel) — zurueckgewiesen. Der User hat weder "Marke oben" noch "Marke unten" gewaehlt, sondern eine dritte Anordnung verlangt: "Logo links, Text rechts daneben" — also nebeneinander statt untereinander, wie in der gelieferten Datei tessera-logo-schriftzug.svg. Nachgezogen mit Commit 11c0ec6: die horizontale Variante nimmt jetzt einen optionalen Untertitel entgegen und stellt rechts neben der Marke den Namen und darunter den Untertitel. Die gestapelte Variante entfiel dabei — sie war danach nirgends mehr im Einsatz.

Frage 1 (Schriftzugfarbe) — offen geblieben. Der User hat direkt die Anordnung entschieden und sich zur Farbe nicht geaeussert. Der Schriftzug bleibt vorerst dunkel (hell im dunklen Erscheinungsbild); die Rueckkehr zu Gelb ist ein Einzeiler und wurde dem User als jederzeit moeglich angeboten.

Ein Defekt ausserhalb dieses Plans, bei der Abnahme gefunden

Die im Plan vorgesehene Plattenkontur dark:stroke-white/25 griff im dunklen Erscheinungsbild nicht. Am laufenden System gemessen war der Grund nicht die Marke, sondern die Grundeinstellung von Tailwind: globals.css deklarierte kein @custom-variant dark, sodass die dark:-Variante an prefers-color-scheme hing — also an der Einstellung des Betriebssystems — waehrend die Anwendung den Modus ueber next-themes per Klasse schaltet. Damit blieb jede dark:-Utility im Web-Quellcode wirkungslos, sobald System und Portal-Einstellung auseinanderlagen: ueber 100 Vorkommen in mehr als zehn Dateien, darunter Status-, Warn- und Fehlerfarben, Hinweisboxen und Badges in der Administration.

Unentdeckt geblieben war das, weil Hintergrund und Textfarbe nicht ueber dark: laufen, sondern ueber die Farbtokens unter .dark — die Oberflaeche wurde also grundsaetzlich dunkel, nur die Feinheiten fehlten.

Behoben mit Commit f8d7da0, erfasst und geschlossen als WINDOWS.md #13. In beide Richtungen nachgemessen: im dunklen Modus greifen dark:-Angaben jetzt und die Kontur steht weiss mit 25 Prozent Deckkraft, im hellen Modus greifen sie weiterhin nicht und die Kontur bleibt unsichtbar.

Sprachbefund am Rande

Auf der Anmeldeseite faellt "Modulare Workflow-Plattform fuer Ihr Unternehmen" auf. Die deutschen Texte schreiben Umlaute an 29 Stellen als Buchstabenpaare aus. Nicht Teil dieses Plans, als Backlog-Punkt 2026-09-07-umlaute-in-der-oberflaeche.md abgelegt.

Vermerkter Backlog-Punkt (nicht in diesem Plan gebaut)

"Administrator kann das Erscheinungsbild je Mandant anpassen — eigenes Logo hochladen, Markenfarben setzen." Ansatzpunkt ist apps/web/src/components/brand/; die Oberflaeche zieht das Logo bereits ausschliesslich von dort. Eingereicht als .planning/todos/pending/2026-09-07-mandanten-branding-logo-und-farben.md.

Self-Check: PASSED

  • apps/web/src/app/icon.svg — FOUND, byteidentisch zu user-files/logo/favicon.svg
  • apps/web/src/app/apple-icon.png — FOUND, byteidentisch zu user-files/logo/apple-touch-icon.png
  • apps/web/src/components/brand/brand.ts — FOUND
  • apps/web/src/components/brand/tessera-logo.tsx — FOUND
  • apps/web/src/components/brand/tessera-logo.test.tsx — FOUND
  • Commit 49d3df4 — FOUND in git log
  • Commit c4cc05a — FOUND in git log