20 KiB
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.cssoderpages/AdminPage.css(Regeln in@mediaund@containerzählen,@keyframesnicht). Geparst mitpostcss. - Benutzt: Wort in einem
className-Ausdruck insrc/**/*.jsx(Literale, Template-Strings, Zweige von?:, rechte Seite von&&, Teile einer+-Kette; Bedingungen und Vergleiche wiefilter === 'all'zählen nicht; ein Ergebnis, das an Text klebt wiefin-todo-${x || 'info'}, ist nur ein Namensteil). Dazu Wörter aus Zeichenketten insrc/lib/*.jsundsrc/hooks/*.js, die eine definierte Klasse sind. Geparst mit@babel/parser. - Präfixe:
xxx-${…}oder'xxx-' + …decktxxx-*. - 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-ANFANGundNEU-ENDEinglobal.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 inneuOhneBenutzer(mit--mit-neuzä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 erzeugtu-legendim DOM) undmine(Modifikator der Sprechblasen des Chat-Bausteins aus dem Kundenportal, gesetzt überrenderMessage(…, { mine })inChatThread.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 infin-stat-labelundfin-stat-value(AboCard.jsx); mit genauer Wortgrenze 0, also tot.success: 71 Treffer, wirklich benutzt:AdminPage.jsxZeile 25 setztadmin-notice ${notice.type}(successodererror). Bleibt.admin-status,admin-empty-line: 0 Treffer, tot, aber inpages/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.jsxsetzt sie über die TabelleVARIANTSundsize; beide stehen in KOMPAT).status-occupiedhat keinen Benutzer:statusClass()inlib/ticketStatus.jsliefert nurstatus-open,-working,-awaiting,-assignedund-closed. Es ist gelöscht, die übrigen fünf stehen in KOMPAT.
Zusätzlich gelöscht (nicht tot, laut Plan)
- Alle
!importantinglobal.css: 77 vorher, 0 nachher. Offen bleiben 6 inpages/AdminPage.cssund 2 inadmin-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-greenstehen 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,fadeInundslideIn(WorksheetList.jsxbringt eigene in einem<style>-Block mit). .kpi*einschließlich.kpi-grid:Kpirendert ab Task 6Stat; bis dahin hatKpikein Styling..fin-stack .kpi-gridund.fin-head .kpi-valueim Finanz-Teil bleiben (Task 9)..priority-none,-low,-medium,-high(tot);.priority-criticalund.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(undtimelineoben); - 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_COLORSunddotColor(): 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-Checkdark-surfaceignoriert seit diesem Task Elemente bis 12 × 12 px.tests/unit/previewEnv.test.mjshält die Hex-Werte fest, deshalb bleibt die Datei hier unverändert. Zielpaket: P5 (Projekte und Services):dotColor()liefertvar(--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).