467 Stellen. Nicht durch einen anderen Strich ersetzt, sondern durch das
Satzzeichen, das an der jeweiligen Stelle richtig ist: Doppelpunkt, wo eine
Erlaeuterung folgt; Komma, wo der Satz weiterlaeuft; Punkt, wo zwei
Hauptsaetze aneinanderstiessen. Ein Halbgeviertstrich waere nur derselbe
Griff mit kuerzerem Strich gewesen.
Regelbasiert ersetzt und danach nachgeprueft, weil eine Regel allein nicht
reicht. Gefunden und einzeln korrigiert:
- Eingeschobene Saetze mit Strichpaar. Nur der oeffnende Strich passte ins
Muster, der schliessende blieb als "—," stehen. Drei Stellen, jetzt mit
Klammern oder als eigener Satz.
- Doppelte Doppelpunkte, wo beide Striche eines Paars zu Doppelpunkten wurden
("Globale Regeln: Schrift, Groessen, Abstaende: kommen aus HiveGrid").
Sieben Stellen in Doku und Oberflaeche, jetzt in Klammern.
- Pfade, denen ein Komma statt eines Doppelpunkts folgte.
- Ausgerichtete Kommentartabellen, in denen der Strich eine Spalte war.
Nicht angefasst: drei Geviertstriche, die keine Prosa sind, sondern
Tabellenplatzhalter fuer "kein Wert" (Trichter, Auftraege, Kunden). Dort ist
der Strich die Angabe selbst; ihn zu entfernen liesse leere Zellen zurueck.
tsc, lint, build, verify:carbon und verify:layout laufen sauber.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
Nach dem Oeffnen der Schublade lag ein blauer Rahmen um "Dashboard", nach dem
Schliessen um den Hamburger — bis man woanders hinklickte. Der Ring hat einen
praktischen Grund, aber nur fuer die Tastatur: Er zeigt, wo man gerade steht.
Nach einem Mausklick weiss man das ohnehin.
Ursache war unser eigener Fokus-Sprung, nicht die CSS-Regel. Die benutzt
laengst :focus-visible. Setzt aber ein Skript den Fokus — Fokusfalle beim
Oeffnen, Rueckgabe an den Ausloeser beim Schliessen —, wertet Chrome das wie
Tastaturbedienung und zeigt den Ring trotzdem.
Drei Aenderungen:
- Beim Oeffnen bekommt der Dialograhmen den Fokus statt des ersten Links. Das
ist ohnehin das uebliche Vorgehen fuer einen Dialog; die Sprachausgabe liest
den Dialog an, der erste Tabulatorschritt landet auf dem ersten Link.
- Elemente mit tabindex="-1" bekommen keinen Ring mehr. Sie sind aus der
Tabulatorreihenfolge heraus und werden nur per Skript fokussiert — ein Ring
um den ganzen Schubladenrahmen waere dort Laerm.
- AppShell schreibt die zuletzt benutzte Eingabeart als data-eingabe an das
Wurzelelement. Solange sie "zeiger" ist, entfaellt der Ring an Knoepfen und
Links. Eingabefelder sind ausgenommen, dort gehoert er zum Zustand "hier
wird gerade geschrieben". Der erste Tastendruck schaltet ihn ueberall zurueck.
Dabei ist eine Luecke in der Fokusfalle aufgefallen und behoben: Mit dem Fokus
auf dem Rahmen lief Umschalt+Tab aus dem Dialog heraus, weil die Falle nur den
ersten Link als Umkehrpunkt kannte. Der Rahmen steht im Dokument vor seinen
Kindern und gehoert dazu — sonst waere die Zusage von aria-modal gebrochen.
Nachgemessen statt begutachtet, alle Faelle:
Maus offen → Rahmen, kein Ring
Maus zu → Hamburger, kein Ring
Tastatur offen → Rahmen, kein Ring
Tastatur erstes → "Dashboard", RING
Tastatur rueckwaerts → "Komponenten", RING (Falle haelt)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
Der Prototyp war auf Schreibtischbreiten gebaut. Bei 375 px lief die Seite um
306 px seitlich über, und dem Inhalt blieben 135 px, weil die Seitenleiste ihre
vollen 240 px behielt.
Seitenleiste (an HiveGrid abgeglichen, nicht erfunden):
- Unterhalb 768 px faehrt sie als Schublade ueber den Inhalt. Derselbe
Breakpoint, den die Software als MOBILE_BREAKPOINT fuehrt.
- Hamburger links in der Kopfzeile, FeatherMenu, 32x32, md:hidden, vor dem
Breadcrumb — wie SubframeAppShell ihn rendert.
- Abdeckung dahinter, Escape schliesst, Fokus wandert beim Oeffnen auf den
ersten Eintrag und kehrt beim Schliessen zum Ausloeser zurueck.
- Fokusfalle mit Tab und Umschalt+Tab: Der Rahmen traegt role=dialog und
aria-modal, ohne Falle waere das gegenueber einem Screenreader unwahr.
- Der Einklapp-Knopf ist unterhalb md ausgeblendet. Er ragt bauartbedingt
17 px nach rechts heraus und blieb sonst als angeschnittener, wirkungsloser
Rest bei x = -16 am Bildrand stehen — der gemeldete Fehler.
Inhalte: Raster einspaltig ab 375 px, Seitenkopf mit Aktionen unter dem Titel
und Icon-only, Zeitraum-Segment und Reiterstreifen waagerecht scrollend statt
umbrechend (ein Segment ueber zwei Zeilen liest sich als zwei Steuerelemente),
Filter-Panel auf volle Zeilenbreite, Tabellen mit eigenem Scrollbereich.
Zwei abgeschnittene Fehler mitbehoben, die der Prueferer nicht sieht:
- KPI-Label lief bei 1280 px um 5 px aus seinem Kasten; bricht jetzt um. Die
Karte wird dadurch eine Zeile hoeher — der Preis fuer eine vollstaendig
lesbare Beschriftung.
- Randmarken der Auslastungsachse ragten je rund 10 px ueber die Spur. In sehr
schmalen Karten entfaellt die Achse ganz; dort bleibt nur rund 40 px Spur,
auf der selbst zwei Marken aneinanderstossen.
verify-layout deckt jetzt 375-1920 px ab (vorher ab 1024) und meldet zusaetzlich
Seitenueberlauf: ein waagerechter Scrollbalken auf Dokumentebene ist immer ein
Fehler, nie ein Kompromiss. 7 Seiten x 9 Breiten gruen.
Ab 1024 px ist der abgenommene Stand unveraendert — numerisch geprueft ueber die
Bounding-Boxen aller Karten, Raster, Tabellen und Kopfelemente.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
Klarstellung, damit beim Port keine globalen Regeln aus diesem Repo in die
Software wandern.
Verbindlich ist aus diesem Repo nur das Analytics-Eigene und das Fachliche:
Kennzahl-Definitionen, Diagrammregeln, Verhalten — und die Navigationsstruktur
als Verabredung (zwei Einträge in der Seitenleiste, Analytics mit innerer
Leiste).
Nicht verbindlich ist alles Globale: Schrift, Schriftgrößen, Abstände, Farben,
Radien, Control-Höhen, App-Shell, Kopfzeile, i18n, Formatierung. Das kommt
ausschließlich aus HiveGrid. Dass dieser Prototyp dieselbe Schrift, dieselbe
Seitenleisten-Komponente und dieselben Token benutzt, dient allein der
Lesbarkeit neben der Software — es ist keine Vorlage, an der sich die Software
auszurichten hätte. Weicht ein Wert hier von HiveGrid ab, ist der Wert hier
falsch.
Ebenso festgehalten, was Gerüst ist und wegfällt: AppShell, unsere Kopie der
Seitenleiste, PageHeader, die Kopfzeile, die Routen unter app/ und die
Dashboard-Platzhalterseite. Der Nachbau der inneren Leiste wird nicht portiert;
in HiveGrid entsteht sie über das dortige SidebarIconsLayout.
Vermerkt in ZIELSYSTEM.md (neuer Abschnitt 0 mit Zuständigkeitstabelle), im
Kopf von HANDOVER.md und README.md, bei der Struktur in NAVIGATION.md, als
Vorbemerkung zu den bewussten Abweichungen in LEITPLANKEN.md — und als
Kommentarblock in AppShell.tsx und AnalyticsInnerNav.tsx, weil beim Port oft
zuerst der Code gelesen wird.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
Der Knopf ragt bauartbedingt 17 px aus der Seitenleiste in die Inhaltsfläche
hinein. Dort wurde seine rechte Hälfte verdeckt — er sah abgeschnitten aus und
war auf diesem Teil nicht anklickbar.
Nicht abgeschnitten, sondern überdeckt: Gemessen war overflow überall visible,
aber das oberste Element an der Knopfmitte war die Inhaltsspalte. Ursache ist
ein Stapelkontext — 'position: sticky' erzeugt einen eigenen, wodurch das
z-index:40 des Knopfes darin gefangen bleibt. Der Rahmen selbst hatte
z-index:auto, also malte die später im Dokument stehende Inhaltsspalte darüber.
Behoben mit z-50 am Sidebar-Rahmen; die Software setzt an derselben Stelle
ebenfalls z-50. Nachgemessen: Am rechten Rand ist jetzt der Knopf selbst das
oberste Element, und ein Klick genau dort schaltet um.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
Der Menüpunkt 'Dashboard' löste bisher nur einen Toast aus. Ein
Navigationseintrag, der nirgendwohin führt, lässt den Leser im Unklaren, ob
etwas fehlt oder etwas kaputt ist.
Jetzt führt er auf /dashboard: ein Leerzustand nach dem Hausmuster
(ui/components/EmptyState), der benennt, warum hier nichts steht, was später
hinkommt (drei Rollen-Layouts, Widgets teils aus Analytics, teils nicht — offene
HR-Anträge, Aufgaben, Termine) und wo der Zuschnitt dokumentiert ist. Mit einem
Weg zurück nach Analytics.
Dabei:
- EmptyState aus der Cloud-Fassung nachgezogen; unsere Kopie hatte den
action-Slot noch nicht.
- PageHeader bekommt 'standardAktionen': Auf einer leeren Seite gibt es nichts
zu aktualisieren oder zu exportieren, also stehen dort auch keine
Schaltflächen dafür.
- Die Variante 'software' in NavZiel entfällt — jeder Eintrag führt jetzt auf
eine echte Seite, der Toast-Zweig in der AppShell war damit toter Code.
- verify-layout deckt /dashboard mit ab (jetzt 7 Seiten x 7 Breiten).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
Der Prototyp hatte eine eigene Seitenleiste mit den fünf Analyse-Seiten als
Menüpunkten. Die Software hat eine andere Navigation, in der Analytics noch gar
nicht vorkommt. Beides zusammen ergab kein Bild davon, wo die Analyse später
sitzt.
Jetzt:
- Die Seitenleiste spiegelt die von HiveGrid Cloud — dieselbe Komponente
(SidebarWithSections aus der Cloud-Fassung portiert, inkl. der dortigen
lokalen Fixes: Collapse-Breite, verdrahteter Toggle, Logo-Slot, Hover-Sweep),
dieselben Gruppen, dieselbe Reihenfolge, dasselbe Logo.
- 'Analytics' ist ein einzelner Menüpunkt, gleichrangig neben 'Dashboard'.
- Die fünf Analyse-Seiten sind darin über Reiter erreichbar, nicht als
Unterpunkte in der Navigation. Zwei Navigationsebenen für dieselbe Sache
würden nur konkurrieren. Die Reiter folgen dem Hausmuster aus
SettingsHubShell (Link um Tabs.Item), damit jeder Reiter eine echte Adresse
hat und mittelklickbar bleibt.
- Routen: /analytics, /analytics/finanzen, /auftraege, /kunden, /team.
'/' leitet auf /analytics; das Dashboard liegt in der Software unter '/'.
- Alle übrigen Einträge sind Kontext: Sie zeigen den Ort in der fertigen
Anwendung und melden beim Klick, dass sie zur Software gehören.
Kopfzeile und Filterleiste sind aus den fünf Seiten in die Analytics-Hülle
gewandert — sie sind für alle gleich, und der Filterzustand gilt bereichsweit.
Nebenbei: @radix-ui/react-slot war eine Phantom-Dependency (nur transitiv über
@subframe/core vorhanden, vom portierten IconButton direkt importiert) und ist
jetzt deklariert. verify-layout prüfte noch die alten Routen und lief damit auf
404-Seiten, die naturgemäß keine Kollisionen haben — Routen korrigiert und eine
Absicherung ergänzt, die bei Statuscode >= 400 abbricht.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
UI/UX-Prototyp der Analytics-Dashboards in HiveGrid, fachlich auf einen
SHK-/Handwerksbetrieb zugeschnitten. Ziel ist die Übergabe an die Entwicklung,
nicht der Produktivbetrieb.
Inhalt: sechs Seiten (Übersicht, Finanzen, Aufträge, Kunden, Team, Komponenten),
26 KPIs, neun Chart-Bausteine, Filtersystem mit seitenabhängiger Relevanz und ein
deterministischer Demo-Datensatz (420 Kunden, 1.900 Aufträge, Stichtag 30.07.2026).
Drei Quellen sind zusammengeführt: die fachliche Planung mit dem Branchenpartner
(Januar 2026), die Subframe-Komponentenbibliothek aus dem HiveGrid-Pitch und
IBM Carbon Data Visualization für die Diagrammregeln. Herkunft und bewusste
Abweichungen stehen in docs/HERKUNFT.md.
Dokumentation: README, HANDOVER (was echte Logik braucht), docs/DESIGN-SYSTEM,
KPI-KATALOG, DATENMODELL, NAVIGATION, HERKUNFT, ZIELSYSTEM (Einbauort in
HiveGrid Cloud) und LEITPLANKEN (welche Cloud-Screens als Vorbild taugen).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX