@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,192 +0,0 @@
1
- # UCM-MSG-20 — Message composer collapses on narrow screens
2
-
3
- # A. Envelope — authored by the Expertenchat
4
-
5
- ## Goal & expected outcome
6
-
7
- - Goal: on a 375 px phone a person can type and send a message in every conversation type.
8
- - Expected outcome:
9
- - The text field keeps a usable width (at least most of the row) next to the action icons; the send
10
- button is fully visible.
11
- - URLs in messages are clickable links.
12
- - The read marker next to the time explains itself (label or tooltip), or is not shown where it
13
- carries no information.
14
-
15
- ## Context — measured 2026-09-29 in jg-ferien's local browser test (ucm 3.5.0 installed there)
16
-
17
- - jg-ferien, event announcement conversation, 375 px: next to four icon buttons (attach, emoji, poll,
18
- announce) the textarea is **16 px** wide (its field 44 px), "Senden" is clipped (44 px), the row
19
- overflows (315 of 295 px).
20
- - Component: `src/messaging/Composer.jsx` (row layout incl. the four icon buttons,
21
- `allowAnnouncement` prop); `src/messaging/MessageBubble.jsx` shows a bare "0/0" next to the time.
22
- - Long words and URLs wrap correctly inside the bubble; URLs are plain text.
23
- - The dcm register is canonical for `MSG-*`; this is the ucm-side row.
24
-
25
- ## Scope + non-goals
26
-
27
- - In scope: composer layout at narrow widths (e.g. actions collapse into one menu, or wrap to their
28
- own row), linkified URLs, an explained or hidden read marker.
29
- - Explicit non-goals / do-not-touch:
30
- - No change to message sending, polls or announcements behaviour.
31
-
32
- ## Tier · gates
33
-
34
- - **Tier 3** — shared-core component.
35
- - Reviewer: `reviewer` (all lenses; linkify is new logic) · `ui_reviewer` · `sec_reviewer` (linkify
36
- must not create script or `javascript:` links).
37
- - **Done means released and jg-ferien's pin bumped.**
38
-
39
- ## Risks
40
-
41
- - Linkify is an injection surface: only `http(s)` URLs, `rel="noopener noreferrer"`, no HTML from
42
- message text.
43
-
44
- ## Required tests to WRITE (you write them and run YOUR OWN new ones; the orchestrator's run is the gate)
45
-
46
- 1. At 375 px width the textarea has at least a defined minimum width and the send button is not
47
- clipped, with all four actions enabled.
48
- 2. `https://…` in a message renders as a link; `javascript:…` does not.
49
- 3. The read marker has an accessible label or is absent.
50
-
51
- ---
52
-
53
- # B. Implementation map — filled by the Orchestrator — ADDRESSED TO THE IMPLEMENTER
54
-
55
- ## Context package — three independent fixes, same file family
56
-
57
- ### 1. Composer overflow at narrow widths — `src/messaging/Composer.jsx`
58
-
59
- - The single overflowing row is at line 139:
60
- `<Stack direction="row" spacing={1} alignItems="flex-end">` — it holds, in order: the hidden file
61
- `<input>`, 4 `IconButton`s (attach `:141`, emoji `:142`, poll `:143`, announce `:144` conditional
62
- on `canAnnounce`), the `TextField` (`:145`, `fullWidth multiline minRows={2}`), and the Send
63
- `Button` (`:146`).
64
- - **Fix: split into two stacked rows, not one collapsing menu** (the WO's "or wrap to their own
65
- row" option — simplest, lowest-risk, no new interaction pattern to test):
66
- 1. First row: a `<Stack direction="row" spacing={1}>` containing only the icon buttons (attach,
67
- emoji, poll, and the conditional announce button) — 3–4 icon buttons at ~40px each comfortably
68
- fit 375px on their own.
69
- 2. Second row: `<Stack direction="row" spacing={1} alignItems="flex-end">` containing only the
70
- `TextField` and the Send `Button`.
71
- 3. Give the `TextField` `sx={{ flex: 1, minWidth: 120 }}` (so it never collapses to near-zero
72
- width when squeezed) and the Send `Button` `sx={{ flexShrink: 0 }}` (so it is never the thing
73
- that gets clipped — it should shrink last, if at all).
74
- 4. Everything else in the file (state, handlers, the poll/announcement dialogs, the emoji
75
- popover) is unchanged — this is a pure JSX layout restructure of one `Stack`.
76
- - Test file: extend `tests/messagingComposer.test.jsx` (existing — read it first for the render
77
- harness/mock-provider pattern already in use, follow it exactly rather than inventing a new one).
78
- Add: render the `Composer`, resize the test's container is not meaningful in jsdom (no real
79
- layout), so instead assert via computed style: the `TextField`'s wrapping element has
80
- `minWidth: '120px'` (or your chosen value) and the Send button's element has `flexShrink: '0'` —
81
- both readable via `window.getComputedStyle`, same technique as
82
- `tests/StatTile.test.jsx`'s `accent` test. Also assert all four action buttons
83
- (`MessagingComposer.ADD_ATTACHMENT`/`ADD_EMOJI`/`MessagingPoll.CREATE`/
84
- `MessagingAnnouncement.CREATE` — pass `allowAnnouncement` + a non-`direct` `conversation` prop to
85
- exercise the fourth) are present and not `disabled` (aside from the poll button's existing
86
- `pollOpen || files.some(isImage)` guard, unrelated to this WO).
87
-
88
- ### 2. Linkify `http(s)` URLs — new file `src/messaging/linkifyText.jsx`
89
-
90
- - No linkify library exists in this repo's dependencies today (checked — do not add one; a
91
- dependency addition needs separate approval this WO does not have, and the requirement is narrow
92
- enough not to need one).
93
- - Export a pure function `linkifyText(text)` returning an array of strings and `<a>` React elements
94
- (a `key`ed fragment-safe array, the same shape `.map()` output must have). URL matching: a strict
95
- **`http://` or `https://` prefix only** — e.g.
96
- `/(https?:\/\/[^\s<>"']+)/g` — so a `javascript:`, `data:`, or any other scheme can never match
97
- the pattern in the first place (that is the actual security property the sec_reviewer will check
98
- for — not an escaping step, an inclusion-list pattern that structurally cannot match anything
99
- else). Split `text` on that pattern; for each URL match render
100
- `<a href={url} target="_blank" rel="noopener noreferrer">{url}</a>`; non-matching segments pass
101
- through as plain strings (React renders an array of strings/elements fine as children).
102
- - Trim likely trailing punctuation that is prose, not part of the URL (a trailing `.`, `,`, `)`,
103
- `!`, `?` immediately followed by a word boundary or end of string) so `"see https://x.com."` does
104
- not link the sentence-ending period — check `tests/` for whether any existing kit code already
105
- does this trimming (grep `messagingContractConformance` / `messagingApi` tests for a URL-trimming
106
- precedent) before inventing your own rule; if none exists, a simple trailing-punctuation strip is
107
- sufficient, name it in your `PROGRESS` narration.
108
- - Wire it into `src/messaging/MessageBubble.jsx:149` — the `<Typography sx={{ whiteSpace:
109
- 'pre-wrap', overflowWrap: 'anywhere' }}>{...}</Typography>` that renders the message body: replace
110
- the raw string child with `linkifyText(<same expression>)` for the non-deleted, non-empty case
111
- (deleted messages keep rendering `t('MessagingThread.DELETED')` as plain text, unlinkified).
112
- - Test file: new `tests/messagingLinkify.test.jsx` (or extend an existing `MessageBubble` test if
113
- one already covers body rendering — check `tests/messagingChunk6.test.jsx` and
114
- `tests/messagingCompactBubble.test.jsx` first).
115
- 1. A message body containing `https://example.com/path` renders an `<a>` with that exact `href`,
116
- `target="_blank"`, and `rel="noopener noreferrer"`.
117
- 2. A message body containing the literal text `javascript:alert(1)` renders it as plain text —
118
- assert `screen.queryByRole('link')` is `null` and the literal string is present as text.
119
- 3. A message body containing both a URL and surrounding prose renders the prose as plain text
120
- and only the URL portion as a link (i.e. the split doesn't eat the surrounding words).
121
-
122
- ### 3. Read marker explains itself — `src/messaging/ReadTicks.jsx`
123
-
124
- - Both existing branches already set `aria-label` (line 74's `<span role="img">`/`<ButtonBase>` for
125
- the counted case, line 80's `<StatusIcon role="img">` for the DM case) — that covers screen
126
- readers, but `aria-label` is invisible to a SIGHTED user looking at a bare "0/0", which is the
127
- Envelope's actual complaint ("explains itself (**label or tooltip**)" — the current label is
128
- ARIA-only, not a visible one).
129
- - Fix, at the `hasCounts` branch (line 56 onward): wrap the returned ratio element in MUI's
130
- `Tooltip` (already imported patterns exist elsewhere in the kit, e.g. `UserListComponent.jsx`'s
131
- `<Tooltip title={...}>`) using the same `label` text as the `title`, so hovering explains it
132
- visually too. Import `Tooltip` from `@mui/material` at the top of the file (currently only
133
- imports `List, ListItem, Popover, Typography, ButtonBase`).
134
- - Additionally: when `status.recipient_count === 0` (a message with literally nobody to read it —
135
- "0/0" carries no information per the Envelope's alternative: "or is not shown where it carries no
136
- information"), return `null` before rendering the ratio, same early-return style already used at
137
- line 41 (`if (!status) return null;`) and line 50 (`if (!hasCounts && conversation?.kind !==
138
- 'direct') return null;`).
139
- - Do NOT change the DM branch (line 78–80) — it already carries a real icon-shape + colour +
140
- aria-label signal (not a bare number), out of this fix's actual complaint.
141
- - Test file: extend `tests/messagingReadTicks*.test.*` if one exists (grep `tests/` for
142
- `ReadTicks`); otherwise create `tests/messagingReadTicksTooltip.test.jsx`.
143
- 1. With `read_count: 2, recipient_count: 5`, assert a `title` attribute (MUI `Tooltip` renders
144
- one on the wrapped element before hover, or use `@testing-library/user-event` to hover and
145
- assert the tooltip text appears — follow whatever pattern this repo's other `Tooltip` tests
146
- already use, grep for one) explaining the ratio is present.
147
- 2. With `recipient_count: 0`, assert the component renders nothing (e.g. `container.textContent`
148
- is empty, or the specific test id/role used elsewhere for "renders null" assertions in this
149
- test suite).
150
-
151
- ## Do-not-touch / invariants
152
-
153
- - No change to message sending, polls, or announcements behaviour (Envelope non-goal) — items 1–3
154
- above are the complete scope; do not touch `submit`/`submitPoll`/`submitAnnouncement`.
155
- - `sec_reviewer` will specifically check the linkify regex cannot match a non-`http(s)` scheme —
156
- keep the pattern an explicit `https?://` prefix, never a generic "looks like a URL" heuristic.
157
-
158
- ## Target repo working directory (absolute)
159
-
160
- `C:\Users\biglmi\Documents\webapps\ui-core-micha` (branch `main`)
161
-
162
- ## Preamble — a REQUIRED block IN this file, not something appended at invocation
163
-
164
- > The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there
165
- > is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the
166
- > app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI
167
- > unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register
168
- > row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source
169
- > and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies,
170
- > touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state
171
- > blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT
172
- > `git add`/`commit`/`push` — leave every
173
- > change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests
174
- > the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute
175
- > and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review).
176
- > The orchestrator re-runs the authoritative set + does the independent review after you finish —
177
- > those are the gate; your own run does not count as the gate.
178
- >
179
- > Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
180
- > `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
181
- > completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
182
- > `RESULT: DONE|BLOCKED <reason>`.
183
-
184
- ---
185
-
186
- # C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
187
-
188
- > **If you are the implementer reading this work order as your own specification: STOP at this line.
189
- > Everything below describes what the Orchestrator does AFTER you finish. You do none of it — no
190
- > reviewers, no verification run, no register edit, no commit.**
191
-
192
- *(to be filled by the Orchestrator: execution directive; `reviewer` (all lenses) + `ui_reviewer` + `sec_reviewer`; release; jg-ferien pin bump and 375 px check in an event conversation; register rows here, in dcm (MSG canonical) and in jg (`JG-UX-14`).)*
@@ -1,114 +0,0 @@
1
- # UCM-PRIM-2 — A shared empty-state primitive
2
-
3
- # A. Envelope — authored by the Expertenchat
4
-
5
- ## Goal & expected outcome
6
-
7
- - Goal: every "nothing here yet" in a consuming app looks and reads the same.
8
- - Expected outcome: `EmptyState` in the kit — an optional icon, one line of text, an optional secondary
9
- line and an optional action — built from theme tokens, accessible (text reachable by screen
10
- readers, action a real button).
11
-
12
- ## Context — measured 2026-09-29 in jg-ferien's local browser test (ucm 3.5.0 installed there)
13
-
14
- - jg-ferien's 15 event sections show "empty" in **seven** ways (plain text, card, blue info alert,
15
- card with title, filled green card, alert inside a green card, nothing at all). No shared component
16
- exists in jg or ucm; jg has only a song-search special case.
17
- - **Operator decision 2026-09-29: generic goes to ucm.** jg adopts it in `JG-UX-9`.
18
- - `PRIM-1` promoted `StatTile`/`SoftChip` along the same lines.
19
-
20
- ## Scope + non-goals
21
-
22
- - In scope: the component, its export, a story or docs entry, tests.
23
- - Explicit non-goals / do-not-touch: no adoption in consumers here; no change to `Alert` styling.
24
-
25
- ## Tier · gates
26
-
27
- - **Tier 3** — new public export in shared-core (additive).
28
- - Reviewer: `reviewer` (all lenses) · `ui_reviewer`.
29
- - **Done means released; jg adoption is `JG-UX-9`.**
30
-
31
- ## Risks
32
-
33
- - A too-flexible API reintroduces the seven variants; keep the props minimal.
34
-
35
- ## Required tests to WRITE (you write them and run YOUR OWN new ones; the orchestrator's run is the gate)
36
-
37
- 1. Renders text only; with secondary line; with action (button with accessible name).
38
- 2. Uses theme tokens (no literal colours; the kit's literal guard passes).
39
-
40
- ---
41
-
42
- # B. Implementation map — filled by the Orchestrator — ADDRESSED TO THE IMPLEMENTER
43
-
44
- ## Context package
45
-
46
- - New file `src/components/EmptyState.jsx`. Model it on the existing primitives
47
- `src/components/StatTile.jsx` and `src/components/SoftChip.jsx` — a small functional component,
48
- default export, built from `Box`/`Typography`/`Button` (MUI), theme tokens only (no literal
49
- colours — `reportOffPaletteColours` in `src/theme/themeCompleteness.js` scans every source file
50
- for off-palette hex/rgb/named colours and is part of the kit's literal guard the Required Tests
51
- reference).
52
- - Props (keep minimal per the Risk note — do not over-generalise):
53
- `icon` (optional, a rendered MUI icon element, e.g. `<InboxOutlinedIcon />`), `title` (string,
54
- required — the one line of text), `description` (optional secondary line), `action` (optional
55
- `{ label, onClick }` — rendered as a real `<Button variant="outlined">`, not a link, so it is
56
- reachable and operable like `StatTile`'s children slot), `sx` (optional passthrough, MUI
57
- convention used throughout the kit, e.g. `Composer.jsx`'s `COMPOSER_EMOJI_BUTTON_SX` pattern).
58
- - Export it from `src/index.js` next to the other components section (`--- 5. Components ---`,
59
- after `SoftChip` at line 65): `export { default as EmptyState } from './components/EmptyState';`.
60
- - Accessibility: `title` must be real text content (not just an `aria-label`), so a screen reader
61
- reads it as part of document flow; if `icon` is passed, it must not need its own label (decorative
62
- — rely on the adjacent text, matching how `StatTile` treats its icon-less design).
63
- - Test file: `tests/EmptyState.test.jsx`, following `tests/StatTile.test.jsx`'s pattern exactly —
64
- `@vitest-environment jsdom`, wrap in `<ThemeProvider theme={createAppTheme(...)}>`, `cleanup()`
65
- in `afterEach`.
66
- - Render text-only, with `description`, with `action` (assert the button has an accessible name
67
- matching the label and that clicking it calls the passed `onClick`).
68
- - The "theme tokens only" requirement: either call `reportOffPaletteColours([{ path: 'src/components/EmptyState.jsx', source: fs.readFileSync(...) }])` (see how `themeCompleteness.js` self-tests, or grep existing callers of `reportOffPaletteColours` in `tests/` for the established pattern) and assert `findings` is empty, or (simpler, sufficient) just don't use any hex/rgb/named-colour literal in the component at all and note in a comment that the guard is structural, not a runtime assertion in this test. Prefer calling `reportOffPaletteColours` directly if an existing test already does — grep `tests/*.test.*` for `reportOffPaletteColours` to find the precedent and match its call shape exactly.
69
-
70
- ## Do-not-touch / invariants
71
-
72
- - Do not add `EmptyState` to `kitSxRegistry.js` unless you export a top-level `sx` object constant
73
- from the component (only needed if the root element gets kit-owned baked-in styling beyond plain
74
- `sx` passthrough — for this minimal component you likely don't need one; only add a registry entry
75
- if you do add such a constant).
76
- - No adoption anywhere in this repo's own consumers (`AccountPage`, etc.) — out of scope per the
77
- Envelope's non-goals.
78
- - Do not touch `Alert` styling anywhere.
79
-
80
- ## Target repo working directory (absolute)
81
-
82
- `C:\Users\biglmi\Documents\webapps\ui-core-micha` (branch `main`)
83
-
84
- ## Preamble — a REQUIRED block IN this file, not something appended at invocation
85
-
86
- > The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there
87
- > is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the
88
- > app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI
89
- > unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register
90
- > row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source
91
- > and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies,
92
- > touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state
93
- > blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT
94
- > `git add`/`commit`/`push` — leave every
95
- > change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests
96
- > the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute
97
- > and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review).
98
- > The orchestrator re-runs the authoritative set + does the independent review after you finish —
99
- > those are the gate; your own run does not count as the gate.
100
- >
101
- > Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
102
- > `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
103
- > completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
104
- > `RESULT: DONE|BLOCKED <reason>`.
105
-
106
- ---
107
-
108
- # C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
109
-
110
- > **If you are the implementer reading this work order as your own specification: STOP at this line.
111
- > Everything below describes what the Orchestrator does AFTER you finish. You do none of it — no
112
- > reviewers, no verification run, no register edit, no commit.**
113
-
114
- *(to be filled by the Orchestrator: execution directive; `reviewer` (all lenses) + `ui_reviewer`; release; register row here and cross-reference in jg (`JG-UX-9`).)*
@@ -1,134 +0,0 @@
1
- # UCM-SHELL-7 — User-menu avatar initials fail contrast
2
-
3
- # A. Envelope — authored by the Expertenchat
4
-
5
- ## Goal & expected outcome
6
-
7
- - Goal: the initials in the header avatar are readable.
8
- - Expected outcome: initials reach at least 4.5:1 against the avatar background, using the consuming
9
- app's theme tokens rather than MUI's default grey.
10
-
11
- ## Context — measured 2026-09-29 in jg-ferien's local browser test (ucm 3.5.0 installed there)
12
-
13
- - `UserMenu` (imported in jg-ferien's `Header.jsx`) renders the MUI default avatar: white initials on
14
- light grey, **1.83:1**, on every page of the app.
15
-
16
- ## Scope + non-goals
17
-
18
- - In scope: avatar colours in `UserMenu` from theme tokens (e.g. primary surface with its
19
- contrastText), with a fallback that passes when a consumer defines nothing.
20
- - Explicit non-goals / do-not-touch: no layout change of the user menu.
21
-
22
- ## Tier · gates
23
-
24
- - **Tier 3** — shared-core component (small).
25
- - Reviewer: `ui_reviewer` (no new logic beyond the colour choice).
26
- - **Done means released and jg-ferien's pin bumped.**
27
-
28
- ## Risks
29
-
30
- - `createAppTheme` baseline: if the chosen token is optional, `assertThemeComplete` must require it or
31
- the fallback must pass on its own.
32
-
33
- ## Required tests to WRITE (you write them and run YOUR OWN new ones; the orchestrator's run is the gate)
34
-
35
- 1. With jg-ferien's theme values the avatar pair is at least 4.5:1.
36
- 2. With a theme defining nothing extra the fallback pair is at least 4.5:1.
37
-
38
- ---
39
-
40
- # B. Implementation map — filled by the Orchestrator — ADDRESSED TO THE IMPLEMENTER
41
-
42
- ## Context package
43
-
44
- - File: `src/auth/UserMenu.jsx`. The avatar is rendered at line 60:
45
- `<Avatar src={avatarSrc} sx={{ width: 32, height: 32, fontSize: '0.8rem' }}>` — no `bgcolor`/`color`
46
- is set today, so it falls through to MUI's default grey Avatar styling (1.83:1, the measured
47
- defect). Only this one JSX element changes; nothing else in the file.
48
- - **Pitfall — do not just reach for `theme.palette.primary.contrastText`.** MUI's own
49
- `createTheme`/`augmentColor` computes `contrastText` with `contrastThreshold: 3` (tuned for large
50
- text/graphics, AA), not the 4.5:1 this WO requires for normal-size initials text. A consumer's
51
- `primary.main` that legitimately passes MUI's own 3:1 threshold can still fail 4.5:1, and nothing
52
- here re-validates it — so `contrastText` alone is not a fallback that "passes when a consumer
53
- defines nothing", it is a fallback that USUALLY passes.
54
- - **Design to implement instead** (uses the kit's own exported contrast helper, satisfies both
55
- required tests meaningfully since both actually depend on the consumer's `primary.main`):
56
- 1. Import `{ calculateContrastRatio }` from `'../theme'` (already exported from
57
- `src/theme/index.js` → re-exported at `src/index.js`) and `useTheme` from
58
- `'@mui/material/styles'`.
59
- 2. Inside `UserMenu`, read `const theme = useTheme();`.
60
- 3. Background: `theme.palette.primary.main` (the "primary surface" the Envelope names).
61
- 4. Text colour: compute
62
- `calculateContrastRatio(theme.palette.background.paper, theme.palette.primary.main) >= 4.5
63
- ? theme.palette.background.paper : theme.palette.ink.primary`.
64
- This is not an arbitrary heuristic: for any background colour, the higher of
65
- (contrast against white) and (contrast against near-black) is mathematically always ≥ √21 ≈
66
- 4.58 — i.e. picking whichever of the kit's own light (`background.paper`, white) or dark
67
- (`ink.primary`, near-black) ink token has the higher measured contrast against
68
- `primary.main` is GUARANTEED to clear 4.5:1 for every possible `primary.main`, including one
69
- a consumer hasn't customised at all (the untouched baseline `primary.main` MUI ships). That is
70
- what makes this "a fallback that passes when a consumer defines nothing" instead of "usually
71
- passes".
72
- 5. Apply as `sx={{ ..., bgcolor: theme.palette.primary.main, color: <computed> }}` on the same
73
- `Avatar` element — keep the existing `width`/`height`/`fontSize` untouched.
74
- 6. Do NOT introduce a new literal hex/rgb anywhere — `theme.palette.background.paper` and
75
- `theme.palette.ink.primary` are both resolved theme values, and referencing them via
76
- `theme.palette.<path>` (not writing their hex value as a string literal) keeps
77
- `reportOffPaletteColours` clean, same as every other component in the kit.
78
- - Test file: new `tests/UserMenu.test.jsx` (none exists yet — check with `Glob` before assuming;
79
- if a `UserMenu` test already exists under a different name, extend it instead of creating a
80
- duplicate). Pattern after `tests/StatTile.test.jsx`: `@vitest-environment jsdom`,
81
- `createAppTheme(...)`, wrap `UserMenu` in the theme provider AND `AuthContext.Provider` (it reads
82
- `user`/`logout` via `useContext(AuthContext)` at line 32 — a minimal `{ user: { username: 'ab' },
83
- logout: () => {} }` value is enough to render the avatar).
84
- 1. With a theme built from jg-ferien's actual `primary.main` — `#367964` (measured directly from
85
- `jg-ferien/frontend/src/theme.js:25`, a mid-brightness teal-green), assert
86
- `calculateContrastRatio(<resolved avatar text colour>, <resolved avatar bg colour>) >= 4.5`
87
- by reading the rendered `Avatar`'s computed `backgroundColor`/`color` via
88
- `window.getComputedStyle` (see `tests/StatTile.test.jsx`'s `accent` border test for the
89
- `getComputedStyle` pattern) and feeding both into `calculateContrastRatio` directly — do not
90
- hardcode an expected hex, assert the ratio.
91
- 2. With `createAppTheme({})` (no consumer overrides — MUI's own baseline `primary.main`), assert
92
- the same ≥4.5 computed-style contrast check.
93
-
94
- ## Do-not-touch / invariants
95
-
96
- - No layout change to the user menu (Envelope non-goal) — only the two `sx` colour values change.
97
- - Do not touch `assertThemeComplete`/`THEME_COMPLETENESS_SURFACES` — this fix reads existing
98
- required surfaces (`primary.main`, `background.paper`, `ink.primary`), it does not need a new one.
99
-
100
- ## Target repo working directory (absolute)
101
-
102
- `C:\Users\biglmi\Documents\webapps\ui-core-micha` (branch `main`)
103
-
104
- ## Preamble — a REQUIRED block IN this file, not something appended at invocation
105
-
106
- > The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there
107
- > is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the
108
- > app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI
109
- > unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register
110
- > row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source
111
- > and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies,
112
- > touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state
113
- > blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT
114
- > `git add`/`commit`/`push` — leave every
115
- > change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests
116
- > the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute
117
- > and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review).
118
- > The orchestrator re-runs the authoritative set + does the independent review after you finish —
119
- > those are the gate; your own run does not count as the gate.
120
- >
121
- > Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
122
- > `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
123
- > completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
124
- > `RESULT: DONE|BLOCKED <reason>`.
125
-
126
- ---
127
-
128
- # C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
129
-
130
- > **If you are the implementer reading this work order as your own specification: STOP at this line.
131
- > Everything below describes what the Orchestrator does AFTER you finish. You do none of it — no
132
- > reviewers, no verification run, no register edit, no commit.**
133
-
134
- *(to be filled by the Orchestrator: execution directive; `ui_reviewer`; release; jg-ferien pin bump; register rows here and in jg (`JG-DL-12`).)*
@@ -1,125 +0,0 @@
1
- # UCM-SHELL-8: Valid SectionNav list items
2
-
3
- # A. Envelope — operator-approved scope
4
-
5
- ## Goal and expected outcome
6
-
7
- SectionNav navigation entries are genuine list items containing the existing buttons.
8
- The account capture in innoservice reports three serious axe list violations at 1280 px;
9
- these remain in ui-core-micha 3.13.0. The correction removes their structural cause.
10
-
11
- ## Scope and non-goals
12
-
13
- - Correct grouped and optional overview entries in SectionNav's shared list renderer.
14
- - Keep selection, aria-current, labels, remembered entry, keyboard operation, callbacks,
15
- controlled/uncontrolled drawer behavior and appearance unchanged.
16
- - Release the correction as patch 3.13.1 and update innoservice's exact package pin.
17
- - No navigation redesign, new text, token delta, authentication, permissions, data contract,
18
- other component, CI configuration or dependency changes beyond that release/pin.
19
- - No new visual design or prototype: retain the existing presentation.
20
-
21
- ## Tier, risk and required tests to write
22
-
23
- Tier 3: shared-core source with a rendered DOM correction used by consumers.
24
- Risk: wrapper defaults could alter spacing or interrupt existing button interaction.
25
- Write focused assertions that every grouped and overview list has li children containing
26
- the existing button controls, on desktop and inside the mobile drawer. Preserve existing
27
- selection and drawer tests; prove overview selection still passes null and closes the drawer.
28
-
29
- # B. Implementation map — ADDRESSED TO THE IMPLEMENTER
30
-
31
- ## Target and ownership
32
-
33
- Target: `C:/Users/Micha Bigler/Documents/webapps/ui-core-micha`.
34
- Native bootstrap retains workspace-root cwd; use absolute paths and explicit workdirs.
35
- You are not alone in the codebase; preserve other agents' changes. Own only:
36
- - `src/layout/SectionNav.jsx`
37
- - `tests/SectionNav.test.jsx`
38
-
39
- ## Context package
40
-
41
- `src/layout/SectionNav.jsx:120`, SectionNavList, is shared by the desktop nav and mobile
42
- drawer. The overview List currently directly contains ListItemButton; grouped Lists at
43
- 159 map item keys to direct ListItemButton children. MUI List defaults to ul and the
44
- button defaults to div. Correct list containment while preserving the interactive button.
45
- The overview handler passes null; grouped handlers pass item.key. Selected buttons carry
46
- aria-current=page; remembered secondary text is shown only on its unselected entry.
47
- Keep exported sx constants, drawer state handlers, prop defaults and group label IDs.
48
- Use existing MUI primitives; prevent wrapper padding from changing the presentation.
49
-
50
- `tests/SectionNav.test.jsx` renders the real named SectionNav with ThemeProvider and a
51
- translation mock. Existing labels: Profile, Security, Users, Invite, Support, Notifications;
52
- optional Overview; trigger accessible name matches /Section Profile/i; drawer title
53
- Switch section. Existing tests cover selection, remembered text, controlled/uncontrolled
54
- drawer, theme tokens and grid. Extend this file without mocking SectionNav or changing
55
- existing tests to accept weaker behavior. Work from these two files, no broad exploration.
56
-
57
- ## Preamble and progress contract
58
-
59
- > This committed WO is the COMPLETE spec. You are the initial implementer, not the reviewer.
60
- > Edit only the owned source/test paths using explicit UTF-8 I/O. Preserve other changes.
61
- > Do not edit dependencies, lockfiles, package/version/changelog/register/README/governance,
62
- > settings, environment, other repos or memory. Never read .env or dump environment/settings.
63
- > Your tools are for editing source/test files and running the tests you wrote, nothing else.
64
- > No installs, package-manager commands, containers, git operations, self-review or subagents.
65
- > Run your newly written SectionNav cases ONCE with the existing Node/Vitest runtime,
66
- > maxWorkers=2, selected by test names; no affected/full suite, build or app startup.
67
- > If blocked, report it rather than changing repo state. Leave all changes uncommitted.
68
- > The orchestrator's tests and independent reviews are the acceptance gate, not your run.
69
- > Start PLAN, emit PROGRESS before relevant actions with no silence over two minutes,
70
- > then exactly one final RESULT: DONE or RESULT: BLOCKED.
71
-
72
- # C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
73
-
74
- > IMPLEMENTER STOP HERE. You ARE the initial implementation instance. No steps below belong to you.
75
-
76
- Gate #1: operator explicitly approved this exact structural correction, preserved behavior
77
- and appearance, tests/review, release and innoservice pin bump on 2026-10-13.
78
- No source approval was inferred from the earlier registration or clarification question.
79
-
80
- Dispatch: fresh native plain worker, requested codex/gpt-6-luna, full WO inline; inherited
81
- cwd is workspace root, target is the absolute core repo above. Record accepted identity
82
- and only exposed effective metadata. Assigned ownership is not technical containment.
83
- Parent owns repo state, package version, changelog, README/register and release/pin.
84
-
85
- Independent envelope/regression/duplication/tests lenses plus UI run concurrently on the
86
- same frozen diff via fresh read-only codex/gpt-6-luna processes. Security reviewer is not
87
- required: no auth/security behavior changes. Parent also checks exposure/permission parity.
88
- Parent runs SectionNav and both existing AccountPage test files, then build. Existing main
89
- publish workflow supplies the full shared-core regression suite and publishing evidence;
90
- normal reviewed main push, no manual publish dispatch. Confirm successful publication of
91
- 3.13.1 before innoservice exact pin and lockfile update. Keep all app capture/axe checks.
92
- Fresh app capture at 375/1280 must verify navigation and absence of the three list violations.
93
- Finalize register with named reviews, deduplicated dispositions and actual test/release proof.
94
-
95
- Accepted native implementer: `/root/kit_sectionnav`, explicit requested gpt-6-luna, high
96
- reasoning, fresh context. Effective native provider/model metadata was not exposed and
97
- remains unverified. Only the two assigned files changed; no author git/review/repo-state
98
- operations. Author's single permitted test run failed before collection with temporary-file
99
- EPERM (zero tests). Parent runs the authoritative gate through the normal runtime path.
100
-
101
- Core acceptance: five fresh concurrent CLI reviews (envelope, regression, duplication,
102
- tests, UI), all exit 0, banners confirm codex/gpt-6-luna, provider openai, read-only.
103
- Deduplicated disposition: 1 raised, 0 accepted, worst accepted none. Tests lens R1 proposed
104
- proving the MUI implementation identity against a fabricated class-bearing stub. Rejected:
105
- the structural assertion fails against the actual pre-change direct div children, existing
106
- selection/theme/drawer tests retain their behavior checks, and the source still directly
107
- imports and renders the real MUI ListItemButton. No behavior or identity abstraction is added.
108
- Other lenses report no findings. Parent targeted pass confirms callbacks/permission filtering,
109
- labels and selected/remembered state unchanged; wrappers use disablePadding.
110
- Parent gate: 21 tests in SectionNav.test.jsx, AccountPage.test.jsx and
111
- AccountPage.profileStatements.test.jsx passed with maxWorkers=2; TypeScript build exit 0.
112
- Publish workflow's full suite is justified by shared-core consumer ripple. App pin and fresh
113
- consumer capture remain pending after the reviewed core source/release lands.
114
-
115
- Closing consumer proof: published3.13.1 verified by workflow38435441867,
116
- 744tests89files plus build and npm Trusted Publishing successful. Innoservice
117
- exact pin3.13.1 is in sourcec527918, CI38444366349. Both source-matching account
118
- captures375/1280 have no axe failures, no console/network failures, and all11
119
- rubric items yes (22answers). Parent inspected both actual account images: same
120
- profile/security/admin/help navigation and consent controls, readable at both
121
- widths. Three previous kit list violations are gone. This completes the scoped
122
- consumer gate; unrelated Organisation-policy axe failures in that app candidate
123
- remain owned by INNO-FIX-11 and do not reopen the kit list correction.
124
- Review remains the named five independent readonly Luna source passes above,
125
- 1deduplicated raised0accepted,worst accepted none; no source changes afterward.