Files
tickte-system/docs/superpowers/plans/2026-10-05-weisses-design-p1-tote-klassen.md
T

20 KiB
Raw Blame History

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.

Bewusst offen (P1 Task 9)

Stand nach Task 9: node "$W/farben.mjs" "$WT" meldet 0 Treffer in allen vier Gründen (kontrast<3, dunkel-auf-akzent, weiss, verlauf). Vorher waren es 41, 1, 18 und 11 (zusammen 71). Was danach noch an Farbliteralen im Quelltext steht, ist hier mit Zielpaket und gemessenem Kontrast festgehalten; keine Zeile liegt unter 3:1.

Stelle Was Kontrast (gemessen) Zielpaket
global.css:269 (.select) Pfeil als zwei linear-gradient mit hartem Stopp (transparent 50%), Wert aus dem Prototyp; farben.mjs führt ihn als „ausgenommen“ (--ohne-ausnahmen zeigt ihn) --text-2 auf Weiß 5,76:1 bleibt (Spec)
global.css:1057 (KOMPAT, select.form-control) derselbe Pfeil für das Altfeld 5,76:1 P10 (KOMPAT entfällt, FormField und die Altfelder gehen in P7 auf .select)
global.css:669 .legal-version-current (Tönung rgba(16,185,129,.08)), :680 .legal-tone-red td (rgba(239,68,68,.10)), :682 .legal-tone-orange td (rgba(245,158,11,.10)) Alpha-Tönungen als Zeilenhintergrund Text --text auf den Tönungen 14,3 bis 15,1:1; .legal-deadline rot (--danger) 5,43:1, orange (--orange-fg) 6,43:1 P8 (Rechtliches, Tönungen werden Badge-Töne)
global.css:964 .fin-confirm (Tönung rgba(245,158,11,.1)) Alpha-Tönung als Kastenhintergrund Text --text auf der Tönung 15,1:1 P7 (Finanzen)
src/components/serverpuls/chartColors.js Canvas-Farben, die einzige erlaubte Ausnahme im Quelltext (Spec) Linie 18,88:1, Achse 5,76:1, Spitze 3,10:1; Raster und Teilstriche sind Hilfslinien ohne Text bleibt (Spec)
src/components/Logo.jsx (fill="#111", fill="#fff") SVG-Marke mit zwei festen Farben Weiß auf Schwarz 18,88:1 bleibt (Marke)

Außerhalb des Scans (er prüft nur CSS und JSX) und nicht unter „bewusst offen“, weil der Kontrast unter 3:1 liegt:

  • src/lib/previewEnv.js, DOT_COLORS und dotColor(): Status-Punkte mit den Altfarben #10b981 (2,54:1), #f59e0b (2,15:1), #ef4444 (3,76:1) und #a0aec0 (2,26:1) auf Weiß. Die Punkte sind höchstens 10 × 10 px groß und stehen immer neben dem Statustext (ServicesPage, PreviewBlock); der Browser-Check dark-surface ignoriert seit diesem Task Elemente bis 12 × 12 px. tests/unit/previewEnv.test.mjs hält die Hex-Werte fest, deshalb bleibt die Datei hier unverändert. Zielpaket: P5 (Projekte und Services): dotColor() liefert var(--green-fg), var(--orange-fg), var(--red-fg), var(--text-3), dazu der Test.

Nicht prüfbar im Werkzeug: Der Eingabebaustein des Chats kommt aus dem Kundenportal und ist dort eine leere Datei (loadChatComposer). Die Variablen --chat-* und die Meldungsfarben (.chat-composer-note, .chat-file-size, .chat-audio-time) sind laut Vorgabe gesetzt; ihr Laufzeitbild muss nach dem Livegang einmal im Chat angesehen werden (Zielpaket P6).