@micha.bigler/ui-core-micha 3.14.3 → 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.
Files changed (367) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +7 -0
  3. package/dist/auth/UserMenu.js +1 -1
  4. package/dist/auth/apiClient.js +7 -6
  5. package/dist/chat/ChatList.js +1 -1
  6. package/dist/chat/ChatThread.js +2 -1
  7. package/dist/chat/ChatWorkspace.js +1 -1
  8. package/dist/chat/ModelPicker.js +2 -5
  9. package/dist/chat/kitSxRegistry.js +9 -0
  10. package/dist/chat/useChatSocket.js +1 -1
  11. package/dist/components/LoginForm.js +1 -1
  12. package/dist/components/SecurityComponent.js +1 -1
  13. package/dist/components/UserListComponent.js +2 -8
  14. package/dist/components/charts/ChartFrame.js +1 -1
  15. package/dist/components/charts/ScatterChart.js +2 -1
  16. package/dist/components/charts/kitSxRegistry.js +6 -0
  17. package/dist/entries/charts.js +6 -0
  18. package/dist/entries/chat.js +8 -0
  19. package/dist/entries/markdown.js +1 -0
  20. package/dist/index.js +0 -14
  21. package/dist/layout/SectionNav.js +1 -1
  22. package/dist/messaging/AttachmentList.js +2 -2
  23. package/dist/messaging/Composer.js +2 -1
  24. package/dist/messaging/ConversationLaunchers.js +1 -4
  25. package/dist/messaging/ConversationList.js +1 -1
  26. package/dist/messaging/DirectMessageLauncher.js +1 -1
  27. package/dist/messaging/MessagingProvider.js +0 -0
  28. package/dist/messaging/PollCard.js +7 -5
  29. package/dist/messaging/ReadTicks.js +2 -2
  30. package/dist/messaging/Thread.js +5 -3
  31. package/dist/notifications/NotificationBell.js +4 -7
  32. package/dist/notifications/NotificationSettings.js +1 -1
  33. package/dist/onboarding/OnboardingProvider.js +3 -6
  34. package/dist/pages/AccountPage.js +1 -2
  35. package/dist/pages/LoginPage.js +2 -3
  36. package/dist/pages/PasswordChangePage.js +2 -3
  37. package/dist/pages/PasswordInvitePage.js +2 -3
  38. package/dist/pages/PasswordResetRequestPage.js +2 -3
  39. package/dist/pages/SignUpPage.js +2 -3
  40. package/dist/pages/SignupConfirmPage.js +2 -3
  41. package/dist/theme/createAppTheme.js +5 -4
  42. package/dist/theme/kitSxEntry.js +11 -0
  43. package/dist/theme/kitSxRegistry.js +2 -15
  44. package/dist/theme/themeCompleteness.js +3 -12
  45. package/dist/utils/auth-errors.js +4 -3
  46. package/package.json +41 -16
  47. package/.github/workflows/publish.yml +0 -126
  48. package/DESIGN.md +0 -60
  49. package/WORK_ORDERS.md +0 -148
  50. package/dev/entries.jsx +0 -721
  51. package/dev/fixtures.js +0 -26
  52. package/dev/main.jsx +0 -75
  53. package/dev/mockTransport.jsx +0 -128
  54. package/docs/CHART-LAYOUT.md +0 -157
  55. package/docs/DARK-TOKENS.md +0 -140
  56. package/docs/TYPE-SCALE.md +0 -111
  57. package/docs/messaging-deviations.md +0 -118
  58. package/index.html +0 -12
  59. package/renovate.json +0 -10
  60. package/scripts/chart-api-census.mjs +0 -415
  61. package/src/auth/AuthContext.jsx +0 -158
  62. package/src/auth/ReauthModal.jsx +0 -82
  63. package/src/auth/UserMenu.jsx +0 -121
  64. package/src/auth/apiClient.jsx +0 -232
  65. package/src/auth/authApi.jsx +0 -539
  66. package/src/auth/authConfig.jsx +0 -34
  67. package/src/auth/reauth.js +0 -47
  68. package/src/chat/ChatComposer.jsx +0 -36
  69. package/src/chat/ChatList.jsx +0 -87
  70. package/src/chat/ChatThread.jsx +0 -128
  71. package/src/chat/ChatWorkspace.jsx +0 -244
  72. package/src/chat/MarkdownReply.jsx +0 -22
  73. package/src/chat/ModelPicker.jsx +0 -85
  74. package/src/chat/api.js +0 -18
  75. package/src/chat/useChatSocket.js +0 -32
  76. package/src/chat/wire.js +0 -7
  77. package/src/components/AccessCodeManager.jsx +0 -288
  78. package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
  79. package/src/components/AllowedEmailDomainsManager.jsx +0 -92
  80. package/src/components/AuthFactorRequirementCard.jsx +0 -95
  81. package/src/components/BulkInviteCsvTab.jsx +0 -198
  82. package/src/components/EmptyState.jsx +0 -38
  83. package/src/components/LoginForm.jsx +0 -159
  84. package/src/components/MFAComponent.jsx +0 -350
  85. package/src/components/MfaLoginComponent.jsx +0 -252
  86. package/src/components/MobileBottomNav.jsx +0 -82
  87. package/src/components/PasskeysComponent.jsx +0 -252
  88. package/src/components/PasswordChangeForm.jsx +0 -87
  89. package/src/components/PasswordResetRequestForm.jsx +0 -43
  90. package/src/components/PasswordSetForm.jsx +0 -97
  91. package/src/components/ProfileComponent.jsx +0 -348
  92. package/src/components/QrSignupManager.jsx +0 -404
  93. package/src/components/QrSignupValidityManager.jsx +0 -106
  94. package/src/components/RegistrationMethodsManager.jsx +0 -150
  95. package/src/components/SecurityComponent.jsx +0 -141
  96. package/src/components/SocialLoginButtons.jsx +0 -83
  97. package/src/components/SoftChip.jsx +0 -93
  98. package/src/components/StatTile.jsx +0 -39
  99. package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
  100. package/src/components/TurnstileWidget.jsx +0 -99
  101. package/src/components/UserInviteComponent.jsx +0 -76
  102. package/src/components/UserListComponent.jsx +0 -618
  103. package/src/components/charts/BarChart.jsx +0 -102
  104. package/src/components/charts/ChartFrame.jsx +0 -214
  105. package/src/components/charts/LineChart.jsx +0 -126
  106. package/src/components/charts/ScatterChart.jsx +0 -299
  107. package/src/components/charts/TimeSeriesChart.jsx +0 -300
  108. package/src/components/charts/chartDefaults.js +0 -644
  109. package/src/components/charts/chartLabels.js +0 -36
  110. package/src/components/charts/exportChart.js +0 -258
  111. package/src/components/charts/formatters.js +0 -39
  112. package/src/components/charts/palette.js +0 -33
  113. package/src/components/charts/yearTickInterval.js +0 -7
  114. package/src/i18n/authTranslations.ts +0 -2651
  115. package/src/i18n/chartsTranslations.ts +0 -91
  116. package/src/i18n/chatTranslations.ts +0 -55
  117. package/src/i18n/messagingTranslations.ts +0 -120
  118. package/src/i18n/notificationsTranslations.ts +0 -32
  119. package/src/i18n/onboardingTranslations.ts +0 -29
  120. package/src/i18n/sectionNavTranslations.ts +0 -20
  121. package/src/i18n/uiCoreTranslations.js +0 -29
  122. package/src/i18n/userMenuTranslations.ts +0 -5
  123. package/src/index.js +0 -158
  124. package/src/layout/PageLayout.jsx +0 -36
  125. package/src/layout/SectionNav.jsx +0 -320
  126. package/src/messaging/AttachmentList.jsx +0 -145
  127. package/src/messaging/Composer.jsx +0 -197
  128. package/src/messaging/ConversationLaunchers.jsx +0 -51
  129. package/src/messaging/ConversationList.jsx +0 -109
  130. package/src/messaging/DirectMessageLauncher.jsx +0 -112
  131. package/src/messaging/MessageBubble.jsx +0 -183
  132. package/src/messaging/MessagingProvider.jsx +0 -0
  133. package/src/messaging/MessagingScopeConfig.jsx +0 -24
  134. package/src/messaging/PollCard.jsx +0 -163
  135. package/src/messaging/ReactionBar.jsx +0 -43
  136. package/src/messaging/ReadTicks.jsx +0 -82
  137. package/src/messaging/Thread.jsx +0 -195
  138. package/src/messaging/api.js +0 -48
  139. package/src/messaging/composerImageCompression.js +0 -35
  140. package/src/messaging/linkifyText.jsx +0 -37
  141. package/src/notifications/NotificationBell.jsx +0 -84
  142. package/src/notifications/NotificationSettings.jsx +0 -330
  143. package/src/notifications/NotificationsProvider.jsx +0 -224
  144. package/src/notifications/PopupSurface.jsx +0 -105
  145. package/src/notifications/api.js +0 -55
  146. package/src/notifications/feedApi.js +0 -18
  147. package/src/notifications/realtime.jsx +0 -138
  148. package/src/notifications/serviceWorker/sw.js +0 -50
  149. package/src/onboarding/OnboardingProvider.jsx +0 -326
  150. package/src/onboarding/OnboardingWizard.jsx +0 -61
  151. package/src/onboarding/WizardDialogShell.jsx +0 -51
  152. package/src/onboarding/api.js +0 -13
  153. package/src/onboarding/stepSelection.js +0 -16
  154. package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
  155. package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
  156. package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
  157. package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
  158. package/src/pages/AccountPage.jsx +0 -394
  159. package/src/pages/LoginPage.jsx +0 -343
  160. package/src/pages/PasswordChangePage.jsx +0 -62
  161. package/src/pages/PasswordInvitePage.jsx +0 -177
  162. package/src/pages/PasswordResetRequestPage.jsx +0 -68
  163. package/src/pages/SignUpPage.jsx +0 -268
  164. package/src/pages/SignupConfirmPage.jsx +0 -155
  165. package/src/testing/checkKitIntegration.js +0 -233
  166. package/src/theme/createAppTheme.js +0 -423
  167. package/src/theme/fonts.js +0 -3
  168. package/src/theme/index.js +0 -21
  169. package/src/theme/kitSxRegistry.js +0 -285
  170. package/src/theme/themeCompleteness.js +0 -1045
  171. package/src/theme/tokens.js +0 -478
  172. package/src/utils/auth-errors.js +0 -76
  173. package/src/utils/authService.js +0 -223
  174. package/src/utils/resolveErrorText.js +0 -28
  175. package/src/utils/webauthn.js +0 -51
  176. package/tests/AccountPage.profileStatements.test.jsx +0 -162
  177. package/tests/AccountPage.test.jsx +0 -200
  178. package/tests/AuthContext.test.jsx +0 -129
  179. package/tests/BarChart.test.jsx +0 -112
  180. package/tests/BrowserPushStep.test.jsx +0 -110
  181. package/tests/ChartFrame.test.jsx +0 -336
  182. package/tests/ConversationList.test.jsx +0 -144
  183. package/tests/CookieConsentStep.test.jsx +0 -69
  184. package/tests/EmptyState.test.jsx +0 -62
  185. package/tests/LineChart.test.jsx +0 -80
  186. package/tests/MessagingProvider.test.jsx +0 -50
  187. package/tests/MobileBottomNav.test.jsx +0 -319
  188. package/tests/NotificationBell.test.jsx +0 -60
  189. package/tests/NotificationSettings.test.jsx +0 -276
  190. package/tests/NotificationsProvider.test.jsx +0 -240
  191. package/tests/OnboardingProvider.test.jsx +0 -294
  192. package/tests/OnboardingWizard.test.jsx +0 -143
  193. package/tests/PasswordChangeForm.test.jsx +0 -70
  194. package/tests/PasswordInvitePage.test.jsx +0 -142
  195. package/tests/PasswordSetForm.test.jsx +0 -70
  196. package/tests/PopupSurface.test.jsx +0 -142
  197. package/tests/ProfileComponent.refresh.test.jsx +0 -194
  198. package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
  199. package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
  200. package/tests/ScatterChart.test.jsx +0 -270
  201. package/tests/SectionNav.test.jsx +0 -363
  202. package/tests/SignUpPage.test.jsx +0 -208
  203. package/tests/SoftChip.test.jsx +0 -105
  204. package/tests/StatTile.test.jsx +0 -57
  205. package/tests/Thread.test.jsx +0 -151
  206. package/tests/TimeSeriesChart.test.jsx +0 -367
  207. package/tests/UserListComponent.test.jsx +0 -192
  208. package/tests/UserMenu.test.jsx +0 -171
  209. package/tests/apiClientLanguage.test.js +0 -33
  210. package/tests/apiClientPublicPaths.test.js +0 -178
  211. package/tests/authApiLogin.test.js +0 -42
  212. package/tests/authApiRegistration.test.js +0 -31
  213. package/tests/authErrorCodeRendering.test.jsx +0 -77
  214. package/tests/authErrors.test.js +0 -74
  215. package/tests/authTranslations.test.js +0 -74
  216. package/tests/chart-api-census.test.js +0 -366
  217. package/tests/chartAxisTickBand.test.jsx +0 -95
  218. package/tests/chartDefaults.test.js +0 -902
  219. package/tests/chartLabels.test.js +0 -50
  220. package/tests/chartsPalette.test.js +0 -99
  221. package/tests/chatApi.test.js +0 -48
  222. package/tests/chatDriverNames.test.jsx +0 -71
  223. package/tests/chatExports.test.js +0 -3
  224. package/tests/chatList.test.jsx +0 -84
  225. package/tests/chatPicker.test.jsx +0 -82
  226. package/tests/chatSocket.test.jsx +0 -26
  227. package/tests/chatThread.test.jsx +0 -116
  228. package/tests/chatTranslations.test.js +0 -47
  229. package/tests/chatWorkspace.test.jsx +0 -234
  230. package/tests/checkKitIntegration.test.jsx +0 -219
  231. package/tests/createAppTheme.test.js +0 -132
  232. package/tests/createAppThemeDark.test.js +0 -127
  233. package/tests/createAppThemeLightGuard.test.js +0 -40
  234. package/tests/createAppThemePageContrast.test.js +0 -108
  235. package/tests/createAppThemeTypography.test.js +0 -53
  236. package/tests/errorCallSiteGuard.test.js +0 -32
  237. package/tests/exportChart.test.js +0 -313
  238. package/tests/feedApi.test.js +0 -46
  239. package/tests/fixtures/light-theme-baseline.json +0 -2234
  240. package/tests/i18nAggregate.test.js +0 -120
  241. package/tests/i18nGermanVariant.test.js +0 -65
  242. package/tests/loginPageErrorResolution.test.jsx +0 -102
  243. package/tests/messagingApi.test.js +0 -32
  244. package/tests/messagingChunk6.test.jsx +0 -116
  245. package/tests/messagingCompactBubble.test.jsx +0 -64
  246. package/tests/messagingComposer.test.jsx +0 -136
  247. package/tests/messagingComposerChunk5.test.jsx +0 -113
  248. package/tests/messagingContractConformance.test.js +0 -69
  249. package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
  250. package/tests/messagingExports.test.js +0 -21
  251. package/tests/messagingInteractions.test.jsx +0 -136
  252. package/tests/messagingLastMessagePreview.test.jsx +0 -93
  253. package/tests/messagingLinkify.test.jsx +0 -51
  254. package/tests/messagingMessageActions.test.jsx +0 -163
  255. package/tests/messagingMsg6.test.jsx +0 -105
  256. package/tests/messagingMsg6f.test.jsx +0 -155
  257. package/tests/messagingMsg6g.test.jsx +0 -166
  258. package/tests/messagingMsg6h.test.jsx +0 -136
  259. package/tests/messagingMsg6i.test.jsx +0 -129
  260. package/tests/messagingPollRendering.test.jsx +0 -142
  261. package/tests/messagingReactionMerge.test.jsx +0 -77
  262. package/tests/messagingReadTicksTooltip.test.jsx +0 -36
  263. package/tests/messagingThreadReceipts.test.jsx +0 -178
  264. package/tests/messagingThreadingQuoting.test.jsx +0 -87
  265. package/tests/messagingUnreadLifecycle.test.jsx +0 -78
  266. package/tests/notificationsApi.test.js +0 -41
  267. package/tests/notificationsExports.test.js +0 -34
  268. package/tests/onboardingDescriptors.test.js +0 -132
  269. package/tests/packageTreeShaking.test.js +0 -126
  270. package/tests/realtime.test.jsx +0 -219
  271. package/tests/resolveErrorText.test.js +0 -72
  272. package/tests/stepSelection.test.js +0 -53
  273. package/tests/themeCompleteness.test.js +0 -626
  274. package/tests/timeSeriesLegend.test.js +0 -99
  275. package/tests/userScreenTranslations.test.jsx +0 -218
  276. package/tsconfig.build.json +0 -18
  277. package/vite.config.mjs +0 -6
  278. package/work-orders/AUTH-1.md +0 -74
  279. package/work-orders/AUTH-2.md +0 -74
  280. package/work-orders/AUTH-4.md +0 -183
  281. package/work-orders/AUTH-5.md +0 -154
  282. package/work-orders/AUTH-7.md +0 -181
  283. package/work-orders/AUTH-8.md +0 -184
  284. package/work-orders/CHART-1.md +0 -285
  285. package/work-orders/CHART-2.md +0 -222
  286. package/work-orders/CHART-3.md +0 -163
  287. package/work-orders/CHART-4.md +0 -203
  288. package/work-orders/CHART-5.md +0 -226
  289. package/work-orders/CHART-6.md +0 -428
  290. package/work-orders/CHART-7.md +0 -175
  291. package/work-orders/DX-1.md +0 -169
  292. package/work-orders/DX-2.md +0 -188
  293. package/work-orders/DX-3.md +0 -195
  294. package/work-orders/I18N-1.md +0 -254
  295. package/work-orders/I18N-3.md +0 -207
  296. package/work-orders/MSG-3.md +0 -375
  297. package/work-orders/MSG-3b.md +0 -1002
  298. package/work-orders/MSG-3c.md +0 -378
  299. package/work-orders/MSG-3d.md +0 -268
  300. package/work-orders/MSG-3e.md +0 -164
  301. package/work-orders/MSG-3f.md +0 -391
  302. package/work-orders/MSG-6e.md +0 -308
  303. package/work-orders/MSG-6f.md +0 -214
  304. package/work-orders/MSG-6g.md +0 -244
  305. package/work-orders/MSG-6h.md +0 -238
  306. package/work-orders/MSG-6i.md +0 -271
  307. package/work-orders/MSG-6j.md +0 -117
  308. package/work-orders/NOTIF-12.md +0 -214
  309. package/work-orders/NOTIF-13.md +0 -142
  310. package/work-orders/NOTIF-14.md +0 -151
  311. package/work-orders/PRIM-1.md +0 -177
  312. package/work-orders/SHELL-1.md +0 -255
  313. package/work-orders/SHELL-2.md +0 -197
  314. package/work-orders/SHELL-3.md +0 -359
  315. package/work-orders/SHELL-4.md +0 -351
  316. package/work-orders/SHELL-5.md +0 -345
  317. package/work-orders/SHELL-6.md +0 -210
  318. package/work-orders/THEME-1.md +0 -587
  319. package/work-orders/THEME-10.md +0 -303
  320. package/work-orders/THEME-11.md +0 -208
  321. package/work-orders/THEME-2.md +0 -339
  322. package/work-orders/THEME-3.md +0 -210
  323. package/work-orders/THEME-4.md +0 -271
  324. package/work-orders/THEME-5.md +0 -341
  325. package/work-orders/THEME-6.md +0 -247
  326. package/work-orders/THEME-7.md +0 -82
  327. package/work-orders/THEME-8.md +0 -211
  328. package/work-orders/THEME-9.md +0 -194
  329. package/work-orders/UCM-AUTH-10.md +0 -490
  330. package/work-orders/UCM-AUTH-11.md +0 -185
  331. package/work-orders/UCM-AUTH-12.md +0 -98
  332. package/work-orders/UCM-AUTH-13.md +0 -47
  333. package/work-orders/UCM-AUTH-9.md +0 -207
  334. package/work-orders/UCM-CHART-10.md +0 -150
  335. package/work-orders/UCM-CHART-11.md +0 -132
  336. package/work-orders/UCM-CHART-12.md +0 -348
  337. package/work-orders/UCM-CHART-13.md +0 -122
  338. package/work-orders/UCM-CHART-14.md +0 -198
  339. package/work-orders/UCM-CHART-15.md +0 -187
  340. package/work-orders/UCM-CHART-16.md +0 -169
  341. package/work-orders/UCM-CHART-17.md +0 -195
  342. package/work-orders/UCM-CHART-18.md +0 -200
  343. package/work-orders/UCM-CHART-8.md +0 -147
  344. package/work-orders/UCM-CHART-9.md +0 -265
  345. package/work-orders/UCM-CHAT-1.md +0 -190
  346. package/work-orders/UCM-CHAT-2.md +0 -75
  347. package/work-orders/UCM-DEP-1.md +0 -63
  348. package/work-orders/UCM-I18N-4.md +0 -226
  349. package/work-orders/UCM-I18N-5.md +0 -211
  350. package/work-orders/UCM-MSG-20.md +0 -192
  351. package/work-orders/UCM-PRIM-2.md +0 -114
  352. package/work-orders/UCM-SHELL-7.md +0 -134
  353. package/work-orders/UCM-SHELL-8.md +0 -125
  354. package/work-orders/UCM-TEST-1.md +0 -304
  355. package/work-orders/UCM-THEME-13.md +0 -69
  356. package/work-orders/UCM-THEME-14.md +0 -312
  357. package/work-orders/UCM-THEME-15.md +0 -356
  358. package/work-orders/UCM-THEME-16.md +0 -80
  359. package/work-orders/UCM-THEME-17.md +0 -111
  360. package/work-orders/UCM-THEME-18.md +0 -184
  361. package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
  362. package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
  363. package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
  364. package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
  365. package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
  366. package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
  367. package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
@@ -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`.
@@ -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`.