@atomazing-org/design-system 2.0.1 → 3.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/AGENTS.md +92 -0
  2. package/README.MD +263 -335
  3. package/dist/index.d.ts +11 -15
  4. package/dist/index.js +22 -22
  5. package/dist/presets/index.d.ts +15 -2
  6. package/dist/presets/index.js +315 -313
  7. package/dist/themePresets-CwgG5XEL.d.ts +65 -0
  8. package/dist/themePresets-CwgG5XEL.js +1 -0
  9. package/migrations/README.UPDATE.md +34 -20
  10. package/migrations/docs/migrations/design-system/README.md +48 -17
  11. package/migrations/docs/migrations/design-system/routes/adopt-existing/AEROCRM-EXAMPLE.md +197 -0
  12. package/migrations/docs/migrations/design-system/routes/adopt-existing/RUNBOOK.md +185 -25
  13. package/migrations/docs/migrations/design-system/routes/adopt-existing/migration.spec.json +84 -20
  14. package/migrations/docs/migrations/design-system/routes/greenfield/RUNBOOK.md +57 -25
  15. package/migrations/docs/migrations/design-system/routes/greenfield/migration.spec.json +37 -14
  16. package/migrations/docs/migrations/design-system/routes/mui4-to-latest/RUNBOOK.md +136 -77
  17. package/migrations/docs/migrations/design-system/routes/mui4-to-latest/migration.spec.json +104 -29
  18. package/migrations/docs/migrations/design-system/shared/WORKING-RULES.md +194 -0
  19. package/migrations/docs/migrations/design-system/shared/acceptance.md +76 -20
  20. package/migrations/docs/migrations/design-system/shared/common-regressions.md +218 -0
  21. package/migrations/docs/migrations/design-system/shared/gates.md +39 -3
  22. package/migrations/docs/migrations/design-system/shared/manual-qa-matrix.md +70 -0
  23. package/migrations/docs/migrations/design-system/shared/phase-exit-criteria.md +129 -0
  24. package/migrations/docs/migrations/design-system/shared/phases.md +377 -0
  25. package/migrations/skills/design-system-consumer-agent/SKILL.md +84 -0
  26. package/migrations/skills/design-system-migration-agent/SKILL.md +75 -9
  27. package/package.json +14 -4
  28. package/dist/typography-B-BeIk0v.d.ts +0 -120
@@ -0,0 +1,65 @@
1
+ import { ThemeOptions, TypeBackground } from '@mui/material/styles';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * Available options for dark mode configuration.
6
+ * - `system`: Follows the operating system preference.
7
+ * - `light`: Forces light mode.
8
+ * - `dark`: Forces dark mode.
9
+ */
10
+ type DarkModeOptions = "system" | "light" | "dark";
11
+ interface OptionItem {
12
+ label: string;
13
+ value: DarkModeOptions;
14
+ icon: ReactNode;
15
+ }
16
+ type ThemeModeBackground = Partial<Record<"light" | "dark", Partial<TypeBackground>>>;
17
+ type NamedThemeOptions = ThemeOptions & {
18
+ name: string;
19
+ background?: ThemeModeBackground;
20
+ };
21
+ /**
22
+ * Represents user-specific theme preferences stored in the application.
23
+ */
24
+ interface AppSettings {
25
+ /**
26
+ * The selected preset id from the available themes list.
27
+ * Invalid or missing values are normalized to the first available theme.
28
+ */
29
+ themeId: string;
30
+ /**
31
+ * Controls how dark mode is applied in the app.
32
+ */
33
+ darkMode: DarkModeOptions;
34
+ }
35
+ interface ThemeContextProps {
36
+ theme: string;
37
+ darkMode: DarkModeOptions;
38
+ setTheme: (theme: string) => void;
39
+ setDarkMode: (mode: DarkModeOptions) => void;
40
+ themes: NamedThemeOptions[];
41
+ selectedTheme: NamedThemeOptions;
42
+ defaultThemeName: string;
43
+ }
44
+
45
+ type ThemeId = string;
46
+ type ThemeScheme = "light" | "dark";
47
+ type DarkModeSetting = DarkModeOptions;
48
+ interface ThemePreset {
49
+ id: ThemeId;
50
+ label: string;
51
+ colorSchemes: {
52
+ light: ThemeOptions;
53
+ dark: ThemeOptions;
54
+ };
55
+ description?: string;
56
+ tags?: string[];
57
+ version?: string;
58
+ }
59
+ type NormalizedPreset = ThemePreset & {
60
+ meta?: {
61
+ origin: "preset" | "legacy" | "custom";
62
+ };
63
+ };
64
+
65
+ export type { AppSettings as A, DarkModeOptions as D, NamedThemeOptions as N, OptionItem as O, ThemeContextProps as T, ThemePreset as a, ThemeModeBackground as b, NormalizedPreset as c, ThemeId as d, ThemeScheme as e, DarkModeSetting as f };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,29 +1,43 @@
1
- # Что здесь должно быть (исправленный формат)
1
+ # Migration And Agent Entry Points
2
2
 
3
- Вы правы: для этой задачи в `migrations/` нужны не исполняемые `mjs`-скрипты, а **инструкции для ИИ/агента**, который выполняет миграцию по runbook'ам.
3
+ This folder ships migration guidance and AI-facing instructions with
4
+ `@atomazing-org/design-system`.
4
5
 
5
- ## Source of truth
6
+ ## Source Of Truth
6
7
 
7
- - `migrations/skills/design-system-migration-agent/SKILL.md` — инструкция для ИИ (главная точка входа)
8
- - `migrations/docs/migrations/design-system/*` — маршруты миграции, runbook'и, shared criteria
8
+ - `AGENTS.md`
9
+ - `migrations/skills/design-system-consumer-agent/SKILL.md`
10
+ - `migrations/skills/design-system-migration-agent/SKILL.md`
11
+ - `migrations/docs/migrations/design-system/README.md`
12
+ - `migrations/docs/migrations/design-system/shared/WORKING-RULES.md`
9
13
 
10
- ## Как использовать (через ИИ)
14
+ ## What Ships With The Package
11
15
 
12
- 1) Дайте агенту задачу на миграцию проекта к `@atomazing-org/design-system`.
13
- 2) Укажите использовать skill:
14
- - `migrations/skills/design-system-migration-agent/SKILL.md`
15
- 3) Агент сам:
16
- - выберет route (`greenfield` / `adopt-existing` / `mui4-to-latest`);
17
- - прочитает нужный `RUNBOOK.md` и `migration.spec.json`;
18
- - выполнит шаги вручную (без обязательной зависимости от `migrations/scripts/*`);
19
- - прогонит проверки (`lint/test/build`) и acceptance criteria.
16
+ - working rules for application repositories
17
+ - route-based migration docs and shared gates
18
+ - AI skills for standard adoption and migration-heavy adoption
19
+ - a concrete `adopt-existing` case study in `routes/adopt-existing/AEROCRM-EXAMPLE.md`
20
20
 
21
- ## Что настроить перед запуском
21
+ ## Which Entry Point To Use
22
22
 
23
- - Заменить `<SET_VERSION>` в route spec (или сообщить версию агенту явно).
24
- - Для token migration подготовить mapping (`token-map.csv`) под конкретный проект.
25
- - Для route `adopt-existing` определить список legacy token imports/identifiers (для search/gates).
23
+ - standard integration or maintenance:
24
+ - `migrations/skills/design-system-consumer-agent/SKILL.md`
25
+ - route-based migration:
26
+ - `migrations/skills/design-system-migration-agent/SKILL.md`
26
27
 
27
- ## Про `migrations/scripts/*`
28
+ ## When To Prefer Migration
28
29
 
29
- `migrations/scripts/*` сейчас можно считать **необязательной/избыточной реализацией** (референс для автоматизации). Для вашего исходного запроса source of truth — именно skill + docs.
30
+ Use route-based migration instead of ad hoc edits when the target app has:
31
+
32
+ - `@material-ui/*`
33
+ - a custom token or theme layer
34
+ - multiple theme providers or persistence stores
35
+ - a broad request to standardize the UI foundation on this package
36
+
37
+ ## Notes
38
+
39
+ - `migrations/scripts/*` is optional legacy automation.
40
+ - The docs and skills are the source of truth for AI-driven migration work.
41
+ - Migration closeout now requires a real app startup check, not only lint/test/build.
42
+ - Run `pnpm run check:migration-readiness` before migration work to validate the
43
+ local migration pack contract (routes, specs, shared docs, and gitignore rules).
@@ -6,7 +6,7 @@ This folder contains the migration router, runbooks, and route specs used to ado
6
6
  Target baseline:
7
7
  - design-system v2 contract
8
8
  - MUI v7
9
- - React 18/19
9
+ - React 18 or 19
10
10
 
11
11
  Repo route model (canonical):
12
12
  - `mui4-to-latest` (backlog alias: `mui4-to-v7`)
@@ -17,53 +17,84 @@ Repo route model (canonical):
17
17
 
18
18
  1. If `package.json` contains `@material-ui/*` dependencies:
19
19
  - use `routes/mui4-to-latest/`
20
- 2. Else if the app is new / no existing theme-token migration is needed:
20
+ 2. Else if the app is new or no existing theme-token migration is needed:
21
21
  - use `routes/greenfield/`
22
22
  3. Else:
23
23
  - use `routes/adopt-existing/`
24
24
 
25
25
  ## Agent workflow (scriptless default)
26
26
 
27
- Use the AI skill/instructions as the primary execution method:
27
+ Use the AI skill or instructions as the primary execution method:
28
28
 
29
+ - `migrations/skills/design-system-consumer-agent/SKILL.md`
29
30
  - `migrations/skills/design-system-migration-agent/SKILL.md`
30
31
 
31
32
  Default flow:
32
33
 
33
- 1. Detect route manually (inspect `package.json`, imports, and current theme setup).
34
- 2. Read the selected route spec + runbook:
34
+ 1. Read `shared/WORKING-RULES.md`.
35
+ 2. Read `shared/phases.md`.
36
+ 3. Detect route manually (inspect `package.json`, imports, and current theme setup).
37
+ 4. Read the selected route spec plus runbook:
35
38
  - `routes/<routeId>/migration.spec.json`
36
39
  - `routes/<routeId>/RUNBOOK.md`
37
- 3. Execute steps from the spec/runbook in the target repo.
38
- 4. Run quality gates / checks (scripted or equivalent manual checks):
39
-
40
- ```bash
41
- npm test
42
- npm run build
43
- ```
40
+ 5. Build a phased plan before editing the target repo.
41
+ 6. Execute the route phase by phase instead of batching unrelated changes together.
42
+ 7. Run quality gates and checks after each meaningful phase, including a real app boot check before closeout.
43
+
44
+ ## Phase Discipline For Large Projects
45
+
46
+ For large repos, route execution must stay phase-gated:
47
+
48
+ - keep the app runnable at the end of every phase
49
+ - keep one main change class per phase:
50
+ - dependency landing
51
+ - mechanical migration
52
+ - root theme unification
53
+ - runtime cleanup
54
+ - shared infrastructure
55
+ - domain waves
56
+ - final token and closeout cleanup
57
+ - do not combine dependency upgrades, shell rewrites, and broad token cleanup into one unvalidated batch
58
+ - add or tighten a smoke safety net before broad shell, overlay, or shared-component rewrites
59
+ - stabilize shared infrastructure before domain-by-domain feature waves
60
+ - checkpoint each phase with a commit or equivalent rollback point before continuing
44
61
 
45
62
  Recommended manual gate equivalents:
46
63
  - search for `@material-ui/*` in source and `package.json`
47
- - search for legacy token imports/identifiers defined for the route/project
64
+ - search for legacy token imports or identifiers defined for the route or project
65
+ - start the app with the repo's normal dev or start command
66
+ - open the first route in a real browser and confirm there are no browser console startup errors
67
+ - fix migration-caused startup warnings before closeout, especially duplicate runtime singleton warnings (`react`, `react-dom`, `@emotion/react`, `@emotion/styled`)
68
+ - if route guards exist, verify at least one protected route as a real screen rather than a fallback page
69
+ - if overlays are in scope, verify at least one stable overlay interaction through smoke or manual QA
70
+ - if shell workspaces or page-root containers were touched, verify the main content fully occupies the workspace and dashboard or form grids do not collapse into partial-width stacks
71
+ - if shared charts, legends, chips, segmented filters, or metric badges were touched, verify compact controls still align with the active preset instead of drifting into ad hoc chip-like chrome
72
+ - if bulk replacements or non-Latin copy were touched, scan for mojibake or replacement characters and verify readable localized text on at least one real route
73
+
74
+ If normal integration would leave dual theme systems or a large unresolved token layer,
75
+ do not treat the task as a small refactor. Select a migration route instead.
48
76
 
49
77
  ## Route index
50
78
 
51
79
  - `mui4-to-latest`: `./routes/mui4-to-latest/RUNBOOK.md`
52
80
  - `greenfield`: `./routes/greenfield/RUNBOOK.md`
53
- - `adopt-existing`: `./routes/adopt-existing/RUNBOOK.md` (also used for backlog Phase 14 specialization)
81
+ - `adopt-existing`: `./routes/adopt-existing/RUNBOOK.md`
82
+ - `adopt-existing` example: `./routes/adopt-existing/AEROCRM-EXAMPLE.md`
54
83
 
55
84
  ## Shared gates
56
85
 
57
86
  Common migration gates are documented in:
58
87
 
88
+ - `./shared/phases.md`
89
+ - `./shared/phase-exit-criteria.md`
90
+ - `./shared/common-regressions.md`
91
+ - `./shared/manual-qa-matrix.md`
59
92
  - `./shared/gates.md`
60
93
  - `./shared/acceptance.md`
61
94
 
62
- Routes should reference the shared gates docs instead of duplicating the full gate list.
95
+ Routes should reference the shared gate docs instead of duplicating the full gate list.
63
96
 
64
97
  ## Notes
65
98
 
66
99
  - Route phases in this repo backlog may be completed in `docs/spec-first` mode before real app dry-runs.
67
100
  - A dedicated `mui5-6-to-v7` route split is a post-v2 option, not a blocker for the current repo route model.
68
-
69
-
@@ -0,0 +1,197 @@
1
+ # AeroCRM Frontend Example For `adopt-existing`
2
+
3
+ This example captures a full migration of
4
+ `C:\Users\Lenovo\Desktop\DEV_PRESALE\aerocrm\frontend` to
5
+ `@atomazing-org/design-system@2.0.1`.
6
+
7
+ ## Why `adopt-existing`
8
+
9
+ The app already had:
10
+
11
+ - React 19
12
+ - MUI 7
13
+ - `@atomazing-org/design-system`
14
+ - an app-level wrapper around `ThemeProviderWrapper`
15
+
16
+ This was not a greenfield integration and not a Material UI v4 migration.
17
+
18
+ ## Real Problems Found
19
+
20
+ 1. A consumer component still imported `useResponsiveDisplay` from the old design-system root API.
21
+ 2. The app crashed on startup because a Lingui translation was evaluated at module scope before locale activation.
22
+ 3. After the crash was fixed, the app still warned that `@emotion/react` was loaded more than once in dev.
23
+ 4. A shell refactor temporarily broke the desktop layout, so the original `sidebar + content` grid was lost.
24
+ 5. The app had no automated shell smoke-check, so the layout regression was caught manually at first.
25
+ 6. Several shared UI components were flattened into pass-through wrappers or empty placeholders, which degraded charts, drawers, segmented controls, cards, and toolbars across multiple screens.
26
+ 7. Smoke mode disabled auth redirect, but without a seeded user it only exercised route fallbacks like `NotFound` instead of the protected pages that actually matter.
27
+ 8. Some consumer-owned atoms still reimplemented stock MUI primitives with generic wrappers such as `Box`, raw `label`, or `div`, which made the shared layer inconsistent and easy to regress.
28
+ 9. Text rendering was inconsistent across shared and page UI: raw text remained inside buttons, chips, alerts, and wrappers, and some `Typography` nodes had no explicit variant.
29
+ 10. Preset selection lived behind a generic constants passthrough layer instead of one explicit app-owned theme module.
30
+ 11. Role-based ticket workflows duplicated the same two-column form shell across `NewTicket`, `Responsible`, and `Approver`.
31
+ 12. Local barrel re-exports produced chunk-cycle build warnings until workflow-local modules were imported directly.
32
+ 13. Workbox still looked for `favicon.svg` even though the app emitted `logo192.png`, `logo256.png`, `logo384.png`, and `logo512.png`.
33
+ 14. Build output contained oversized consumer-owned chunks until vendor splitting was configured explicitly.
34
+ 15. Shared overlays had semantic drift: dialog and drawer wrappers no longer exposed stable label or description wiring, command palette search behaved like generic markup instead of combobox or listbox UI, and decorative bottom-sheet chrome remained visible to assistive technology.
35
+ 16. `PwaInitializer` attached browser listeners from the render path, which risked duplicate `beforeinstallprompt` and display-mode handlers after rerenders.
36
+ 17. The app still kept a zero-value `SurfaceCard` wrapper that only forwarded to MUI `Card`, which blurred ownership between app primitives and stock MUI surfaces.
37
+ 18. Shared consumer styling still contained design-contract drift:
38
+ - the PWA install banner injected its own gradient chrome
39
+ - sidebar selection used palette-string alpha suffix hacks instead of theme helpers
40
+ - the repo-local design-contract lint did not yet protect against those patterns
41
+ 19. A later QA pass found compact analytics legend chips that no longer matched the active preset and read like ad hoc consumer chrome instead of neutral shared UI.
42
+ 20. Some page roots stopped filling the workspace, so tickets and analytics could collapse into partial-width content with broken grids and unused work area.
43
+ 21. A later text-integrity pass found mojibake and replacement characters in Cyrillic copy across screens, fixtures, and mock data.
44
+ 22. A later shell-sizing pass found the shared workspace overflowing on the right edge across routes because some shared containers mixed `width: 100%` with internal padding under content-box sizing.
45
+ 23. A later analytics QA pass found metric labels, values, and helper text collapsing into the same visual level, while the reasons card still carried an accidental full-width span and inconsistent gaps.
46
+
47
+ ## Applied Fixes
48
+
49
+ 1. Upgrade `@atomazing-org/design-system` from `1.2.9` to `2.0.1`.
50
+ 2. Replace the outdated root import in `ResponsiveModal` with the app's local `@hooks` export.
51
+ 3. Remove module-scope translation from the toast layer:
52
+ - do not call translation helpers at module scope before `i18n.loadAndActivate()`
53
+ - move the translated label into component render with `Trans`
54
+ 4. Deduplicate singleton runtimes in Vite:
55
+ - add `resolve.dedupe` for `react`, `react-dom`, `@emotion/react`, and `@emotion/styled`
56
+ 5. Restore the app shell layout in `Harness.tsx`:
57
+ - keep an explicit desktop grid for `sidebar + content`
58
+ - preserve content scrolling and sizing with `minHeight`, `minWidth`, and `overflow`
59
+ 6. Add an automated smoke-check:
60
+ - run the app in mock mode
61
+ - disable silent auth redirect only for smoke mode
62
+ - seed a deterministic demo user with required roles in smoke mode
63
+ - assert desktop and mobile shell layout with Playwright
64
+ - assert role-protected pages render real content, not only shell plus fallback
65
+ 7. Restore shared UI contracts when they were simplified into placeholders:
66
+ - rebuild shared cards, overlays, radio groups, charts, and nav actions with explicit spacing, sizing, and interaction states
67
+ - do not accept placeholder structures like empty `Box` tracks or pass-through wrappers as "good enough" migration output
68
+ 8. Replace substitute shared primitives with MUI-based equivalents when no real custom behavior exists:
69
+ - move atoms like `IconButton`, `FormLabel`, `FormError`, and `Skeleton` onto direct MUI primitives or thin wrappers
70
+ - move picker clear affordances into MUI `InputAdornment` instead of keeping floating ad hoc controls
71
+ 9. Normalize the text layer:
72
+ - render visible text through `Typography` with explicit variants
73
+ - wrap button, chip, alert, menu-item, and toggle labels in `Typography component="span"`
74
+ - add a small typography contract lint so future refactors cannot silently reintroduce raw text nodes
75
+ 10. Make preset policy explicit:
76
+ - replace generic constants passthrough exports with one theme-owned `appThemes` module
77
+ - keep the consumer's allowed preset pack visible near `AppThemeProvider`
78
+ 11. Add a design-contract guard:
79
+ - fail the migration on hardcoded colors, raw numeric type scale, and ad hoc radius or opacity values when those patterns are widespread
80
+ 12. Collapse repeated workflow page shells into one layout contract:
81
+ - extract a shared `TicketFormLayout` for the common two-column form shell
82
+ - keep page-specific behavior in headers and sections
83
+ - import workflow-local modules directly when barrel exports create chunk-cycle warnings
84
+ 13. Align PWA asset config with real app assets:
85
+ - replace the stale `favicon.svg` Workbox glob with the actual emitted logo files
86
+ 14. Split oversized local bundles intentionally:
87
+ - add targeted `manualChunks` groups for React, MUI, Emotion, forms, auth, i18n, design-system, and module-federation vendor code
88
+ - remove chunk warnings by changing bundling strategy, not by inflating the warning threshold
89
+ 15. Refresh the local browser-target database:
90
+ - update `caniuse-lite` / Browserslist data so the build reflects the current target matrix
91
+ 16. Restore overlay semantics and overlay-smoke coverage:
92
+ - wire `ResponsiveModal`, shared dialog titles, and notification drawer through stable `aria-labelledby` and `aria-describedby` ids
93
+ - add explicit accessible labels to shared close actions
94
+ - hide decorative bottom-sheet handles from assistive technology
95
+ - update smoke checks through stable overlay entrypoints such as notifications and command palette
96
+ 17. Normalize command palette search semantics:
97
+ - make the search field a real combobox
98
+ - make the result list a real listbox with active option tracking and keyboard-help text
99
+ 18. Move browser-only PWA listeners into effects with cleanup:
100
+ - attach `beforeinstallprompt` and display-mode listeners from `useEffect`
101
+ - remove duplicate subscriptions on rerender
102
+ 19. Remove zero-value surface wrappers:
103
+ - delete `SurfaceCard`
104
+ - use direct MUI `Card` composition in analytics, profile, tickets, and metric surfaces
105
+ 20. Harden the consumer visual-token contract:
106
+ - simplify the PWA install banner to a standard MUI surface instead of a local gradient panel
107
+ - replace palette alpha suffix hacks with `alpha()`
108
+ - expand `lint:design-contract` to fail on decorative gradients, direct shadow styling, theme shadow-token drift, and palette suffix hacks
109
+ - keep the theme swatch as the only documented exception because it intentionally previews preset colors
110
+ 21. Rework preset-drifted analytics legends:
111
+ - replace custom chip-like legend chrome with neutral marker plus `Typography` composition
112
+ - keep compact analytic labels visually aligned with the preset instead of recreating local chip styling
113
+ 22. Restore workspace fill behavior:
114
+ - preserve flex growth and min-size constraints in the shell content area
115
+ - make ticket and analytics page roots fill the available content pane instead of shrinking to content width
116
+ 23. Normalize Cyrillic text integrity:
117
+ - repair mojibake and replacement-character corruption in touched UI files and mocks
118
+ - keep rewritten files in UTF-8
119
+ - recheck smoke-visible strings after bulk fixes
120
+ 24. Harden shared box sizing for shell-critical containers:
121
+ - remove shell sizing that makes the main content column wider than the visible desktop workspace
122
+ - apply `box-sizing: border-box` to shared padded containers such as app-owned cards and page roots when they are also expected to fill available width
123
+ - add smoke assertions that fail on horizontal overflow in the shared content pane and routed page roots
124
+ 25. Restore analytics dashboard hierarchy and grid discipline:
125
+ - separate metric labels, values, and helper text into different text scales instead of relying on one blended default
126
+ - emphasize numeric values in breakdown lists and timeline rows so they do not read like surrounding labels
127
+ - remove the accidental full-width analytics-card span and keep one consistent desktop gap contract across the dashboard grid
128
+ - add smoke assertions that fail if metric value emphasis disappears or if the desktop analytics cards stop sharing the intended row
129
+
130
+ ## Resulting Validation
131
+
132
+ - `npm run lint` passed
133
+ - `npm run lint:style-contract` passed
134
+ - `npm run lint:design-contract` passed
135
+ - `npm run lint:typography-contract` passed
136
+ - `npm run lint:ts` passed
137
+ - `npm run build` passed
138
+ - `npm run test:smoke` passed
139
+ - the app started successfully in the browser
140
+ - first page load completed with `0` browser console errors
141
+ - first page load completed with `0` browser console warnings
142
+ - desktop layout again renders with the menu on the left and page content on the right
143
+ - ticket and analytics pages again occupy the full workspace instead of collapsing into partial-width stacks
144
+ - shared workspace content no longer protrudes past the visible right edge when routed pages render padded full-width surfaces
145
+ - analytics metrics again read as metrics instead of plain helper text, and the reasons card no longer drops onto its own desktop row
146
+ - `npm run test:smoke` now protects the shell layout, smoke auth bootstrapping, profile rendering, and analytics route against the same regression class
147
+ - `npm run test:smoke` now also protects notification drawer and command palette overlay behavior through stable entrypoints
148
+ - `npm run test:smoke` now also fails if the shared content pane or routed page roots overflow horizontally on desktop
149
+ - `npm run test:smoke` now also fails if analytics metric emphasis disappears or if the three desktop analytics cards stop aligning in the intended row
150
+ - preset selection is now explicit in a theme-owned `appThemes` module instead of a generic constants passthrough
151
+ - repeated ticket workflow pages now share a `TicketFormLayout` contract instead of duplicating the same shell three times
152
+ - build no longer reports the previous local chunk-cycle warning around `UploadedFiles`
153
+ - Workbox no longer warns about a missing `favicon.svg`
154
+ - local chunk-size warnings are gone after targeted vendor splitting
155
+ - the stale Browserslist database warning is gone after refreshing `caniuse-lite`
156
+ - shared overlays now expose stable dialog semantics instead of relying on incidental text structure
157
+ - command palette search now follows explicit combobox or listbox accessibility semantics
158
+ - browser-driven PWA listeners no longer attach during render
159
+ - analytics, profile, and ticket surfaces no longer depend on a zero-value `SurfaceCard` wrapper
160
+ - the PWA install banner no longer competes with preset styling through a local gradient surface
161
+ - sidebar state styling now uses theme helpers instead of palette-string alpha suffix hacks
162
+ - `lint:design-contract` now enforces decorative-token drift rules with a documented swatch exception
163
+ - analytics legends no longer use preset-breaking custom chip chrome
164
+ - the post-fix text scan no longer finds mojibake or replacement characters in the touched migration surface
165
+
166
+ ## Lessons To Reuse
167
+
168
+ - A green build does not prove the app actually boots after migration.
169
+ - Startup console errors must be part of the migration gate, not an optional QA note.
170
+ - Module-scope i18n work is a migration risk in apps that initialize locale asynchronously.
171
+ - Duplicate React or Emotion runtime warnings should be fixed immediately with bundler dedupe or the repo's equivalent singleton-sharing mechanism.
172
+ - Layout wrappers are behavioral infrastructure. Replacing them with plain containers without porting grid or flex constraints can break the whole app shell even when TypeScript and build are green.
173
+ - Route roots need the same discipline as shell wrappers. If they stop stretching to fill the workspace, dashboards and work areas can look broken even though the route still technically renders.
174
+ - Width filling plus internal padding needs explicit box-sizing discipline in shared containers. A padded app-owned `Card` or page root with `width: 100%` can silently overflow the workspace by a few pixels on every route.
175
+ - Dashboard metrics need their own hierarchy gate. If labels, values, and helper text collapse to one scale, the screen still renders but stops communicating status.
176
+ - Desktop dashboard grids need explicit span discipline. A stale full-width card prop can silently break row alignment even when the page still compiles and passes a basic render check.
177
+ - Route-protected pages need a deterministic smoke user; otherwise automated checks may "pass" against `NotFound` or fail for the wrong reason.
178
+ - Shared UI regressions often show up as flattened pass-through wrappers or empty placeholder markup. Search for those patterns explicitly after migration.
179
+ - Compact shared UI can regress without turning into placeholders. Chart legends, chips, and segmented filters should be checked for preset drift, not only for presence.
180
+ - Shared UI layers can also hide substitute atoms that duplicate stock MUI controls. Replace them during migration instead of treating them as acceptable legacy structure.
181
+ - Overlay wrappers can silently lose semantic wiring even when the visual layout still looks acceptable. Keep stable title or description ids, labeled close actions, and combobox or listbox roles under test when overlays are touched.
182
+ - Decorative overlay chrome such as bottom-sheet grab handles should be hidden from assistive technology unless it conveys state.
183
+ - Browser event listeners belong in effects with cleanup. Render-path subscriptions can create duplicated runtime behavior without tripping TypeScript or build.
184
+ - Zero-value surface wrappers are not harmless convenience. If a wrapper only forwards MUI `Card` or `Paper`, delete it and keep the component tree honest.
185
+ - Design-contract lint should guard against decorative gradients, direct shadow styling, and palette alpha suffix hacks, not only raw hex colors.
186
+ - If a visual-preview component really needs gradient or shadow styling, document that exception inline and keep it on a tiny explicit allowlist instead of letting the pattern spread.
187
+ - Keep preset policy explicit in the theme layer. Generic constants passthrough files hide the real allowed preset pack and make later migration drift easier.
188
+ - If several role-based pages share the same shell, extract one layout contract before making further visual changes. Duplicated workflow shells drift quickly.
189
+ - Local app barrels are optional, not sacred. If a barrel creates chunk-cycle warnings, use direct imports for the affected workflow internals.
190
+ - A small design-contract lint is worth adding when raw colors, raw numeric font sizes, or ad hoc radius/opacity values are already spreading through the UI.
191
+ - Asset globs are part of migration correctness. If PWA config points at files the app does not emit, fix the config instead of carrying the warning forward.
192
+ - For chunk warnings, prefer targeted vendor splitting or new lazy boundaries. Raising the warning limit is not a migration fix.
193
+ - If one warning remains and it comes from an upstream toolchain package, record it precisely as external debt instead of treating it as unresolved app work.
194
+ - Text regressions deserve their own gate. If an app has broad UI churn, add a typography contract check so raw text nodes and variantless typography fail fast.
195
+ - Encoding regressions deserve their own gate too. After bulk rewrites, scan for mojibake or replacement characters and verify at least one real localized route before closing the migration.
196
+ - For important shell layouts and core pages, add a dedicated smoke-check instead of relying only on manual QA after migration.
197
+ - For overlay-heavy apps, prefer smoke coverage through stable entrypoints such as notification drawers or command palettes instead of brittle settings-modal paths that are not consistently reachable in the current route.