Continues #29866 (wave 4b, navigation). Own ticket so that a release between the two merges does not close the ticket of the open one.
Problem
The layout containers of the React view layer – TLPanel, TLSplitPanel, TLCard, TLStack, TLGrid, TLDeckPane, TLTileStack, TLInset, TLAdaptiveDetail, TLAccordion, TLWizard and TLViewError – are styled by the old stylesheet tlReactControls.css. The same jobs are done several times in different ways (forecast Q14–Q18 in the package, docs/migration/altlast.md "Welle 4"):
- Bars: the panel button bar repeats what the toolbar and the window footer already do.
- Surfaces: TLCard, .tlPanel--card and the accordion draw three card surfaces.
- Gaps: TLStack and TLGrid carry the three-step gap scale of tl-columns on old tokens; --tlGrid-gap and --page-inset live outside the package.
- Dividers: the split panel divider has no role and no keyboard; the column handle of the table already is a role=separator.
- Breadcrumb: TLAdaptiveDetail draws its own breadcrumb with ›`, without `aria-current and with a fixed English aria-label.
- Panel minimize has no aria-expanded; the error box of TLViewError repeats tl-alert.
Solution
Spec in the package: docs/superpowers/specs/2026-10-16-welle-4c-behaelter-design.md. Panel and card share the head of the window (tl-titlebar); panel button bar and dialog footer are one block tl-button-bar. A card takes its surface from where it lies (page, inside a surface, on a floating surface) through a React context, the same one an inset reads its padding from. Stack, grid and columns share one gap scale. The split handle and the column width handle are separators with keyboard (arrow keys, Home, End); a double click on the split handle resets to the configured sizes. A panel handles like a window: double click on the head maximizes, Escape restores, a click on the head of a minimized panel opens it. Wizard and tile stack mark their transitions as data-tl-state; the adaptive detail draws the package breadcrumb; a view that cannot be loaded is an error alert.
Migration
The containers (panel, card, accordion, stack, grid, inset, deck, split panel, tile stack, wizard, adaptive detail, view error) now draw with the design system package. Application stylesheets that address the old classes must move to the new ones.
Removed classes: tlPanel*, tlCard*, tlStack*, tlGrid*, tlInset, tlBounded, tlItem, tlDeckPane, tlSplitPanel*, tlTileStack*, tlWizard*, tlAdaptiveDetail*, tlViewError*, tlHtml__error. The dialog footer tl-dialog__footer is now tl-button-bar.
Removed custom properties: --page-inset (the surface sets the inset: tl-inset, tl-inset--panel, tl-inset--card); --tlGrid-gap. --tl-item-index is now --item-index.
States are attributes, not classes: minimized/maximized panel [data-tl-state~="minimized"], ~="maximized"; collapsed split pane [data-tl-state~="collapsed"], all collapsed [data-tl-state~="all-collapsed"]; tile stack and wizard transitions [data-tl-state~="entering"], ~="exiting", ~="covered", direction ~="backward"; wizard steps [data-tl-state~="done"], current [aria-current="step"]; a selected item [aria-selected="true"] (no tlItem--selectable/--selected).
Old → new (selection):
| = Old = | = New = |
| .tlPanel | .tl-panel |
| .tlPanel--card | .tl-panel.tl-card |
| .tlPanel__header, __title, __toolbar, __actions | .tl-titlebar, __title (h2), __actions, __buttons |
| .tlPanel__content | .tl-panel__body |
| .tlPanel__buttonBar, .tl-dialog__footer | .tl-button-bar |
| .tlCard, --outlined, --elevated | .tl-card (surface by nesting: --nested, --overlay; no shadow) |
| .tlStack, .tlGrid, --gap-* | .tl-stack, .tl-grid, --gap-compact/default/loose |
| .tlInset | .tl-inset |
| .tlBounded, .tlItem, .tlDeckPane | .tl-bounded, .tl-item, .tl-deck |
| .tlSplitPanel, __child, __splitter | .tl-split, __pane, __handle (role="separator") |
| .tlTileStack, __frame | .tl-tile-stack, __frame |
| .tlWizard* | .tl-wizard* |
| .tlAdaptiveDetail, __breadcrumb | .tl-adaptive-detail, __bar > .tl-breadcrumb |
| .tlViewError, .tlHtml__error | .tl-alert[data-tl-role="error"] |
The complete table is in the design system repository, docs/migration/altlast.md, section "Welle 4c".
Visible changes: gaps in stack and grid are narrower (default 1rem instead of 1.5rem); panel heads have no tint, the title is no longer bold, 40px instead of 48px; card bodies are padded 1rem instead of 1.5rem; elevated cards have no shadow; the split handle is a line instead of a bar and can be moved with the keyboard (arrow keys, Home, End; double click resets to the configured sizes); the width handle of a table column takes the same keyboard; a view that cannot be loaded shows an error message of the package.