Design: KOMPAT-Schicht fuer Altklassen, tote Regeln und !important entfernt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c18a29c748
commit
c19e19968d
2 files changed
+357
-733
No files matched your search
@@ -0,0 +1,178 @@
|
||||
# P1 Task 4: tote Klassen und Übergangsschicht KOMPAT
|
||||
|
||||
Ergebnis des Klassen-Abgleichs mit `css-klassen.mjs` (Werkzeug-Repo `$W`). Zeilenangaben beziehen sich auf `global.css` im Stand `a6877aa` (vor diesem Commit). Spec: Abschnitt „Übergangsschicht KOMPAT“.
|
||||
|
||||
## Werkzeug
|
||||
|
||||
`node "$W/css-klassen.mjs" "$WT" [--ohne-ausnahmen] [--mit-neu]` gibt JSON aus: `{ defined, used, dead, undefinedUsed }` und dazu `definedAt` (Name → Datei:Zeile), `prefixes`, `ausnahmen`, `laufzeit`, `neuOhneBenutzer`, `counts`.
|
||||
|
||||
- **Definiert:** Klasse in einem Selektor in `global.css`, `chat.css`, `serverpuls.css`, `admin-areas.css` oder `pages/AdminPage.css` (Regeln in `@media` und `@container` zählen, `@keyframes` nicht). Geparst mit `postcss`.
|
||||
- **Benutzt:** Wort in einem `className`-Ausdruck in `src/**/*.jsx` (Literale, Template-Strings, Zweige von `?:`, rechte Seite von `&&`, Teile einer `+`-Kette; Bedingungen und Vergleiche wie `filter === 'all'` zählen nicht; ein Ergebnis, das an Text klebt wie `fin-todo-${x || 'info'}`, ist nur ein Namensteil). Dazu Wörter aus Zeichenketten in `src/lib/*.js` und `src/hooks/*.js`, die eine definierte Klasse sind. Geparst mit `@babel/parser`.
|
||||
- **Präfixe:** `xxx-${…}` oder `'xxx-' + …` deckt `xxx-*`.
|
||||
- **Ausnahmeliste** (entfällt mit `--ohne-ausnahmen`): `fin-neg`, `fin-fixed-off`, `legal-tone-*`, `legal-version-*`, `badge-*`, `status-*`, `ticket-tab-active`, `ui-btn-*`, `side-dot-*`, `woms-chat`, `chat-*`.
|
||||
- **NEU-Bereiche:** Regeln zwischen den Kommentaren `NEU-ANFANG` und `NEU-ENDE` in `global.css` (Basis, Hilfsklassen und Bausteine aus Task 2 und 3) sind das neue System; ihre Benutzer entstehen in P1 Task 5 bis 8 und in P2 bis P9. Eine Klasse mit einer Regel dort gilt nie als tot und steht in `neuOhneBenutzer` (mit `--mit-neu` zählt sie normal, so findet P10 unbenutzt gebliebene neue Klassen). Ohne diese Trennung stünden 77 neue Klassen als „tot“ in der Liste.
|
||||
- **Laufzeit-Klassen** (gelten immer als benutzt): `u-*` (uPlot erzeugt `u-legend` im DOM) und `mine` (Modifikator der Sprechblasen des Chat-Bausteins aus dem Kundenportal, gesetzt über `renderMessage(…, { mine })` in `ChatThread.jsx`).
|
||||
|
||||
## Ergebnis
|
||||
|
||||
| Lauf | definiert | tot |
|
||||
|---|---|---|
|
||||
| Vor P1 (`bd84d22`, ohne NEU-Bereiche) | 514 | **67** |
|
||||
| Vor diesem Task (`a6877aa`), roh | 594 | 144 |
|
||||
| davon Laufzeit-Klassen (`mine`, `u-legend`) | | 2 |
|
||||
| davon NEU-Bereiche (Task 2 und 3, noch ohne Benutzer) | | 77 |
|
||||
| **Kandidaten (Altlast)** | | **65** |
|
||||
| Nach diesem Task | 524 | 3 (siehe Gegenprobe) |
|
||||
|
||||
Erwartet waren etwa 66 Namen (Grenzen 40 und 90). Der Lauf auf dem Stand vor P1 ergibt 67, die Altlast-Kandidaten im aktuellen Stand 65: Die Differenz sind `link-danger`, `num`, `nowrap`, `small`, `strong` und `xs` (jetzt NEU) sowie `mine` und `u-legend` (Laufzeit), dazu kommen `stat-label` und `stat-value` wie unten.
|
||||
|
||||
## Gegenprobe
|
||||
|
||||
Für jeden der 65 Kandidaten: `rg -w <name> src --glob '!*.css'`. Bei Treffern zusätzlich mit genauer Wortgrenze (`rg -e '(^|[^A-Za-z0-9_-])<name>($|[^A-Za-z0-9_-])' --glob '!*.css' src`), weil `-w` den Bindestrich als Wortgrenze behandelt und `stat-value` in `fin-stat-value` „findet“.
|
||||
|
||||
- 62 Kandidaten: 0 Treffer.
|
||||
- `stat-label`, `stat-value`: je 3 Treffer, alle in `fin-stat-label` und `fin-stat-value` (`AboCard.jsx`); mit genauer Wortgrenze 0, also tot.
|
||||
- `success`: 71 Treffer, wirklich benutzt: `AdminPage.jsx` Zeile 25 setzt `admin-notice ${notice.type}` (`success` oder `error`). Bleibt.
|
||||
- `admin-status`, `admin-empty-line`: 0 Treffer, tot, aber in `pages/AdminPage.css`, das nicht zu diesem Paket gehört (Task 9 und P8 fassen die Datei an). Bleiben vorerst.
|
||||
|
||||
Gelöscht sind damit 62 Namen aus `global.css`.
|
||||
|
||||
| Klasse | Definition (Stand `a6877aa`) | `rg -w` Treffer | Ergebnis |
|
||||
|---|---|---|---|
|
||||
| `admin-empty-line` | pages/AdminPage.css:361, pages/AdminPage.css:372 | 0 | tot, bleibt vorerst: Datei liegt ausserhalb dieses Pakets (P8 baut die Admin-Seite um) |
|
||||
| `admin-status` | pages/AdminPage.css:280, pages/AdminPage.css:293 | 0 | tot, bleibt vorerst: Datei liegt ausserhalb dieses Pakets (P8 baut die Admin-Seite um) |
|
||||
| `bg-amber` | global.css:494 | 0 | gelöscht |
|
||||
| `bg-black` | global.css:487 | 0 | gelöscht |
|
||||
| `bg-blue` | global.css:490 | 0 | gelöscht |
|
||||
| `bg-blue-grey` | global.css:491 | 0 | gelöscht |
|
||||
| `bg-dark-grey` | global.css:484, global.css:748, global.css:761 | 0 | gelöscht |
|
||||
| `bg-green` | global.css:488 | 0 | gelöscht |
|
||||
| `bg-light-grey` | global.css:485 | 0 | gelöscht |
|
||||
| `bg-orange` | global.css:495 | 0 | gelöscht |
|
||||
| `bg-teal` | global.css:489 | 0 | gelöscht |
|
||||
| `bg-white` | global.css:486 | 0 | gelöscht |
|
||||
| `bg-yellow` | global.css:493 | 0 | gelöscht |
|
||||
| `btn-secondary` | global.css:593 | 0 | gelöscht |
|
||||
| `col-12` | global.css:695 | 0 | gelöscht |
|
||||
| `container` | global.css:504 | 0 | gelöscht |
|
||||
| `control-panel-section` | global.css:1009, global.css:1014 | 0 | gelöscht |
|
||||
| `dashboard-section` | global.css:1238 | 0 | gelöscht |
|
||||
| `drop-zone` | global.css:963, global.css:972 | 0 | gelöscht |
|
||||
| `fade-in` | global.css:1041 | 0 | gelöscht |
|
||||
| `flex-col` | global.css:1321 | 0 | gelöscht |
|
||||
| `form-select` | global.css:638, global.css:654, global.css:1308, global.css:1309 | 0 | gelöscht |
|
||||
| `gap-1` | global.css:1324 | 0 | gelöscht |
|
||||
| `gap-4` | global.css:1324 | 0 | gelöscht |
|
||||
| `mb-1` | global.css:707 | 0 | gelöscht |
|
||||
| `modal-content` | global.css:904 | 0 | gelöscht |
|
||||
| `modern-card` | global.css:993, global.css:1003, global.css:1306, global.css:1307 | 0 | gelöscht |
|
||||
| `mt-1` | global.css:704 | 0 | gelöscht |
|
||||
| `nav-link` | global.css:545, global.css:553 | 0 | gelöscht |
|
||||
| `nav-right` | global.css:558 | 0 | gelöscht |
|
||||
| `navbar` | global.css:518 | 0 | gelöscht |
|
||||
| `navbar-brand` | global.css:531 | 0 | gelöscht |
|
||||
| `navbar-nav` | global.css:540, global.css:1095 | 0 | gelöscht |
|
||||
| `priority-high` | global.css:838 | 0 | gelöscht |
|
||||
| `priority-low` | global.css:836 | 0 | gelöscht |
|
||||
| `priority-medium` | global.css:837 | 0 | gelöscht |
|
||||
| `priority-none` | global.css:835 | 0 | gelöscht |
|
||||
| `quick-actions` | global.css:1239 | 0 | gelöscht |
|
||||
| `side-group-label` | global.css:1134, global.css:1138 | 0 | gelöscht |
|
||||
| `slide-in` | global.css:1045 | 0 | gelöscht |
|
||||
| `slider` | global.css:916, global.css:926, global.css:930, global.css:941, global.css:946, global.css:957 | 0 | gelöscht |
|
||||
| `slider-container` | global.css:911 | 0 | gelöscht |
|
||||
| `spacer` | global.css:609 | 0 | gelöscht |
|
||||
| `stat-card` | global.css:1234 | 0 | gelöscht |
|
||||
| `stat-info` | global.css:1235 | 0 | gelöscht |
|
||||
| `stat-label` | global.css:1237 | 3, alle nur Teil von `fin-stat-label` | gelöscht |
|
||||
| `stat-value` | global.css:1236 | 3, alle nur Teil von `fin-stat-value` | gelöscht |
|
||||
| `stats-grid` | global.css:1233 | 0 | gelöscht |
|
||||
| `success` | pages/AdminPage.css:99 | 71 | bleibt: dynamischer Modifikator `admin-notice ${notice.type}` (AdminPage.jsx:25, Typen `success`/`error`) |
|
||||
| `table-hover` | global.css:600, global.css:604 | 0 | gelöscht |
|
||||
| `text-black` | global.css:498 | 0 | gelöscht |
|
||||
| `text-green` | global.css:500 | 0 | gelöscht |
|
||||
| `text-large` | global.css:701 | 0 | gelöscht |
|
||||
| `text-right` | global.css:699 | 0 | gelöscht |
|
||||
| `text-small` | global.css:700 | 0 | gelöscht |
|
||||
| `text-xlarge` | global.css:702 | 0 | gelöscht |
|
||||
| `ticket-collapsed` | global.css:742, global.css:748 | 0 | gelöscht |
|
||||
| `ticket-expanded` | global.css:755, global.css:761 | 0 | gelöscht |
|
||||
| `ticket-id` | global.css:742, global.css:755, global.css:794, global.css:807 | 0 | gelöscht |
|
||||
| `ticket-id-expanded` | global.css:807, global.css:811 | 0 | gelöscht |
|
||||
| `ticket-info` | global.css:820 | 0 | gelöscht |
|
||||
| `ticket-row` | global.css:715, global.css:720, global.css:727, global.css:731, global.css:735 | 0 | gelöscht |
|
||||
| `ticket-time` | global.css:815 | 0 | gelöscht |
|
||||
| `worksheet-cell` | global.css:771, global.css:777 | 0 | gelöscht |
|
||||
| `worksheet-expansion` | global.css:767 | 0 | gelöscht |
|
||||
|
||||
## Nicht gelöscht, obwohl der Abgleich sie roh nennt
|
||||
|
||||
- **NEU (77, Task 2 und 3, Benutzer folgen):** `actions`, `brand`, `btn-block`, `btn-primary`, `btn-quiet`, `cell-sub`, `cell-title`, `check`, `code-input`, `count`, `critical`, `crumb`, `dialog`, `dialog-body`, `dialog-close`, `dialog-foot`, `dialog-head`, `dialog-wide`, `err`, `eyebrow`, `fact`, `facts`, `field-row`, `field-row-3`, `hide-md`, `hide-sm`, `hint`, `hot`, `input`, `is-invalid`, `k`, `kv`, `link-danger`, `loading`, `login`, `login-box`, `login-foot`, `login-links`, `main`, `menu-open`, `mobile-bar`, `msg`, `nav`, `nav-count`, `nav-dot`, `nav-item`, `neg`, `nowrap`, `num`, `page-head`, `paused`, `prose`, `right`, `scrim`, `search`, `section`, `select`, `select-quiet`, `shell`, `sidebar`, `sidebar-foot`, `small`, `stat`, `stats`, `strong`, `sub`, `sw`, `tab`, `table`, `table-foot`, `tabs`, `textarea`, `toast`, `two-col`, `v`, `who`, `xs`
|
||||
- **Laufzeit (2):** `mine`, `u-legend`.
|
||||
- **Nur durch die Ausnahmeliste am Leben** (Lauf mit `--ohne-ausnahmen`, 6 Namen): `chat-bubble`, `chat-input-row`, `chat-meta` (Sprechblasen und Eingabezeile kommen zur Laufzeit aus dem Chat-Baustein des Portals), `ui-btn-danger`, `ui-btn-sm` (`Button.jsx` setzt sie über die Tabelle `VARIANTS` und `size`; beide stehen in KOMPAT). `status-occupied` hat keinen Benutzer: `statusClass()` in `lib/ticketStatus.js` liefert nur `status-open`, `-working`, `-awaiting`, `-assigned` und `-closed`. Es ist gelöscht, die übrigen fünf stehen in KOMPAT.
|
||||
|
||||
## Zusätzlich gelöscht (nicht tot, laut Plan)
|
||||
|
||||
- Alle `!important` in `global.css`: 77 vorher, 0 nachher. Offen bleiben 6 in `pages/AdminPage.css` und 2 in `admin-areas.css` (beide Dateien gehören nicht zu diesem Paket; Task 9 und P8).
|
||||
- `.btn-green, .btn-primary { … !important }` samt Hover und `.btn-secondary`; `.btn-dark`, `.btn-teal`, `.btn-green` stehen neu in KOMPAT.
|
||||
- `.footer` (zweimal), `.navbar*`, `.nav-link`, `.nav-right`, `.ticket-row*`, `.ticket-collapsed`, `.ticket-expanded`, `.ticket-id*`, `.ticket-time`, `.ticket-info`, `.worksheet-expansion`, `.worksheet-cell`, `.slider*`, `.drop-zone`, `.modern-card`.
|
||||
- Die Legacy-Responsive-Regeln (`@media (max-width: 768px)` mit `.col-6`, `.navbar-nav`, `.ticket-tab`); `.col-6 { width: 100% }` unter 768 px steht neu in KOMPAT.
|
||||
- Die Keyframes `slideDown`, `fadeIn` und `slideIn` (`WorksheetList.jsx` bringt eigene in einem `<style>`-Block mit).
|
||||
- `.kpi*` einschließlich `.kpi-grid`: `Kpi` rendert ab Task 6 `Stat`; bis dahin hat `Kpi` kein Styling. `.fin-stack .kpi-grid` und `.fin-head .kpi-value` im Finanz-Teil bleiben (Task 9).
|
||||
- `.priority-none`, `-low`, `-medium`, `-high` (tot); `.priority-critical` und `.status-*` stehen in KOMPAT.
|
||||
- `.ui-card*`, `.ui-btn*`, `.badge-*`, `.form-group`, `.form-label`, `.form-control` (und `.form-select`, tot), `.card*`, `.row`, `.col`, `.col-6`, `.dropdown*`, `.spinner`, `.overlay-content`, `.ticket-tab*` und die Regeln „Soften legacy“: durch KOMPAT-Zeilen ersetzt.
|
||||
- `.fin-form-field .form-control[aria-invalid="true"] { border-color: … !important }`: ersetzt durch die roten Ringe aus Task 3 (`.form-control[aria-invalid="true"]`).
|
||||
- Die Aliasvariable `--sidebar-w-collapsed` (Task 2).
|
||||
- Die toten Hilfsklassen `.flex-col`, `.gap-1`, `.gap-4`, `.container`, `.mt-1`, `.mb-1`, `.text-right`, `.text-small`, `.text-large`, `.text-xlarge`, `.col-12`, `.bg-*` außer `.bg-red`, `.text-black`, `.text-green` (stehen in der Tabelle oben).
|
||||
|
||||
### Abweichung: `.side*` bleibt bis Task 5
|
||||
|
||||
Der Plan nennt `.side*` zum Löschen. Das alte Menü (`Navbar.jsx`) benutzt sie aber bis Task 5. Ohne sie fällt das Alt-Gerüst `.app-shell` zusammen: Der Lauf `shots.sh --gate p1` brach auf fast allen Ansichten mit `step-failed` ab, weil das ungebremste Menü den Inhalt verdrängte (auf dem Handy auch ohne die Regel für `.collapsed`). Die Regeln stehen deshalb unverändert in einem eigenen Teil des KOMPAT-Blocks („Altes Menü“). Geändert sind nur `--sidebar-w-collapsed` (jetzt `72px`) und das tote `.side-group-label` (entfernt). **Task 5 löscht diesen Teil**; dafür muss `global.css` in die Dateiliste von Task 5. `.side-count` und `.side-logo` stehen wie im Plan als eigene KOMPAT-Zeilen.
|
||||
|
||||
## KOMPAT-Zeilen (Selektor → Look)
|
||||
|
||||
| Selektor | Look |
|
||||
|---|---|
|
||||
| `.ui-card`, `.ui-card.pad`, `.ui-card-head`, `.ui-card-head h3`, `.ui-card-body` | Abschnitt ohne Kasten, Kopf wie `h2.section` (16/24, 600) |
|
||||
| `.ui-btn`, `.ui-btn-primary`, `.ui-btn-danger` | wie `.btn` (weiß, Ring, 32 px), `.btn-primary` (schwarz), `.link-danger` (roter Textlink); `-ghost` und `-sm` ohne eigene Regel (wirken wie `.ui-btn`) |
|
||||
| `.btn-dark`, `.btn-teal`, `.btn-green` | wie `.btn-primary` |
|
||||
| `.form-group`, `.form-label`, `.form-control` (mit `textarea`, `select`, `:focus`, `[readonly]`, Platzhalter) | wie `.field`, Beschriftung 500, `.input`/`.select`/`.textarea` |
|
||||
| `.badge-muted`, `-info`, `-warn`, `-ok`, `-danger` | Badge-Töne grau, blau, orange, grün, rot |
|
||||
| `.status-open`, `-working`, `-awaiting`, `-assigned`, `-closed`, `.priority-critical` | grau, blau, orange, violett, „plain“ (geschlossen und storniert teilen sich die Klasse), rot |
|
||||
| `.overlay:has(> .overlay-content)` | `overflow-y: auto`, `align-items: flex-start`, Abstand 24/16, Hintergrund `--overlay`, ohne Einblend-Animation |
|
||||
| `.overlay-content` (und `.overlay-content.fin-dialog`) | weiße Box: 100 %, max. 520 px (760 px bei `.fin-dialog`), Radius 12, `--shadow-pop`, Abstand 24, Schrift `--text` |
|
||||
| `.overlay-close` | fest oben rechts, 32×32, weißer runder Knopf, „ד in `--text-2` |
|
||||
| `.seg button.active` | wie `.seg button.on` |
|
||||
| `.bg-red` (mit `.text-white` oder ohne), `.text-grey`, `.text-red` | kein Hintergrund, `--red-fg`, 13 px; `--text-2`; `--red-fg`. `.text-white` allein hat keine Regel |
|
||||
| `.side-count`, `.side-logo` | kleine graue Zahl; Initiale ohne Verlauf |
|
||||
| `.card`, `.card-header`, `.card-body` | neutral: ohne Kasten, Kopf mit Haarlinie |
|
||||
| `div.row`, `.col`, `.col-6` (unter 768 px 100 %) | Raster ohne Look; `div.row`, damit `tr.row` unberührt bleibt |
|
||||
| `.dropdown`, `.dropdown-content`, `.dropdown-item` | weißes Popover mit `--shadow-pop` |
|
||||
| `.spinner` | grauer Ring |
|
||||
| `.page .page`, `.page .main-content` | Abstand und Breite aufgehoben |
|
||||
| `.fin-link`, `.legal-files a`, `.credit-cols a`, `.area-rows a` | feiner Unterstrich (`--line-strong`, beim Überfahren `currentColor`) |
|
||||
| `.ticket-tabs`, `.ticket-tab`, `.ticket-tab-active`, `.ticket-tab-content` | wie `.tabs` und `.tab` (Unterstrich statt Kasten); nicht in der Spec-Tabelle, aber `Tabs.jsx` bleibt bis Task 6 |
|
||||
| `.side*` („Altes Menü“) | siehe Abweichung oben; Task 5 löscht den Teil |
|
||||
|
||||
Das `:has()` der Alt-Dialoge ist nötig, damit `^\.overlay *\{` genau einmal trifft (Grundregel des neuen `.overlay > .dialog`).
|
||||
|
||||
Die Einblend-Animation des neuen `.overlay` (`fade`, Deckkraft 0 → 1) ließ `submitReachable` mit „kein offener Dialog gefunden“ scheitern, wenn der Dialog im ersten Bild geprüft wurde (`checkVisibility` mit `checkOpacity`). Alt-Dialoge hatten nie eine Animation, deshalb `animation: none` in KOMPAT. Task 7 muss dasselbe für `Dialog` lösen, z. B. mit `@media (prefers-reduced-motion: reduce) { .overlay, .dialog { animation: none; } }` (der Lauf setzt `reducedMotion: 'reduce'`).
|
||||
|
||||
Zusätzlich: `.datetime-pair input[type="date"]` bekommt `flex: 1.3`, weil das Datum im 520-px-Dialog sonst das Jahr abschneidet.
|
||||
|
||||
## Benutzt, aber ohne Regel (`undefinedUsed`)
|
||||
|
||||
Der Lauf nach diesem Task nennt 67 Namen. Der Lauf auf dem Stand vor P1 (`bd84d22`) nannte 58 davon schon; neu sind 9, alle gewollt:
|
||||
|
||||
| Name | Grund |
|
||||
|---|---|
|
||||
| `dot`, `empty-icon` | Task 3 hat die Regeln mit dem neuen `.badge` und `.empty` ersetzt; Task 6 baut `Badge` und `EmptyState` um (Prop `dot` und `icon` entfallen) |
|
||||
| `footer` | Regel nach Plan gelöscht; Task 5 löscht `Footer.jsx` |
|
||||
| `kpi`, `kpi-accent`, `kpi-label`, `kpi-sub` | Regeln nach Plan gelöscht; Task 6 lässt `Kpi` das neue `Stat` rendern |
|
||||
| `text-white` | Spec: allein keine Regel |
|
||||
| `ui-btn-ghost` | gleicher Look wie `.ui-btn`, braucht keine eigene Regel |
|
||||
|
||||
Die übrigen 58 hatten schon vor P1 keine Regel:
|
||||
- die Bootstrap-Namen aus `WorksheetList.jsx` (wirkungslos): `alert`, `alert-info`, `align-items-center`, `border-0`, `col-md-6`, `d-flex`, `fs-5`, `fs-6`, `justify-content-between`, `justify-content-md-end`, `mb-3`, `mb-4`, `me-1`, `me-2`, `ms-2`, `ms-3`, `mx-2`, `overflow-hidden`, `p-3`, `px-3`, `py-2`, `py-3`, `rounded-3`, `shadow-sm`, `spinner-border`, `text-dark`, `text-md-end`, `text-muted`, `visually-hidden`, `timeline`, `timeline-item`;
|
||||
- die Namen aus dem Plan: `p-4`, `btn-sm`, `status-filter`, `supporters-editor` (und `timeline` oben);
|
||||
- reine Haken ohne Styling: `credits-view`, `fin-abo-amount`, `fin-abo-main`, `fin-abo-next`, `fin-abo-product`, `fin-assign`, `fin-days`, `fin-inv-abo`, `fin-memo`, `fin-tax-card`, `fin-tax-note`, `fin-todo-main`, `fin-total-value`, `fin-tx-out`, `fin-wrap`, `legal-doc`, `offer-form`, `sp-ampel`, `sp-apps`, `sp-cleanup-body`, `status-filter-actions`, `worksheet-list`, `worksheet-supporters`.
|
||||
Reference in new issue
Block a user