refactor(startseite): Meetingraum als Fotoszene mit Live-Auslastung

Die gezeichnete Raumkulisse ist ersetzt. Aus Farbflächen konstruierte Wände
bleiben neben fotografierten Agentenporträts erkennbar gezeichnet — die
Bildwirkung muss aus dem Foto kommen, nicht aus Geometrie. Entfallen sind
damit die beiden SVG-Stadtansichten, die CSS-3D-Flächen und die Farbwelt
DS_MEETING_ROOM.

Neu trägt die Szene die Basler Aussicht aus dem Auftrag als Foto (§5), mit
abgestuftem Verlauf für Lesbarkeit und Übergang zur Objektliste. Ein Austausch
des Motivs ist ein Einzeiler in `roomBackdrop.ts`.

Mehrwert statt Kulisse: Jedes Namensschild zeigt die aktuelle Auslastung
seines Agenten — überfällige Fristen, Termine der Woche, offene Exposés, neue
Marktchancen, Objekte mit Datenlücken, offene Freigaben. Darüber fasst ein
Anriss zusammen, wie viele Bereiche heute Aufmerksamkeit brauchen. Damit
beantwortet die Startseite die Frage, mit der sie geöffnet wird, statt sie
auf sechs Zahlen zu verteilen.

- `agentWorkloadService` hält die fachlichen Festlegungen: Zeitfenster,
  Dringlichkeitsschwellen und Formulierungen. Der Stichzeitpunkt ist ein
  Parameter, nicht die Systemuhr — dieselbe Datenlage ergibt dasselbe
  Ergebnis, und der Dienst ist ohne Renderer prüfbar (10 neue Tests).
- `useAgentWorkload` sammelt nur die Bestände ein.
- Noras Zahl wird nie «dringend»: sie schlägt vor, sie entscheidet nicht.
- Die Schilder bemessen ihre Höchstbreite an der Szenenbreite (`cqw`), nicht
  am Fenster. Am Fenster gemessen überlappten sie auf schmalen Laptops, weil
  die Szene um das Seitenmenü schmaler ist.

Geprüft: 423 Tests, Typecheck, Build, ESLint, Token-Schwelle (889/925).
Im Browser 1280–1920 px: keine Überlappungen, Titel und «Filter & Übersicht»
beim Einstieg sichtbar, alle sechs Agentenklicks auf der richtigen Subpage,
Tablet-Ansicht mit allen sechs Agenten, keine Konsolenfehler, keine 404.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin SutterandClaude Opus 5 committed 2026-08-06 14:07:21 +02:00
1 parent 9ed21e33a7
commit d8f8f728cc
13 files changed
+717 -568

No files matched your search

-73
View File
@@ -292,79 +292,6 @@ export const RESULT_TYPE_META: Record<string, { label: string; color: string; bg
FUTURE_AVAILABILITY: { label: 'Zukunftssignal', color: '#5b3f8a', bg: 'rgba(91,63,138,0.10)' },
}
// ── Agenten-Meetingraum auf der Startseite (Runde 5, §3) ─────────────────────
/**
* Farbwelt der Meetingraum-Szene.
*
* Die Szene ist eine reine 2D-/CSS-Komposition ohne 3D-Bibliothek — sie besteht
* deshalb aus ungewöhnlich vielen Einzelflächen: Decke, Wände, Boden, Tischplatte,
* Fensterrahmen sowie die Basler Aussicht mit Rhein, Altstadt und Münster.
*
* Sie stehen hier statt in der Komponente, weil eine Szene mit vierzig
* Farbstufen in der Komponente nichts anderes wäre als vierzig fest verdrahtete
* Hexwerte (CLAUDE.md §8). Bewusst eigene Gruppe: es sind Szenenfarben, keine
* semantischen Zustandsfarben — ein Dachziegelrot darf nie versehentlich als
* Fehlerfarbe verwendet werden.
*/
export const DS_MEETING_ROOM = {
/** Innenraum: Decke, Wände, Boden, Sockelleisten. */
room: {
ceiling: '#f4f2ee',
ceilingShadow: '#e6e3dd',
wall: '#eae6df',
wallShade: '#ddd8cf',
wallAccent: '#d9d3c8',
floorNear: '#b9a893',
floorFar: '#d8ccbb',
skirting: '#cfc7ba',
mullion: '#5d6773',
frame: '#7b848f',
glassTint: 'rgba(214,232,240,0.18)',
glassGlare: 'rgba(255,255,255,0.30)',
},
/** Besprechungstisch samt Stühlen. */
table: {
topNear: '#6b5a48',
topFar: '#8a7359',
edge: '#4e4133',
inlay: '#f6f3ee',
chair: '#3b4450',
chairRim: '#2c333d',
shadow: 'rgba(45,35,25,0.28)',
},
/** Basler Aussicht: Himmel, Rhein, Altstadt, Münster, Wettsteinbrücke. */
view: {
skyTop: '#a8ccdf',
skyHorizon: '#e2ecef',
hills: '#b3c2c0',
riverTop: '#7fa6ac',
riverBottom: '#4d7d86',
riverGlint: 'rgba(255,255,255,0.45)',
quay: '#c8bda9',
treeDark: '#4e6b4a',
treeLight: '#6b8a5c',
facadeLight: '#efe8dc',
facadeMid: '#ded3c2',
facadeDark: '#c9bda9',
roof: '#a2543f',
roofDark: '#8a4433',
minsterWall: '#b8654a',
minsterRoof: '#5f7f6d',
spire: '#8f4a38',
bridge: '#b9b2a6',
bridgeDark: '#9a9287',
window: '#8fa3ad',
},
/** Agentenplakette über dem Kopf. */
label: {
bg: 'rgba(255,255,255,0.94)',
border: 'rgba(21,38,66,0.14)',
ring: 'rgba(255,255,255,0.85)',
focus: '#b8975a',
},
} as const
// ── Kanalherkunft der Leads bei Nora (Runde 5, §12) ──────────────────────────
/**