@micha.bigler/ui-core-micha 3.14.4 → 4.0.0
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.
- package/CHANGELOG.md +25 -0
- package/README.md +7 -0
- package/dist/chat/kitSxRegistry.js +9 -0
- package/dist/components/charts/kitSxRegistry.js +6 -0
- package/dist/entries/charts.js +6 -0
- package/dist/entries/chat.js +8 -0
- package/dist/entries/markdown.js +1 -0
- package/dist/index.js +0 -14
- package/dist/pages/AccountPage.js +1 -2
- package/dist/pages/LoginPage.js +1 -2
- package/dist/pages/PasswordChangePage.js +1 -2
- package/dist/pages/PasswordInvitePage.js +1 -2
- package/dist/pages/PasswordResetRequestPage.js +1 -2
- package/dist/pages/SignUpPage.js +1 -2
- package/dist/pages/SignupConfirmPage.js +1 -2
- package/dist/theme/kitSxEntry.js +11 -0
- package/dist/theme/kitSxRegistry.js +2 -15
- package/package.json +32 -7
- package/.github/workflows/ci.yml +0 -35
- package/.github/workflows/publish.yml +0 -126
- package/DESIGN.md +0 -60
- package/WORK_ORDERS.md +0 -150
- package/dev/entries.jsx +0 -721
- package/dev/fixtures.js +0 -26
- package/dev/main.jsx +0 -75
- package/dev/mockTransport.jsx +0 -128
- package/docs/CHART-LAYOUT.md +0 -157
- package/docs/DARK-TOKENS.md +0 -140
- package/docs/TYPE-SCALE.md +0 -111
- package/docs/messaging-deviations.md +0 -118
- package/index.html +0 -12
- package/renovate.json +0 -10
- package/scripts/chart-api-census.mjs +0 -415
- package/src/auth/AuthContext.jsx +0 -158
- package/src/auth/ReauthModal.jsx +0 -82
- package/src/auth/UserMenu.jsx +0 -121
- package/src/auth/apiClient.jsx +0 -232
- package/src/auth/authApi.jsx +0 -539
- package/src/auth/authConfig.jsx +0 -34
- package/src/auth/reauth.js +0 -47
- package/src/chat/ChatComposer.jsx +0 -36
- package/src/chat/ChatList.jsx +0 -87
- package/src/chat/ChatThread.jsx +0 -128
- package/src/chat/ChatWorkspace.jsx +0 -244
- package/src/chat/MarkdownReply.jsx +0 -22
- package/src/chat/ModelPicker.jsx +0 -85
- package/src/chat/api.js +0 -18
- package/src/chat/useChatSocket.js +0 -32
- package/src/chat/wire.js +0 -7
- package/src/components/AccessCodeManager.jsx +0 -288
- package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
- package/src/components/AllowedEmailDomainsManager.jsx +0 -92
- package/src/components/AuthFactorRequirementCard.jsx +0 -95
- package/src/components/BulkInviteCsvTab.jsx +0 -198
- package/src/components/EmptyState.jsx +0 -38
- package/src/components/LoginForm.jsx +0 -159
- package/src/components/MFAComponent.jsx +0 -350
- package/src/components/MfaLoginComponent.jsx +0 -252
- package/src/components/MobileBottomNav.jsx +0 -82
- package/src/components/PasskeysComponent.jsx +0 -252
- package/src/components/PasswordChangeForm.jsx +0 -87
- package/src/components/PasswordResetRequestForm.jsx +0 -43
- package/src/components/PasswordSetForm.jsx +0 -97
- package/src/components/ProfileComponent.jsx +0 -348
- package/src/components/QrSignupManager.jsx +0 -404
- package/src/components/QrSignupValidityManager.jsx +0 -106
- package/src/components/RegistrationMethodsManager.jsx +0 -150
- package/src/components/SecurityComponent.jsx +0 -141
- package/src/components/SocialLoginButtons.jsx +0 -83
- package/src/components/SoftChip.jsx +0 -93
- package/src/components/StatTile.jsx +0 -39
- package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
- package/src/components/TurnstileWidget.jsx +0 -99
- package/src/components/UserInviteComponent.jsx +0 -76
- package/src/components/UserListComponent.jsx +0 -618
- package/src/components/charts/BarChart.jsx +0 -102
- package/src/components/charts/ChartFrame.jsx +0 -214
- package/src/components/charts/LineChart.jsx +0 -126
- package/src/components/charts/ScatterChart.jsx +0 -299
- package/src/components/charts/TimeSeriesChart.jsx +0 -300
- package/src/components/charts/chartDefaults.js +0 -644
- package/src/components/charts/chartLabels.js +0 -36
- package/src/components/charts/exportChart.js +0 -258
- package/src/components/charts/formatters.js +0 -39
- package/src/components/charts/palette.js +0 -33
- package/src/components/charts/yearTickInterval.js +0 -7
- package/src/i18n/authTranslations.ts +0 -2651
- package/src/i18n/chartsTranslations.ts +0 -91
- package/src/i18n/chatTranslations.ts +0 -55
- package/src/i18n/messagingTranslations.ts +0 -120
- package/src/i18n/notificationsTranslations.ts +0 -32
- package/src/i18n/onboardingTranslations.ts +0 -29
- package/src/i18n/sectionNavTranslations.ts +0 -20
- package/src/i18n/uiCoreTranslations.js +0 -29
- package/src/i18n/userMenuTranslations.ts +0 -5
- package/src/index.js +0 -158
- package/src/layout/PageLayout.jsx +0 -36
- package/src/layout/SectionNav.jsx +0 -320
- package/src/messaging/AttachmentList.jsx +0 -145
- package/src/messaging/Composer.jsx +0 -197
- package/src/messaging/ConversationLaunchers.jsx +0 -51
- package/src/messaging/ConversationList.jsx +0 -109
- package/src/messaging/DirectMessageLauncher.jsx +0 -112
- package/src/messaging/MessageBubble.jsx +0 -183
- package/src/messaging/MessagingProvider.jsx +0 -0
- package/src/messaging/MessagingScopeConfig.jsx +0 -24
- package/src/messaging/PollCard.jsx +0 -163
- package/src/messaging/ReactionBar.jsx +0 -43
- package/src/messaging/ReadTicks.jsx +0 -82
- package/src/messaging/Thread.jsx +0 -195
- package/src/messaging/api.js +0 -48
- package/src/messaging/composerImageCompression.js +0 -35
- package/src/messaging/linkifyText.jsx +0 -37
- package/src/notifications/NotificationBell.jsx +0 -84
- package/src/notifications/NotificationSettings.jsx +0 -330
- package/src/notifications/NotificationsProvider.jsx +0 -224
- package/src/notifications/PopupSurface.jsx +0 -105
- package/src/notifications/api.js +0 -55
- package/src/notifications/feedApi.js +0 -18
- package/src/notifications/realtime.jsx +0 -138
- package/src/notifications/serviceWorker/sw.js +0 -50
- package/src/onboarding/OnboardingProvider.jsx +0 -326
- package/src/onboarding/OnboardingWizard.jsx +0 -61
- package/src/onboarding/WizardDialogShell.jsx +0 -51
- package/src/onboarding/api.js +0 -13
- package/src/onboarding/stepSelection.js +0 -16
- package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
- package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
- package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
- package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
- package/src/pages/AccountPage.jsx +0 -394
- package/src/pages/LoginPage.jsx +0 -343
- package/src/pages/PasswordChangePage.jsx +0 -62
- package/src/pages/PasswordInvitePage.jsx +0 -177
- package/src/pages/PasswordResetRequestPage.jsx +0 -68
- package/src/pages/SignUpPage.jsx +0 -268
- package/src/pages/SignupConfirmPage.jsx +0 -155
- package/src/testing/checkKitIntegration.js +0 -233
- package/src/theme/createAppTheme.js +0 -423
- package/src/theme/fonts.js +0 -3
- package/src/theme/index.js +0 -21
- package/src/theme/kitSxRegistry.js +0 -285
- package/src/theme/themeCompleteness.js +0 -1045
- package/src/theme/tokens.js +0 -478
- package/src/utils/auth-errors.js +0 -76
- package/src/utils/authService.js +0 -223
- package/src/utils/resolveErrorText.js +0 -28
- package/src/utils/webauthn.js +0 -51
- package/tests/AccountPage.profileStatements.test.jsx +0 -162
- package/tests/AccountPage.test.jsx +0 -200
- package/tests/AuthContext.test.jsx +0 -129
- package/tests/BarChart.test.jsx +0 -112
- package/tests/BrowserPushStep.test.jsx +0 -110
- package/tests/ChartFrame.test.jsx +0 -336
- package/tests/ConversationList.test.jsx +0 -144
- package/tests/CookieConsentStep.test.jsx +0 -69
- package/tests/EmptyState.test.jsx +0 -62
- package/tests/LineChart.test.jsx +0 -80
- package/tests/MessagingProvider.test.jsx +0 -50
- package/tests/MobileBottomNav.test.jsx +0 -319
- package/tests/NotificationBell.test.jsx +0 -60
- package/tests/NotificationSettings.test.jsx +0 -276
- package/tests/NotificationsProvider.test.jsx +0 -240
- package/tests/OnboardingProvider.test.jsx +0 -294
- package/tests/OnboardingWizard.test.jsx +0 -143
- package/tests/PasswordChangeForm.test.jsx +0 -70
- package/tests/PasswordInvitePage.test.jsx +0 -142
- package/tests/PasswordSetForm.test.jsx +0 -70
- package/tests/PopupSurface.test.jsx +0 -142
- package/tests/ProfileComponent.refresh.test.jsx +0 -194
- package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
- package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
- package/tests/ScatterChart.test.jsx +0 -270
- package/tests/SectionNav.test.jsx +0 -363
- package/tests/SignUpPage.test.jsx +0 -208
- package/tests/SoftChip.test.jsx +0 -105
- package/tests/StatTile.test.jsx +0 -57
- package/tests/Thread.test.jsx +0 -151
- package/tests/TimeSeriesChart.test.jsx +0 -367
- package/tests/UserListComponent.test.jsx +0 -192
- package/tests/UserMenu.test.jsx +0 -171
- package/tests/apiClientLanguage.test.js +0 -33
- package/tests/apiClientPublicPaths.test.js +0 -178
- package/tests/authApiLogin.test.js +0 -42
- package/tests/authApiRegistration.test.js +0 -31
- package/tests/authErrorCodeRendering.test.jsx +0 -77
- package/tests/authErrors.test.js +0 -74
- package/tests/authTranslations.test.js +0 -74
- package/tests/chart-api-census.test.js +0 -366
- package/tests/chartAxisTickBand.test.jsx +0 -95
- package/tests/chartDefaults.test.js +0 -902
- package/tests/chartLabels.test.js +0 -50
- package/tests/chartsPalette.test.js +0 -99
- package/tests/chatApi.test.js +0 -48
- package/tests/chatDriverNames.test.jsx +0 -71
- package/tests/chatExports.test.js +0 -3
- package/tests/chatList.test.jsx +0 -84
- package/tests/chatPicker.test.jsx +0 -82
- package/tests/chatSocket.test.jsx +0 -26
- package/tests/chatThread.test.jsx +0 -116
- package/tests/chatTranslations.test.js +0 -47
- package/tests/chatWorkspace.test.jsx +0 -234
- package/tests/checkKitIntegration.test.jsx +0 -219
- package/tests/createAppTheme.test.js +0 -132
- package/tests/createAppThemeDark.test.js +0 -127
- package/tests/createAppThemeLightGuard.test.js +0 -40
- package/tests/createAppThemePageContrast.test.js +0 -108
- package/tests/createAppThemeTypography.test.js +0 -53
- package/tests/errorCallSiteGuard.test.js +0 -32
- package/tests/exportChart.test.js +0 -313
- package/tests/feedApi.test.js +0 -46
- package/tests/fixtures/light-theme-baseline.json +0 -2234
- package/tests/i18nAggregate.test.js +0 -120
- package/tests/i18nGermanVariant.test.js +0 -65
- package/tests/loginPageErrorResolution.test.jsx +0 -102
- package/tests/messagingApi.test.js +0 -32
- package/tests/messagingChunk6.test.jsx +0 -116
- package/tests/messagingCompactBubble.test.jsx +0 -64
- package/tests/messagingComposer.test.jsx +0 -136
- package/tests/messagingComposerChunk5.test.jsx +0 -113
- package/tests/messagingContractConformance.test.js +0 -69
- package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
- package/tests/messagingExports.test.js +0 -21
- package/tests/messagingInteractions.test.jsx +0 -136
- package/tests/messagingLastMessagePreview.test.jsx +0 -93
- package/tests/messagingLinkify.test.jsx +0 -51
- package/tests/messagingMessageActions.test.jsx +0 -163
- package/tests/messagingMsg6.test.jsx +0 -105
- package/tests/messagingMsg6f.test.jsx +0 -155
- package/tests/messagingMsg6g.test.jsx +0 -166
- package/tests/messagingMsg6h.test.jsx +0 -136
- package/tests/messagingMsg6i.test.jsx +0 -129
- package/tests/messagingPollRendering.test.jsx +0 -142
- package/tests/messagingReactionMerge.test.jsx +0 -77
- package/tests/messagingReadTicksTooltip.test.jsx +0 -36
- package/tests/messagingThreadReceipts.test.jsx +0 -178
- package/tests/messagingThreadingQuoting.test.jsx +0 -87
- package/tests/messagingUnreadLifecycle.test.jsx +0 -78
- package/tests/notificationsApi.test.js +0 -41
- package/tests/notificationsExports.test.js +0 -34
- package/tests/onboardingDescriptors.test.js +0 -132
- package/tests/packageTreeShaking.test.js +0 -126
- package/tests/realtime.test.jsx +0 -219
- package/tests/resolveErrorText.test.js +0 -72
- package/tests/stepSelection.test.js +0 -53
- package/tests/themeCompleteness.test.js +0 -626
- package/tests/timeSeriesLegend.test.js +0 -99
- package/tests/userScreenTranslations.test.jsx +0 -218
- package/tsconfig.build.json +0 -18
- package/vite.config.mjs +0 -6
- package/work-orders/AUTH-1.md +0 -74
- package/work-orders/AUTH-2.md +0 -74
- package/work-orders/AUTH-4.md +0 -183
- package/work-orders/AUTH-5.md +0 -154
- package/work-orders/AUTH-7.md +0 -181
- package/work-orders/AUTH-8.md +0 -184
- package/work-orders/CHART-1.md +0 -285
- package/work-orders/CHART-2.md +0 -222
- package/work-orders/CHART-3.md +0 -163
- package/work-orders/CHART-4.md +0 -203
- package/work-orders/CHART-5.md +0 -226
- package/work-orders/CHART-6.md +0 -428
- package/work-orders/CHART-7.md +0 -175
- package/work-orders/DX-1.md +0 -169
- package/work-orders/DX-2.md +0 -188
- package/work-orders/DX-3.md +0 -195
- package/work-orders/I18N-1.md +0 -254
- package/work-orders/I18N-3.md +0 -207
- package/work-orders/MSG-3.md +0 -375
- package/work-orders/MSG-3b.md +0 -1002
- package/work-orders/MSG-3c.md +0 -378
- package/work-orders/MSG-3d.md +0 -268
- package/work-orders/MSG-3e.md +0 -164
- package/work-orders/MSG-3f.md +0 -391
- package/work-orders/MSG-6e.md +0 -308
- package/work-orders/MSG-6f.md +0 -214
- package/work-orders/MSG-6g.md +0 -244
- package/work-orders/MSG-6h.md +0 -238
- package/work-orders/MSG-6i.md +0 -271
- package/work-orders/MSG-6j.md +0 -117
- package/work-orders/NOTIF-12.md +0 -214
- package/work-orders/NOTIF-13.md +0 -142
- package/work-orders/NOTIF-14.md +0 -151
- package/work-orders/PRIM-1.md +0 -177
- package/work-orders/SHELL-1.md +0 -255
- package/work-orders/SHELL-2.md +0 -197
- package/work-orders/SHELL-3.md +0 -359
- package/work-orders/SHELL-4.md +0 -351
- package/work-orders/SHELL-5.md +0 -345
- package/work-orders/SHELL-6.md +0 -210
- package/work-orders/THEME-1.md +0 -587
- package/work-orders/THEME-10.md +0 -303
- package/work-orders/THEME-11.md +0 -208
- package/work-orders/THEME-2.md +0 -339
- package/work-orders/THEME-3.md +0 -210
- package/work-orders/THEME-4.md +0 -271
- package/work-orders/THEME-5.md +0 -341
- package/work-orders/THEME-6.md +0 -247
- package/work-orders/THEME-7.md +0 -82
- package/work-orders/THEME-8.md +0 -211
- package/work-orders/THEME-9.md +0 -194
- package/work-orders/UCM-AUTH-10.md +0 -490
- package/work-orders/UCM-AUTH-11.md +0 -185
- package/work-orders/UCM-AUTH-12.md +0 -98
- package/work-orders/UCM-AUTH-13.md +0 -47
- package/work-orders/UCM-AUTH-9.md +0 -207
- package/work-orders/UCM-CHART-10.md +0 -150
- package/work-orders/UCM-CHART-11.md +0 -132
- package/work-orders/UCM-CHART-12.md +0 -348
- package/work-orders/UCM-CHART-13.md +0 -122
- package/work-orders/UCM-CHART-14.md +0 -198
- package/work-orders/UCM-CHART-15.md +0 -187
- package/work-orders/UCM-CHART-16.md +0 -169
- package/work-orders/UCM-CHART-17.md +0 -195
- package/work-orders/UCM-CHART-18.md +0 -200
- package/work-orders/UCM-CHART-8.md +0 -147
- package/work-orders/UCM-CHART-9.md +0 -265
- package/work-orders/UCM-CHAT-1.md +0 -190
- package/work-orders/UCM-CHAT-2.md +0 -75
- package/work-orders/UCM-CI-1.md +0 -65
- package/work-orders/UCM-DEP-1.md +0 -63
- package/work-orders/UCM-I18N-4.md +0 -226
- package/work-orders/UCM-I18N-5.md +0 -211
- package/work-orders/UCM-MSG-20.md +0 -192
- package/work-orders/UCM-PRIM-2.md +0 -114
- package/work-orders/UCM-SHELL-7.md +0 -134
- package/work-orders/UCM-SHELL-8.md +0 -125
- package/work-orders/UCM-TEST-1.md +0 -304
- package/work-orders/UCM-THEME-13.md +0 -69
- package/work-orders/UCM-THEME-14.md +0 -312
- package/work-orders/UCM-THEME-15.md +0 -356
- package/work-orders/UCM-THEME-16.md +0 -80
- package/work-orders/UCM-THEME-17.md +0 -111
- package/work-orders/UCM-THEME-18.md +0 -184
- package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
- package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
- package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
- package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
- package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
- package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
- package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
package/work-orders/THEME-2.md
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
# THEME-2 — Two defects from the THEME-1/CHART-6 landings: `warning.main` contrast, and `grid` replacing instead of merging
|
|
2
|
-
|
|
3
|
-
**Target repo:** `ui-core-micha` (branch `main` — this repo has no `develop`)
|
|
4
|
-
**Tier:** 2 (shared core — `ui-core-micha` is named in AGENTS.md's Tier-2 forcing list)
|
|
5
|
-
**Review:** independent `reviewer` **and** `ui_reviewer` — spawned concurrently, both mandatory before commit
|
|
6
|
-
**Version target:** `2.31.1` (patch — one palette value corrected, one merge bug fixed, one assertion rule added; no API change)
|
|
7
|
-
**Decision record:** `webapp-management/DESIGN_SYSTEM_PROGRAM.md` → "Open follow-ups from the two landings"
|
|
8
|
-
|
|
9
|
-
Short-form WO: both defects are fully diagnosed and measured. There is no design question in either.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## A. Envelope
|
|
14
|
-
|
|
15
|
-
### Goal
|
|
16
|
-
|
|
17
|
-
Fix the two defects found after `THEME-1` (`96992cf`) and `CHART-6` (`6dedc62`) landed, and in each
|
|
18
|
-
case close the **mechanism** rather than only the instance — both are the same failure class as
|
|
19
|
-
something already fixed, which is why they recurred.
|
|
20
|
-
|
|
21
|
-
### Defect 1 — `warning.main` fails AA as a foreground
|
|
22
|
-
|
|
23
|
-
THEME-1's R1 fix gave every status channel an explicit `main`/`light`/`dark`/`contrastText` (correct
|
|
24
|
-
— MUI was otherwise filling its stock hues for `color="success"` and friends). It put the **fill**
|
|
25
|
-
tone in `main`. Measured against `#FFFFFF`:
|
|
26
|
-
|
|
27
|
-
| Channel | `main` | as foreground | |
|
|
28
|
-
|---|---|---|---|
|
|
29
|
-
| success | `#1B8038` | 5.010 | passes |
|
|
30
|
-
| error | `#BF3227` | 5.674 | passes |
|
|
31
|
-
| **warning** | `#C08A2C` | **3.038** | **fails AA (4.5)** |
|
|
32
|
-
|
|
33
|
-
`main`/`contrastText` pairs are all fine (warning 5.078 with dark ink). The failure is only when
|
|
34
|
-
`main` is used as a **foreground on a light surface** — `<Typography color="warning.main">`,
|
|
35
|
-
`color="warning"` on an icon, and an outlined warning chip, whose border and label both come from
|
|
36
|
-
`main`.
|
|
37
|
-
|
|
38
|
-
**Why warning specifically, and why this is not carelessness:** green and red can serve both roles
|
|
39
|
-
with one value. Amber cannot. A legible amber **fill** needs dark text on it and must therefore stay
|
|
40
|
-
light; a legible amber **text** must be dark. The two requirements pull in opposite directions.
|
|
41
|
-
Warning is the one channel where "one hex for both roles" is impossible in principle — so the
|
|
42
|
-
pattern that works for success and error had to break here.
|
|
43
|
-
|
|
44
|
-
**Fix:** `warning.main` = `#976100` (the text tone already in the same token block, 5.216 on white),
|
|
45
|
-
`contrastText` = `#FFFFFF`. The light amber stays available as `warning.fill` for deliberate fill
|
|
46
|
-
use, unchanged.
|
|
47
|
-
|
|
48
|
-
**Accepted visual consequence, stated so nobody treats it as a regression:** a filled
|
|
49
|
-
`color="warning"` Button/Chip becomes a darker brown with white text instead of a lighter amber with
|
|
50
|
-
dark text. That is the price of one token serving MUI's `main` contract, and it is the operator's
|
|
51
|
-
call already recorded in the programme doc.
|
|
52
|
-
|
|
53
|
-
**Close the mechanism, not just the value:** add an assertion rule that checks **every** status
|
|
54
|
-
channel's `main` against `#FFFFFF` and `background.default` at 4.5:1. Without it the next channel
|
|
55
|
-
added repeats this exactly — the existing contrast checks were designed before R1 introduced `main`,
|
|
56
|
-
which is why they did not catch it.
|
|
57
|
-
|
|
58
|
-
### Defect 2 — `grid` is replaced, not merged
|
|
59
|
-
|
|
60
|
-
`LineChart` and `BarChart` declare `grid = { horizontal: true }` as a plain default parameter and
|
|
61
|
-
pass it straight through. A caller writing `grid={{ vertical: true }}` — intending to *add* vertical
|
|
62
|
-
lines — silently loses the horizontal ones.
|
|
63
|
-
|
|
64
|
-
This is the same class as the `scaleType` bug the rendered gate caught during CHART-6: **a partial
|
|
65
|
-
caller object erases a default.** `xAxis`, `yAxis`, `margin` and `slotProps` all go through merge
|
|
66
|
-
helpers; `grid` alone does not.
|
|
67
|
-
|
|
68
|
-
**Fix:** merge `grid` with the default the way the sibling props already do, so a caller adds to it
|
|
69
|
-
rather than replacing it.
|
|
70
|
-
|
|
71
|
-
**Close the mechanism:** audit the remaining object-valued props the wrappers default or forward
|
|
72
|
-
(`slots`, `tickLabelStyle` and anything CHART-6 introduced) for the same replace-instead-of-merge
|
|
73
|
-
shape, and state the result — either "all others already merge" or a named list. **Audit and report;
|
|
74
|
-
do not refactor beyond `grid`** unless the audit finds another live instance, in which case fix that
|
|
75
|
-
too and say so.
|
|
76
|
-
|
|
77
|
-
### Non-goals / do not touch
|
|
78
|
-
|
|
79
|
-
- The other status channels' `main` values — success and error measure fine and stay.
|
|
80
|
-
- `warning.fill` / `warning.text` / `warning.bg` — unchanged.
|
|
81
|
-
- The reference sheet's committed HTML artifact. It is the frozen spec of the accepted baseline;
|
|
82
|
-
`warning.main` is a channel the sheet never depicted (see Verification).
|
|
83
|
-
- Anything in `CHART-6`'s scope beyond the `grid` merge and the audit.
|
|
84
|
-
- No behaviour, permission or data-contract change.
|
|
85
|
-
|
|
86
|
-
### Risks
|
|
87
|
-
|
|
88
|
-
- **A palette value change is visible.** Any app already using `color="warning"` sees a darker
|
|
89
|
-
filled control. No app has an adoption WO yet, so the blast radius today is ucm's own harness — but
|
|
90
|
-
say it in the release note rather than let someone find it.
|
|
91
|
-
- **Adding an assertion rule can turn a green suite red.** Safe today by the ratchet: the
|
|
92
|
-
completeness check is a hard failure only for an app whose adoption WO has landed, and none has.
|
|
93
|
-
It must stay that way — the new rule must not become hard for non-adopters.
|
|
94
|
-
- **No staging net.** A push to `main` touching `src/**` publishes to npm at once; the independent
|
|
95
|
-
review is the only gate and is not back-fillable.
|
|
96
|
-
- **The `grid` merge changes behaviour for any caller who passes a partial `grid` today.** That is
|
|
97
|
-
the point, but it means the rendered check should look at a chart that passes `grid` explicitly if
|
|
98
|
-
one exists.
|
|
99
|
-
|
|
100
|
-
### Required tests to WRITE
|
|
101
|
-
|
|
102
|
-
Narrow. Extend the existing files rather than adding new ones.
|
|
103
|
-
|
|
104
|
-
**`tests/themeCompleteness.test.js`**
|
|
105
|
-
|
|
106
|
-
1. Every status channel's `main` clears 4.5:1 against `#FFFFFF` **and** against
|
|
107
|
-
`background.default`. **Prove non-vacuity** by restoring `warning.main` to `#C08A2C` and
|
|
108
|
-
confirming this test fails — that is the whole point of the rule.
|
|
109
|
-
2. The new rule reports, and does not hard-fail, for a theme belonging to an app without a landed
|
|
110
|
-
adoption WO (the ratchet stays intact).
|
|
111
|
-
|
|
112
|
-
**`tests/chartDefaults.test.js`**
|
|
113
|
-
|
|
114
|
-
3. A caller passing `grid={{ vertical: true }}` receives **both** `vertical: true` and the default
|
|
115
|
-
`horizontal: true`. **Prove non-vacuity** by reverting to the plain default parameter and
|
|
116
|
-
confirming the test fails.
|
|
117
|
-
4. A caller passing `grid={false}` (or the documented way to switch the grid off entirely) still
|
|
118
|
-
gets no grid — merging must not make the default un-removable.
|
|
119
|
-
|
|
120
|
-
Plus `tsc -p tsconfig.build.json --noEmit` clean.
|
|
121
|
-
|
|
122
|
-
**No full-suite run.** Affected-areas set is the two test files above.
|
|
123
|
-
|
|
124
|
-
### Verification
|
|
125
|
-
|
|
126
|
-
- The rendered two-width side-by-side per DS-1, **and this time it must cover what changed**: the
|
|
127
|
-
harness needs a specimen row rendering `color="success|warning|error|info"` on **Button, Chip and
|
|
128
|
-
Alert** — the components where `main` actually resolves. It has none today, which is precisely why
|
|
129
|
-
the gate could not catch defect 1 the first time. Adding that row is part of this WO.
|
|
130
|
-
- A chart specimen that passes a partial `grid`, to show the merge.
|
|
131
|
-
|
|
132
|
-
### Preconditions
|
|
133
|
-
|
|
134
|
-
- `THEME-1` (`2.30.0`) and `CHART-6` (`2.31.0`) landed and published.
|
|
135
|
-
|
|
136
|
-
### Parity guardrail
|
|
137
|
-
|
|
138
|
-
No behaviour, permission or data-contract change. One palette value moves deliberately and visibly;
|
|
139
|
-
everything else must render identically.
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## B. Implementation map
|
|
144
|
-
|
|
145
|
-
*Filled by the Orchestrator on `git pull` — see AGENTS.md → "Work Order".*
|
|
146
|
-
|
|
147
|
-
### Execution directive (read this first)
|
|
148
|
-
|
|
149
|
-
> **If you are the implementer reading this work order as your own specification: this section is
|
|
150
|
-
> NOT addressed to you.** It tells the Orchestrator how to invoke you. **You ARE that invocation —
|
|
151
|
-
> do NOT shell out to `codex exec`.**
|
|
152
|
-
>
|
|
153
|
-
> Implement through `codex exec` in the background — invoked directly via Bash (never the
|
|
154
|
-
> `debugger`/`*_coder` Agent wrappers) with BOTH flags `--skip-git-repo-check` and
|
|
155
|
-
> `--dangerously-bypass-approvals-and-sandbox`. **Pass the WO via stdin, not as a positional
|
|
156
|
-
> argument** — `cat work-orders/THEME-2.md | codex exec --skip-git-repo-check
|
|
157
|
-
> --dangerously-bypass-approvals-and-sandbox -` (a positional arg hits Windows' command-line length
|
|
158
|
-
> limit on a WO this size — proven on THEME-1/CHART-6). Fallback to direct Claude implementation
|
|
159
|
-
> only on Codex quota/rate-limit/non-zero exit.
|
|
160
|
-
|
|
161
|
-
### Context package
|
|
162
|
-
|
|
163
|
-
**Preconditions verified 2026-08-10:** `THEME-1` (`96992cf`) and `CHART-6` (`6dedc62`) are both
|
|
164
|
-
landed on `main` and published (`2.30.0`, `2.31.0`).
|
|
165
|
-
|
|
166
|
-
**Defect 1 — exact current state, verified in `src/theme/tokens.js:81-87`:**
|
|
167
|
-
```js
|
|
168
|
-
warning: {
|
|
169
|
-
...withMainShades('#C08A2C', '#212529'),
|
|
170
|
-
text: '#976100',
|
|
171
|
-
fill: '#C08A2C',
|
|
172
|
-
fillText: '#212529',
|
|
173
|
-
bg: '#FBF0DC',
|
|
174
|
-
},
|
|
175
|
-
```
|
|
176
|
-
`withMainShades(main, contrastText)` (defined near the top of `tokens.js`) sets `main`/`light`/`dark`/
|
|
177
|
-
`contrastText` via MUI's own `lighten`/`darken` at 0.2/0.3 tonal offsets. **Fix:** change the call to
|
|
178
|
-
`withMainShades('#976100', '#FFFFFF')` — reusing the existing `text` value as the new `main`, and
|
|
179
|
-
`'#FFFFFF'` as `contrastText` (verify this actually clears 4.5:1 — the WO states 5.216 on white
|
|
180
|
-
already for `#976100`, and `contrastText` white-on-`#976100` is the same ratio by symmetry). Leave
|
|
181
|
-
`text`/`fill`/`fillText`/`bg` untouched — `fill` stays the lighter amber for deliberate fill use
|
|
182
|
-
(THEME-1's own `MuiAlert` `standardWarning` styleOverride already reads `palette.warning.text`/`.bg`,
|
|
183
|
-
NOT `.main`, so that specimen is unaffected by this change — see the harness note below for why a
|
|
184
|
-
NEW specimen is needed to actually exercise `.main`).
|
|
185
|
-
|
|
186
|
-
**Defect 1's assertion rule — add to `src/theme/themeCompleteness.js`'s `contrastFindings(theme)`
|
|
187
|
-
function (~line 249).** Alongside the existing per-status `text`-vs-`bg` and `fillText`-vs-`fill`
|
|
188
|
-
loops, add a third: for each `status` in `STATUS_KEYS` (`['success','warning','error','info',
|
|
189
|
-
'stale']`, from `tokens.js`) that HAS a `.main` property (**`stale` does not** — it's a custom
|
|
190
|
-
augmented namespace, never passed through MUI's `createPalette`/`augmentColor`, so
|
|
191
|
-
`theme.palette.stale.main` is `undefined` — skip it, don't push a spurious finding for a channel
|
|
192
|
-
that was never supposed to have one), check `calculateContrastRatio(tokens.main, '#FFFFFF')` and
|
|
193
|
-
`calculateContrastRatio(tokens.main, theme.palette.background.default)`, both `>= 4.5`, pushing a
|
|
194
|
-
`contrast.<status>.main-on-<white|page>` finding (matching the existing naming convention,
|
|
195
|
-
`contrast.controlBorder.<state>-on-<surface>`) on failure. This is a REPORT via the existing
|
|
196
|
-
`findings` array — `assertThemeComplete` never throws or hard-fails on its own (confirm this by
|
|
197
|
-
reading the function; the "ratchet stays a report, not a hard fail for non-adopters" is structural
|
|
198
|
-
here, not a flag to add — a consuming app's OWN test suite decides whether to assert
|
|
199
|
-
`findings.length === 0`, ucm's export just returns data either way).
|
|
200
|
-
|
|
201
|
-
**Defect 2 — exact current state, verified in `src/components/charts/BarChart.jsx:26` and
|
|
202
|
-
`LineChart.jsx:43`:** `grid = { horizontal: true }` as a bare JS default parameter, then
|
|
203
|
-
`grid={grid}` passed straight through (`BarChart.jsx:65`, `LineChart.jsx:88`) — a caller-supplied
|
|
204
|
-
`grid` object REPLACES the default wholesale rather than merging per-key, unlike every sibling prop
|
|
205
|
-
in this file (compare `withAxisDefaults`'s `tickLabelStyle` merge, `withChartSlotDefaults`'s
|
|
206
|
-
`tooltip`/`legend` merge — both spread the default first, caller second, so the caller only
|
|
207
|
-
overrides the keys it actually sets). **Fix:** add a `withGridDefaults(grid)` helper to
|
|
208
|
-
`src/components/charts/chartDefaults.js` following the SAME pattern (`{ horizontal: true, ...grid }`
|
|
209
|
-
— MUI's `grid` prop type is `Pick<ChartsGridProps, 'vertical'|'horizontal'>`, plain optional
|
|
210
|
-
booleans, no special `false`/`true` shorthand at the type level, so spreading a caller's object
|
|
211
|
-
after the default is sufficient: a caller wanting no grid at all passes
|
|
212
|
-
`grid={{ horizontal: false, vertical: false }}` explicitly, which the spread correctly honours since
|
|
213
|
-
it's a later key overriding an earlier one — do not add special-casing for a literal `grid={false}`
|
|
214
|
-
unless you find MUI's actual runtime prop handling treats a boolean differently from the declared
|
|
215
|
-
type, which the WO's own phrasing ("or the documented way to switch the grid off entirely") already
|
|
216
|
-
anticipates might not be a literal `false`). Wire it into both `BarChart.jsx` and `LineChart.jsx`
|
|
217
|
-
the same way the other `chartDefaults.js` helpers are used.
|
|
218
|
-
|
|
219
|
-
**Defect 2's audit — read `src/components/charts/chartDefaults.js` in full and check each
|
|
220
|
-
object-valued prop the wrappers default or forward against the same replace-vs-merge question:**
|
|
221
|
-
- `withAxisDefaults`'s `tickLabelStyle: { fontSize: tickFontSize, ...axis.tickLabelStyle }` —
|
|
222
|
-
ALREADY merges correctly (default first, caller's own `tickLabelStyle` fields win per-key).
|
|
223
|
-
- `withChartSlotDefaults`'s `{ ...slotProps, tooltip: {...}, legend: {...} }` — the outer
|
|
224
|
-
`...slotProps` spread preserves any OTHER slot key a caller sets (e.g. `slotProps.axisHighlight`),
|
|
225
|
-
and the `tooltip`/`legend` sub-objects are themselves merged default-first. ALREADY correct.
|
|
226
|
-
- `LineChart.jsx`'s `slots={{ mark: FilledMarkElement, ...slots }}` — default first, caller's own
|
|
227
|
-
`slots` spread after, so a caller's own `slots.mark` wins and other slot keys survive. ALREADY
|
|
228
|
-
correct.
|
|
229
|
-
- `spaceForRotatedTicks`'s `margin` handling is NOT a "default object caller can partially override"
|
|
230
|
-
shape at all (it only computes `margin.bottom` when rotation is detected AND the caller hasn't set
|
|
231
|
-
one) — not the same bug class, nothing to fix there, but confirm this reading is right by re-reading
|
|
232
|
-
the function rather than trusting this summary.
|
|
233
|
-
**Verify each of these four independently rather than trusting this list — this map is a starting
|
|
234
|
-
point for the audit, not a substitute for it.** If the audit finds anything actually broken beyond
|
|
235
|
-
`grid`, fix it and say so explicitly in the PR/commit, per the WO's "fix that too and say so." If the
|
|
236
|
-
audit confirms all four are already correct, state that explicitly too — "audited and confirmed
|
|
237
|
-
correct" is a valid, expected outcome per the WO ("either... or a named list").
|
|
238
|
-
|
|
239
|
-
**Harness — why a new specimen row is required, not optional (verified 2026-08-10):** the current
|
|
240
|
-
`ThemeBaselineEntry` (`dev/entries.jsx`) has TWO status-colour specimens today, and NEITHER exercises
|
|
241
|
-
`palette.<status>.main`:
|
|
242
|
-
1. `StatusChip` (`dev/entries.jsx:71-78`) sets `sx={{ bgcolor: '${tone}.fill', color:
|
|
243
|
-
'${tone}.fillText' }}` directly — bypasses `.main` entirely by design.
|
|
244
|
-
2. `<Alert severity="warning">` etc. (`dev/entries.jsx:136-140`) — THEME-1's `MuiAlert`
|
|
245
|
-
`styleOverrides.standardWarning` (`src/theme/createAppTheme.js`'s `createPaletteAwareComponents`)
|
|
246
|
-
already overrides the STANDARD variant's `color`/`backgroundColor` to `palette.warning.text`/
|
|
247
|
-
`.bg` directly, NOT `.main` — so this existing Alert row was already immune to defect 1 and would
|
|
248
|
-
not have caught it even now.
|
|
249
|
-
Add: a row of `<Button color="success|warning|error|info" variant="contained">` (MUI's contained
|
|
250
|
-
Button reads `palette[color].main` for its background and `.contrastText` for its label — this is
|
|
251
|
-
the most direct `.main` exposure in the kit), a row of native `<Chip color="warning">` (not
|
|
252
|
-
`StatusChip` — MUI's own `color` prop on `Chip`, filled variant, also reads `.main`/
|
|
253
|
-
`.contrastText` directly), and an `<Alert severity="warning" variant="filled">` (MUI's `filled`
|
|
254
|
-
Alert variant is NOT covered by THEME-1's `standardWarning`-only override, so it still resolves
|
|
255
|
-
`.main` — confirm this by checking `createPaletteAwareComponents`'s `alertStyles` only sets
|
|
256
|
-
`standard${Status}` keys, never `filled${Status}` or `outlined${Status}`). These three together
|
|
257
|
-
are what the WO's Verification section means by "Button, Chip and Alert — the components where
|
|
258
|
-
`main` actually resolves."
|
|
259
|
-
|
|
260
|
-
**Chart specimen for the `grid` merge:** the existing "Caller overrides" `LineChart` specimen
|
|
261
|
-
(`dev/entries.jsx`, added in CHART-6) already sets `grid={{ horizontal: true, vertical: true }}` — a
|
|
262
|
-
COMPLETE object, which happens to already include `horizontal: true`, so it would not visibly
|
|
263
|
-
demonstrate the bug even pre-fix. Change it to a genuinely PARTIAL grid, e.g. `grid={{ vertical:
|
|
264
|
-
true }}` alone — pre-fix this would have shown ONLY vertical lines (losing the horizontal default);
|
|
265
|
-
post-fix it must show both. This is the specimen the WO's Verification section calls for ("A chart
|
|
266
|
-
specimen that passes a partial `grid`, to show the merge").
|
|
267
|
-
|
|
268
|
-
### Named files to change
|
|
269
|
-
|
|
270
|
-
- `src/theme/tokens.js` — the `warning` entry's `withMainShades(...)` call (line 82).
|
|
271
|
-
- `src/theme/themeCompleteness.js` — `contrastFindings` (~line 249), add the `main`-vs-white/page
|
|
272
|
-
loop, skipping any `STATUS_KEYS` entry without a `.main`.
|
|
273
|
-
- `src/components/charts/chartDefaults.js` — new `withGridDefaults` export.
|
|
274
|
-
- `src/components/charts/BarChart.jsx:26,65`, `src/components/charts/LineChart.jsx:43,88` — wire in
|
|
275
|
-
`withGridDefaults`.
|
|
276
|
-
- `dev/entries.jsx` — new Button/Chip/Alert `.main`-exercising specimen row; fix the existing
|
|
277
|
-
"Caller overrides" LineChart's `grid` prop to a genuinely partial object.
|
|
278
|
-
- `package.json` — version `2.31.0` → `2.31.1` (patch).
|
|
279
|
-
- `tests/themeCompleteness.test.js` — extend with the 2 required tests (main contrast + non-vacuity
|
|
280
|
-
proof by temporarily reverting `warning.main`; ratchet/report-not-hard-fail confirmation).
|
|
281
|
-
- `tests/chartDefaults.test.js` — extend with the 2 required tests (partial-grid merge + non-vacuity
|
|
282
|
-
proof by temporarily reverting to the bare default parameter; grid-off-via-explicit-false-object
|
|
283
|
-
still works).
|
|
284
|
-
|
|
285
|
-
### Do-not-touch / invariants
|
|
286
|
-
|
|
287
|
-
- `success`/`error`/`info`/`stale` palette values — untouched, they measure fine.
|
|
288
|
-
- `warning.fill`/`.text`/`.bg` — untouched.
|
|
289
|
-
- The committed reference-sheet HTML artifact (`work-orders/assets/THEME-1-baseline-reference-sheet.html`)
|
|
290
|
-
— frozen spec, never depicted `warning.main` as a foreground, not touched by this WO.
|
|
291
|
-
- Anything in CHART-6's scope beyond the `grid` merge and the audit — no new chart-chrome feature
|
|
292
|
-
work here.
|
|
293
|
-
- No behaviour, permission, or data-contract change.
|
|
294
|
-
|
|
295
|
-
### Pitfalls (verified against landed code 2026-08-10)
|
|
296
|
-
|
|
297
|
-
- `withMainShades` is defined once near the top of `tokens.js` and used for
|
|
298
|
-
`success`/`warning`/`error`/`info` — changing ONLY the `warning` call site, not the helper itself
|
|
299
|
-
(the helper's `lighten`/`darken` derivation logic is correct and unrelated to this bug).
|
|
300
|
-
- `STATUS_KEYS` includes `'stale'`, which has no MUI-augmented `.main` — a naive loop over all
|
|
301
|
-
`STATUS_KEYS` reading `tokens.main` will hit `undefined` for `stale`; guard it (`if (!tokens?.main)
|
|
302
|
-
continue`, matching the existing loop's `if (!tokens) continue` pattern one function up).
|
|
303
|
-
- Don't confuse this WO's `contrastFindings` addition with `THEME_COMPLETENESS_SURFACES`'s existing
|
|
304
|
-
`STATUS_SURFACES` (`text`/`fill`/`fillText`/`bg` presence-vs-default check) — the new rule is a
|
|
305
|
-
CONTRAST check (numeric ratio), same family as the existing `contrast.<status>.text-on-bg` /
|
|
306
|
-
`contrast.controlBorder.*` findings, not a "surface is deliberately defined" presence check.
|
|
307
|
-
|
|
308
|
-
### Target repo working directory (absolute)
|
|
309
|
-
|
|
310
|
-
`C:\Users\biglmi\Documents\webapps\ui-core-micha`
|
|
311
|
-
|
|
312
|
-
### Required tests to WRITE (Codex writes them; the Orchestrator runs them)
|
|
313
|
-
|
|
314
|
-
Exactly the 4 tests enumerated in Envelope § "Required tests to WRITE" above, extending
|
|
315
|
-
`tests/themeCompleteness.test.js` and `tests/chartDefaults.test.js` (no new files), plus
|
|
316
|
-
`tsc -p tsconfig.build.json --noEmit` clean. Do not add more, do not run the full suite. Affected-areas
|
|
317
|
-
set is exactly those two files.
|
|
318
|
-
|
|
319
|
-
### Preamble (append verbatim)
|
|
320
|
-
|
|
321
|
-
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there
|
|
322
|
-
> is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the
|
|
323
|
-
> app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI
|
|
324
|
-
> unless the spec says so; do not update `MEMORY.md`. Do NOT `git add`/`commit`/`push` — leave every
|
|
325
|
-
> change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests
|
|
326
|
-
> the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute
|
|
327
|
-
> and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review).
|
|
328
|
-
> The orchestrator re-runs the authoritative set + does the independent review after you finish —
|
|
329
|
-
> those are the gate; your own run does not count as the gate.
|
|
330
|
-
>
|
|
331
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
|
|
332
|
-
> `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
|
|
333
|
-
> completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
|
|
334
|
-
> `RESULT: DONE|BLOCKED <reason>`.
|
|
335
|
-
|
|
336
|
-
### Mini-handover
|
|
337
|
-
|
|
338
|
-
Repo: `ui-core-micha` (`C:\Users\biglmi\Documents\webapps\ui-core-micha`), branch `main`. WO:
|
|
339
|
-
`work-orders/THEME-2.md`. Follow `orchestrate-codex`.
|
package/work-orders/THEME-3.md
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
# THEME-3 — Add the missing "subtle surface" baseline token
|
|
2
|
-
|
|
3
|
-
**Target repo:** `ui-core-micha` (branch `main` — this repo has no `develop`; a push touching
|
|
4
|
-
`src/**`/`package.json` publishes to npm immediately via `publish.yml`)
|
|
5
|
-
**Tier:** 3 — shared-core theme baseline, consumed by every `createAppTheme` adopter.
|
|
6
|
-
**Review:** independent `reviewer` **and** `ui_reviewer`, concurrently, both mandatory before commit
|
|
7
|
-
(no staging net in this repo — the independent review is the only gate and is not back-fillable).
|
|
8
|
-
**Found by:** `cockpit/UI-6` (adopting `createAppTheme` with the frozen `UI-4` token table). The
|
|
9
|
-
sheet's canonical token table (section 8, "what cockpit stops owning") lists an *inset surface*
|
|
10
|
-
`#F4F5F6` as a baseline-supplied value, replacing `cockpit.surface2` (16 of 195 token reads in that
|
|
11
|
-
WO). It does not exist anywhere in the shipped package — confirmed by grepping
|
|
12
|
-
`src/theme/tokens.js`/`themeCompleteness.js` for the hex and for any "surface"/"inset" key. The value
|
|
13
|
-
was one of the design-language instrument's *own* internal comparison-stack entries
|
|
14
|
-
(`cockpit/work-orders/assets/UI-4-design-language.html:681`), never actually wired into
|
|
15
|
-
`createAppTheme`. Per this estate's own rule ("a gap in the shared kit discovered mid-adoption is a
|
|
16
|
-
`ui-core-micha` work order and cockpit's item waits — not a local workaround"), `UI-6` is blocked on
|
|
17
|
-
this landing and publishing first.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## A. Envelope
|
|
22
|
-
|
|
23
|
-
### Goal
|
|
24
|
-
|
|
25
|
-
Add a third baseline background tier — `palette.background.subtle` — to `createAppTheme`'s shared
|
|
26
|
-
palette, for panels/table stripes/excerpt boxes that need to read as slightly recessed from
|
|
27
|
-
`background.paper` without a bespoke per-app colour. Register it in the completeness-assertion
|
|
28
|
-
surface inventory so every adopter (present and future) gets the same guarantee the other baseline
|
|
29
|
-
surfaces already have.
|
|
30
|
-
|
|
31
|
-
### Scope
|
|
32
|
-
|
|
33
|
-
1. **`src/theme/tokens.js`** — add `background.subtle: '#F4F5F6'` to `BASELINE_PALETTE.background`
|
|
34
|
-
(alongside the existing `default`/`paper`). This is a **fixed baseline constant**, not
|
|
35
|
-
accent-derived — the same treatment as `default`/`paper`, not the accent-tint derivation used for
|
|
36
|
-
`cockpit.accentTint`.
|
|
37
|
-
2. **`src/theme/themeCompleteness.js`** — add `pathSurface('palette.background.subtle')` to
|
|
38
|
-
`THEME_COMPLETENESS_SURFACES`.
|
|
39
|
-
3. **Recompute the contrast claim independently** — the frozen sheet's "muted ink on it: 4.81" was
|
|
40
|
-
computed on the sheet's own static comparison canvas, not via this package's
|
|
41
|
-
`calculateContrastRatio`. Recompute `calculateContrastRatio('#5B6670', '#F4F5F6')` (baseline
|
|
42
|
-
`ink.secondary`, the tone most likely to sit on this surface) directly against the shipped
|
|
43
|
-
function before treating the sheet's number as confirmed.
|
|
44
|
-
4. Publish (version bump — see Risks for the semver call).
|
|
45
|
-
|
|
46
|
-
### Non-goals / do not touch
|
|
47
|
-
|
|
48
|
-
- Renaming or removing any existing palette token.
|
|
49
|
-
- `CHART-*`/`SHELL-*`/`AUTH-*` surfaces — unrelated to this addition.
|
|
50
|
-
- `fitness-monitor` or any other consuming app's own repo — this WO lands and publishes the token
|
|
51
|
-
only; `cockpit/UI-6` consumes it afterward, in its own repo, as a separate step.
|
|
52
|
-
- Any accent-derived tint/shade math — this token is a fixed baseline value, structurally unlike
|
|
53
|
-
`cockpit.accentTint`/`accentLight`/`accentDark`.
|
|
54
|
-
|
|
55
|
-
### Risks
|
|
56
|
-
|
|
57
|
-
- **`fitness-monitor` is a real, already-shipped adopter** (`frontend/src/theme.js` +
|
|
58
|
-
`frontend/src/theme.test.js`) that hard-asserts `assertThemeComplete(theme).findings` equals `[]`.
|
|
59
|
-
A new *required* completeness surface must resolve automatically for every adopter with zero
|
|
60
|
-
app-level action — the same guarantee `background.default`/`background.paper` already give,
|
|
61
|
-
**not** an opt-in the app must declare. Concretely: the new key must come from
|
|
62
|
-
`BASELINE_PALETTE` so every real `createAppTheme(...)` output has it defined, and MUI's own
|
|
63
|
-
default theme must never define `background.subtle` itself (a novel key — verify this, don't
|
|
64
|
-
assume it), so `descriptor.get(MUI_DEFAULT_THEME)` returns `undefined` and the "still equals MUI's
|
|
65
|
-
untouched default" branch never fires. If either assumption is wrong, `fitness-monitor`'s CI
|
|
66
|
-
breaks on its next pin bump and this WO must not ship that way.
|
|
67
|
-
- **Semver classification** — additive to the factory's *output* (no adopter passes anything new to
|
|
68
|
-
get it), which argues for a patch, mirroring `SHELL-4`'s "narrows the contract, cannot turn
|
|
69
|
-
cockpit red" precedent in the opposite direction (widens the contract, but resolves automatically,
|
|
70
|
-
so it also cannot turn an adopter red). Confirm no adopter needs a code change before treating
|
|
71
|
-
this as settled rather than asserting it.
|
|
72
|
-
- **Do not silently rename cockpit's `surface2` in this repo** — this WO adds the baseline token;
|
|
73
|
-
cockpit's own re-point of 16 call sites from `cockpit.surface2` to the new baseline token is
|
|
74
|
-
`UI-6`'s job, in cockpit's repo, not this one's.
|
|
75
|
-
|
|
76
|
-
### Required tests to WRITE
|
|
77
|
-
|
|
78
|
-
1. `assertThemeComplete` stays empty-findings for a minimal adopter call —
|
|
79
|
-
`createAppTheme({ palette: { primary: { main: '#0F62FE' } } })` (mirroring `fitness-monitor`'s
|
|
80
|
-
real usage) — proving the new surface resolves with zero adopter action, not just for a theme
|
|
81
|
-
that happens to declare it.
|
|
82
|
-
2. `theme.palette.background.subtle` equals `'#F4F5F6'` on an unconfigured `createAppTheme(...)`
|
|
83
|
-
call.
|
|
84
|
-
3. `calculateContrastRatio('#5B6670', '#F4F5F6')` (baseline `ink.secondary` on the new surface)
|
|
85
|
-
passes AA (≥ 4.5:1) — computed via the shipped function, not asserted from the sheet's number.
|
|
86
|
-
4. Existing `tests/createAppTheme.test.js` and `tests/themeCompleteness.test.js` stay green
|
|
87
|
-
unmodified in intent (only extended where the new surface must appear in an enumeration they
|
|
88
|
-
already assert against, e.g. a surface-count or key-list check if one exists).
|
|
89
|
-
|
|
90
|
-
### Verification
|
|
91
|
-
|
|
92
|
-
No visual/prototype gate — this is a token-level palette addition with no rendered specimen of its
|
|
93
|
-
own in this repo. The rendered check for what this token actually looks like on real cockpit
|
|
94
|
-
surfaces happens downstream, in `cockpit/UI-6`'s own two-width verification.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## B. Implementation map
|
|
99
|
-
|
|
100
|
-
*Filled by the Orchestrator on `git pull` — see `AGENTS.md` → "Work Order".*
|
|
101
|
-
|
|
102
|
-
### Context package
|
|
103
|
-
|
|
104
|
-
- **`src/theme/tokens.js`** — `BASELINE_PALETTE.background` currently reads:
|
|
105
|
-
```js
|
|
106
|
-
background: {
|
|
107
|
-
default: '#FAFAFA',
|
|
108
|
-
paper: '#FFFFFF',
|
|
109
|
-
},
|
|
110
|
-
```
|
|
111
|
-
Add `subtle: '#F4F5F6'` as a third key. This is the ONLY change needed in this file for the new
|
|
112
|
-
value itself — do not touch `SERIES_COLOURS`, `STATUS_KEYS`, `BASELINE_STATIC`, or the exemptions
|
|
113
|
-
list.
|
|
114
|
-
- **`src/theme/themeCompleteness.js`** — `THEME_COMPLETENESS_SURFACES` (around line 155-192) already
|
|
115
|
-
has `pathSurface('palette.background.default')` and `pathSurface('palette.background.paper')` in
|
|
116
|
-
its list. Add `pathSurface('palette.background.subtle')` immediately next to them — same helper,
|
|
117
|
-
same pattern, no new machinery needed.
|
|
118
|
-
- **Why this can't collide with an existing adopter (verified, not assumed):** `MUI_DEFAULT_THEME =
|
|
119
|
-
createTheme()` (line 5 of `themeCompleteness.js`) is vanilla MUI with no `background.subtle` key —
|
|
120
|
-
MUI's own palette only ever defines `background.default`/`.paper`. So for every real
|
|
121
|
-
`createAppTheme(...)` output, `descriptor.get(theme)` resolves to `'#F4F5F6'` (defined) while
|
|
122
|
-
`descriptor.get(MUI_DEFAULT_THEME)` resolves to `undefined` — the `sameValue` check in
|
|
123
|
-
`assertThemeComplete` (around line 354) therefore never flags it, with no exemption required. This
|
|
124
|
-
is exactly why `background.default` needs no exemption today; `background.subtle` gets the same
|
|
125
|
-
treatment. `background.paper` is the one that DOES need an exemption, because MUI's own default
|
|
126
|
-
theme also happens to be white — do not copy that exemption pattern here, it does not apply.
|
|
127
|
-
- **`calculateContrastRatio` is already exported** from `src/theme/themeCompleteness.js` and
|
|
128
|
-
re-exported from `src/theme/index.js` — use it directly for the required contrast test, do not
|
|
129
|
-
reimplement contrast math.
|
|
130
|
-
- **Test file conventions** (read `tests/themeCompleteness.test.js` and
|
|
131
|
-
`tests/createAppTheme.test.js` for the existing style before writing new assertions — minimal
|
|
132
|
-
`createAppTheme({ palette: { primary: { main: '#0F62FE' } } })` is the repo's own established
|
|
133
|
-
"minimal adopter" fixture, already used in both files; reuse it rather than inventing a new one).
|
|
134
|
-
- Directive: work from this package; do not explore broadly from scratch; open only the two named
|
|
135
|
-
source files plus the two named test files to verify. If you must dig deeper, delegate to a
|
|
136
|
-
read-only Explore sub-agent (Haiku).
|
|
137
|
-
|
|
138
|
-
### Target repo working directory (absolute)
|
|
139
|
-
|
|
140
|
-
`C:\Users\biglmi\Documents\webapps\ui-core-micha`
|
|
141
|
-
|
|
142
|
-
### Preamble
|
|
143
|
-
|
|
144
|
-
> The text of this whole file is the COMPLETE spec — not a plan to refine; there is no separate plan
|
|
145
|
-
> file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and this repo's
|
|
146
|
-
> own `DESIGN.md`/conventions ONLY for conventions. Stay in scope; do not touch
|
|
147
|
-
> `CHART-*`/`SHELL-*`/`AUTH-*` surfaces or any file outside `src/theme/` and `tests/` unless this
|
|
148
|
-
> spec says so; do not update any `MEMORY.md`. Do NOT `git add` / `commit` / `push` — leave every
|
|
149
|
-
> change uncommitted in the working tree for the orchestrator's independent review; do NOT bump
|
|
150
|
-
> `package.json`'s version yourself — the Orchestrator decides and applies the semver bump after
|
|
151
|
-
> review, per the Risks section's still-open patch/minor question. WRITE the tests the "Required
|
|
152
|
-
> tests to WRITE" section calls for AND **RUN the tests you just wrote** (plus the two named existing
|
|
153
|
-
> spec files, to confirm no regression) to confirm they execute and pass — that is the ONLY test run
|
|
154
|
-
> you do (NOT this repo's full suite, NOT any review). The orchestrator re-runs the authoritative set
|
|
155
|
-
> + does the independent review after you finish — those are the gate; your own run does not count
|
|
156
|
-
> as the gate.
|
|
157
|
-
>
|
|
158
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
|
|
159
|
-
> `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
|
|
160
|
-
> completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
|
|
161
|
-
> `RESULT: DONE|BLOCKED <reason>`.
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
|
|
166
|
-
|
|
167
|
-
> **If you are the implementer reading this work order as your own specification: STOP at this line.
|
|
168
|
-
> Everything below describes what the Orchestrator does AFTER you finish. You do none of it — no
|
|
169
|
-
> reviewers, no verification run, no register edit, no commit.** You ARE the invocation described
|
|
170
|
-
> below; do NOT shell out to `codex exec`.
|
|
171
|
-
|
|
172
|
-
### Execution directive
|
|
173
|
-
|
|
174
|
-
Implement through `codex exec` in the background — invoked directly via Bash (never the
|
|
175
|
-
`debugger`/`*_coder` Agent wrappers) with BOTH flags `--skip-git-repo-check` and
|
|
176
|
-
`--dangerously-bypass-approvals-and-sandbox`. **Pass the work order via stdin, not as a positional
|
|
177
|
-
argument** (this repo's own `THEME-1` row already documents the Windows command-line length limit
|
|
178
|
-
hitting this via the npm shim). Fallback to direct Claude implementation only on Codex
|
|
179
|
-
quota/rate-limit/non-zero exit — the fallback flips authorship, so both reviewers stay mandatory
|
|
180
|
-
either way.
|
|
181
|
-
|
|
182
|
-
### Review routing
|
|
183
|
-
|
|
184
|
-
Tier 3: `reviewer` (Sonnet) + `ui_reviewer` (Sonnet), concurrent, same background batch, before
|
|
185
|
-
commit. No `sec_reviewer` — no auth/security surface in scope. `ui_reviewer`'s job here is narrow
|
|
186
|
-
(no rendered surface to review) — focus it on the completeness-contract and adopter-safety question
|
|
187
|
-
rather than visual design.
|
|
188
|
-
|
|
189
|
-
### Verification
|
|
190
|
-
|
|
191
|
-
No rendered two-width check — token-only change with no specimen in this repo (per the Envelope).
|
|
192
|
-
The authoritative check is: the two new/extended test files pass, `tests/createAppTheme.test.js` +
|
|
193
|
-
`tests/themeCompleteness.test.js` stay green, and a direct read of `fitness-monitor`'s
|
|
194
|
-
`frontend/src/theme.test.js` assertion confirms it would still pass unmodified against the new
|
|
195
|
-
package version (do not just reason about it — actually run `fitness-monitor`'s own scoped theme
|
|
196
|
-
test against the locally-built `ui-core-micha` if practical, or explain why not).
|
|
197
|
-
|
|
198
|
-
### Register + commit
|
|
199
|
-
|
|
200
|
-
Decide and apply the semver bump (patch, per the Risks section's reasoning, unless the
|
|
201
|
-
implementation reveals an adopter needs a code change — then escalate to minor and say why). Update
|
|
202
|
-
the `WORK_ORDERS.md` THEME-3 row to `done` with the named review verdicts and version, then commit +
|
|
203
|
-
push to `main` on green (this push publishes to npm — confirm everything is green first, there is no
|
|
204
|
-
staging net here).
|
|
205
|
-
|
|
206
|
-
### Mini-handover
|
|
207
|
-
|
|
208
|
-
Repo: `ui-core-micha` (`C:\Users\biglmi\Documents\webapps\ui-core-micha`), branch `main`.
|
|
209
|
-
WO: `work-orders/THEME-3.md`. **Ready to run** — no preconditions, small well-bounded addition.
|
|
210
|
-
Follow `orchestrate-codex`.
|